Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,16 @@ jobs:
- uses: actions/setup-go@v6
with:
go-version: '1.26.3'
- uses: actions/setup-node@v4
with:
node-version: '20'

- name: Run Nigiri
uses: vulpemventures/nigiri-github-action@v1
- name: Start regtest base stack (Bitcoin Core + Fulcrum + mempool)
run: |
# Temporary: track the unmerged #27 branch so regtest.mjs exists.
# Switch back to master once ArkLabsHQ/arkade-regtest#27 merges.
git clone --branch denigiri-regtest https://github.com/ArkLabsHQ/arkade-regtest.git regtest
REGTEST_PROFILES=base node regtest/regtest.mjs start

- name: Run regtest environment
run: make docker-run
Expand All @@ -50,3 +57,7 @@ jobs:
- name: Tear down
if: always()
run: make docker-stop

- name: Tear down regtest stack
if: always()
run: node regtest/regtest.mjs clean || true
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,8 @@ The service can be configured using environment variables:

- Go 1.26+
- Docker and Docker Compose
- Node.js 18+ (to drive the [arkade-regtest](https://github.com/ArkLabsHQ/arkade-regtest) stack for integration testing)
- Buf CLI (for protocol buffer generation)
- [Nigiri](https://nigiri.vulpem.com) (for integration testing)

### Building

Expand All @@ -223,12 +223,22 @@ make run
# Run unit tests
make test

# Run docker regtest environment
nigiri start
# Bring up the regtest base stack (Bitcoin Core + Fulcrum + mempool) via the
# arkade-regtest Node CLI (replaces `nigiri start`). Esplora's REST API is served
# by mempool under /api (http://localhost:3000/api on the host,
# http://mempool_web/api in-network).
git clone https://github.com/ArkLabsHQ/arkade-regtest.git regtest
REGTEST_PROFILES=base node regtest/regtest.mjs start

# Run the emulator + arkd docker environment
make docker-run

# Run integration tests
make integrationtest

# Tear down
make docker-stop
node regtest/regtest.mjs clean
```

## Supported Opcodes
Expand Down
21 changes: 13 additions & 8 deletions docker-compose.regtest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,12 @@ services:
interval: 2s
timeout: 2s
retries: 30
nbxplorer:
# Renamed from `nbxplorer` (+ host port dropped) to avoid colliding with the
# arkade-regtest base stack's own `nbxplorer` container/port on the shared
# network. Only arkd-wallet talks to it, in-network.
emulator-nbxplorer:
restart: unless-stopped
container_name: nbxplorer
ports:
- 32838:32838
container_name: emulator-nbxplorer
image: nicolasdorier/nbxplorer:2.5.30
environment:
- NBXPLORER_NETWORK=regtest
Expand Down Expand Up @@ -66,12 +67,12 @@ services:
image: ghcr.io/arkade-os/arkd-wallet:v0.9.3
container_name: arkd-wallet
depends_on:
- nbxplorer
- emulator-nbxplorer
ports:
- "6060:6060"
environment:
- ARKD_WALLET_LOG_LEVEL=5
- ARKD_WALLET_NBXPLORER_URL=http://nbxplorer:32838
- ARKD_WALLET_NBXPLORER_URL=http://emulator-nbxplorer:32838
- ARKD_WALLET_DATADIR=./data/regtest
- ARKD_WALLET_NETWORK=regtest
- ARKD_WALLET_SIGNER_KEY=afcd3fa10f82a05fddc9574fdb13b3991b568e89cc39a72ba4401df8abef35f0
Expand Down Expand Up @@ -99,7 +100,7 @@ services:
- ARKD_CHECKPOINT_EXIT_DELAY=512
- ARKD_DATADIR=./data/regtest
- ARKD_WALLET_ADDR=arkd-wallet:6060
- ARKD_ESPLORA_URL=http://chopsticks:3000
- ARKD_ESPLORA_URL=http://mempool_web/api
- ARKD_ROUND_MIN_PARTICIPANTS_COUNT=${ARKD_ROUND_MIN_PARTICIPANTS_COUNT:-1}
- ARKD_ROUND_MAX_PARTICIPANTS_COUNT=${ARKD_ROUND_MAX_PARTICIPANTS_COUNT:-128}
- ARKD_VTXO_MIN_AMOUNT=1
Expand All @@ -113,7 +114,11 @@ services:
- type: tmpfs
target: /app/data

# Join the network created by the arkade-regtest stack so this compose's arkd /
# arkd-wallet can reach the shared bitcoin, nbxplorer and mempool_web containers.
# Docker Compose names the default network "<project>_default"; arkade-regtest's
# compose project is "arkade-regtest", hence "arkade-regtest_default".
networks:
default:
name: nigiri
name: arkade-regtest_default
external: true
2 changes: 1 addition & 1 deletion test/asset_account_covenant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func TestAssetAccountCovenant(t *testing.T) {
})

indexerSvc := setupIndexer(t)
explorerSvc, err := mempoolexplorer.NewExplorer("http://localhost:3000", arklib.BitcoinRegTest)
explorerSvc, err := mempoolexplorer.NewExplorer("http://localhost:3000/api", arklib.BitcoinRegTest)
require.NoError(t, err)

infos, err := grpcAlice.GetInfo(ctx)
Expand Down
4 changes: 2 additions & 2 deletions test/asset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ func TestOffchainTxWithAsset(t *testing.T) {
encodedValidTx, err := validTx.B64Encode()
require.NoError(t, err)

explorer, err := mempoolexplorer.NewExplorer("http://localhost:3000", arklib.BitcoinRegTest)
explorer, err := mempoolexplorer.NewExplorer("http://localhost:3000/api", arklib.BitcoinRegTest)
require.NoError(t, err)

signedTx, err := bobWallet.SignTransaction(
Expand Down Expand Up @@ -216,7 +216,7 @@ func TestSettlementWithAsset(t *testing.T) {
conn.Close()
})

explorer, err := mempoolexplorer.NewExplorer("http://localhost:3000", arklib.BitcoinRegTest)
explorer, err := mempoolexplorer.NewExplorer("http://localhost:3000/api", arklib.BitcoinRegTest)
require.NoError(t, err)

// =========================================================================
Expand Down
2 changes: 1 addition & 1 deletion test/batch_continuation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func TestCounterContractBatchContinuation(t *testing.T) {

indexerSvc := setupIndexer(t)

explorer, err := mempoolexplorer.NewExplorer("http://localhost:3000", arklib.BitcoinRegTest)
explorer, err := mempoolexplorer.NewExplorer("http://localhost:3000/api", arklib.BitcoinRegTest)
require.NoError(t, err)

// =========================================================================
Expand Down
2 changes: 1 addition & 1 deletion test/contract_id_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func TestContractIdWithAssetIdentity(t *testing.T) {
require.NoError(t, err)

indexerSvc := setupIndexer(t)
explorer, err := mempoolexplorer.NewExplorer("http://localhost:3000", arklib.BitcoinRegTest)
explorer, err := mempoolexplorer.NewExplorer("http://localhost:3000/api", arklib.BitcoinRegTest)
require.NoError(t, err)

// Recipient for the reader's value after the co-spend.
Expand Down
2 changes: 1 addition & 1 deletion test/cross_input_script_validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ func newCrossInputTestEnv(t *testing.T) *crossInputTestEnv {

indexerSvc := setupIndexer(t)

explorerSvc, err := mempoolexplorer.NewExplorer("http://localhost:3000", arklib.BitcoinRegTest)
explorerSvc, err := mempoolexplorer.NewExplorer("http://localhost:3000/api", arklib.BitcoinRegTest)
require.NoError(t, err)

recipientPrivKey, err := btcec.NewPrivateKey()
Expand Down
2 changes: 1 addition & 1 deletion test/delegate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func TestCovenantDelegate(t *testing.T) {
indexerSvc := setupIndexer(t)

explorerSvc, err := mempoolexplorer.NewExplorer(
"http://localhost:3000", arklib.BitcoinRegTest,
"http://localhost:3000/api", arklib.BitcoinRegTest,
)
require.NoError(t, err)

Expand Down
11 changes: 5 additions & 6 deletions test/deprecated_key_signing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func runSubmitTxWithDeprecatedKey(
bobWallet, _, bobPubKey := setupWallet(t, ctx)
aliceAddr := fundAndSettleAlice(t, ctx, alice, 10_000)
indexerSvc := setupIndexer(t)
explorer, err := mempoolexplorer.NewExplorer("http://localhost:3000", arklib.BitcoinRegTest)
explorer, err := mempoolexplorer.NewExplorer("http://localhost:3000/api", arklib.BitcoinRegTest)
require.NoError(t, err)

alicePkScript, err := script.P2TRScript(aliceAddr.VtxoTapKey)
Expand Down Expand Up @@ -164,7 +164,7 @@ func runSubmitIntentFinalizationWithDeprecatedKey(
t.Cleanup(func() { grpcClient.Close() })
aliceAddr := fundAndSettleAlice(t, ctx, alice, 100_000)
indexerSvc := setupIndexer(t)
explorerSvc, err := mempoolexplorer.NewExplorer("http://localhost:3000", arklib.BitcoinRegTest)
explorerSvc, err := mempoolexplorer.NewExplorer("http://localhost:3000/api", arklib.BitcoinRegTest)
require.NoError(t, err)

delegateArkadeScript := enforceSelfSend(t)
Expand Down Expand Up @@ -325,13 +325,12 @@ func runSubmitOnchainWithDeprecatedKey(

tapAddr, err := btcutil.NewAddressTaproot(schnorr.SerializePubKey(vtxoTapKey), getRegtestParams(t))
require.NoError(t, err)
_, err = runCommand("nigiri", "faucet", tapAddr.EncodeAddress(), "0.01")
_, err = onchainFaucet(tapAddr.EncodeAddress(), "0.01")
require.NoError(t, err)
explorerSvc, err := mempoolexplorer.NewExplorer("http://localhost:3000", arklib.BitcoinRegTest)
explorerSvc, err := mempoolexplorer.NewExplorer("http://localhost:3000/api", arklib.BitcoinRegTest)
require.NoError(t, err)
fundingUtxo := waitForUtxo(t, explorerSvc, tapAddr.EncodeAddress(), 60*time.Second)
_, err = runCommand("nigiri", "rpc", "-generate", "1")
require.NoError(t, err)
require.NoError(t, mineBlocks(1))
rawFundingHex, err := explorerSvc.GetTxHex(fundingUtxo.Txid)
require.NoError(t, err)
rawFundingBytes, err := hex.DecodeString(rawFundingHex)
Expand Down
22 changes: 9 additions & 13 deletions test/onchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import (
"github.com/stretchr/testify/require"
)

// TestSubmitOnchainTx funds an arkade-tweaked P2TR address directly via
// `nigiri faucet`, then spends it via a plain Bitcoin transaction where the
// emulator co-signs after running the embedded arkade script.
// TestSubmitOnchainTx funds an arkade-tweaked P2TR address directly via the
// regtest Bitcoin Core node, then spends it via a plain Bitcoin transaction
// where the emulator co-signs after running the embedded arkade script.
func TestSubmitOnchainTx(t *testing.T) {
ctx := context.Background()

Expand Down Expand Up @@ -93,21 +93,20 @@ func TestSubmitOnchainTx(t *testing.T) {
require.NoError(t, err)
tapAddrStr := tapAddr.EncodeAddress()

// --- Fund the address via nigiri ---
_, err = runCommand("nigiri", "faucet", tapAddrStr, "0.01")
// --- Fund the address via the regtest Bitcoin Core node ---
_, err = onchainFaucet(tapAddrStr, "0.01")
require.NoError(t, err)

explorerSvc, err := mempoolexplorer.NewExplorer(
"http://localhost:3000", arklib.BitcoinRegTest,
"http://localhost:3000/api", arklib.BitcoinRegTest,
)
require.NoError(t, err)

// --- Poll for UTXO and fetch raw funding tx ---
fundingUtxo := waitForUtxo(t, explorerSvc, tapAddrStr, 60*time.Second)

// Mine a block so the funding tx is confirmed.
_, err = runCommand("nigiri", "rpc", "-generate", "1")
require.NoError(t, err)
require.NoError(t, mineBlocks(1))

rawFundingHex, err := explorerSvc.GetTxHex(fundingUtxo.Txid)
require.NoError(t, err)
Expand Down Expand Up @@ -337,16 +336,13 @@ func TestSubmitOnchainTx(t *testing.T) {
require.NoError(t, err)
exitAddrStr := exitAddr.EncodeAddress()

_, err = runCommand("nigiri", "faucet", exitAddrStr, "0.01")
_, err = onchainFaucet(exitAddrStr, "0.01")
require.NoError(t, err)

exitUtxo := waitForUtxo(t, explorerSvc, exitAddrStr, 60*time.Second)

// Mine CSV + 1 blocks so the relative locktime is satisfied.
for i := uint32(0); i < csvBlocks+1; i++ {
_, err = runCommand("nigiri", "rpc", "-generate", "1")
require.NoError(t, err)
}
require.NoError(t, mineBlocks(int(csvBlocks+1)))

exitRawHex, err := explorerSvc.GetTxHex(exitUtxo.Txid)
require.NoError(t, err)
Expand Down
4 changes: 2 additions & 2 deletions test/pay_2_out_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func TestPayToTwoOutputs(t *testing.T) {
aliceAddr, err := arklib.DecodeAddressV0(offchainAddr)
require.NoError(t, err)

_, err = runCommand("nigiri", "faucet", boardingAddress)
_, err = onchainFaucet(boardingAddress, "")
require.NoError(t, err)

time.Sleep(5 * time.Second)
Expand Down Expand Up @@ -229,7 +229,7 @@ func TestPayToTwoOutputs(t *testing.T) {
RevealedTapscripts: []string{hex.EncodeToString(arkadeTapscript)},
}

explorer, err := mempoolexplorer.NewExplorer("http://localhost:3000", arklib.BitcoinRegTest)
explorer, err := mempoolexplorer.NewExplorer("http://localhost:3000/api", arklib.BitcoinRegTest)
require.NoError(t, err)

// ========================================
Expand Down
2 changes: 1 addition & 1 deletion test/recursive_covenant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func TestRecursivePolicy(t *testing.T) {
alicePkScript, err := txscript.PayToTaprootScript(alicePubKey)
require.NoError(t, err)

explorer, err := mempoolexplorer.NewExplorer("http://localhost:3000", arklib.BitcoinRegTest)
explorer, err := mempoolexplorer.NewExplorer("http://localhost:3000/api", arklib.BitcoinRegTest)
require.NoError(t, err)

submitAndFinalize := func(candidateTx *psbt.Packet, checkpoints []*psbt.Packet) {
Expand Down
2 changes: 1 addition & 1 deletion test/signed_pay_to_output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestSignedPayToOutput(t *testing.T) {
indexerSvc := setupIndexer(t)

explorerSvc, err := mempoolexplorer.NewExplorer(
"http://localhost:3000", arklib.BitcoinRegTest,
"http://localhost:3000/api", arklib.BitcoinRegTest,
)
require.NoError(t, err)

Expand Down
Loading
Loading