README
¶
Devnet & blockchain integration tests
Full deposit and withdrawal flows per chain, exercised end-to-end
against real nodes. The tests are build-tagged integration and live next to
each adapter (pkg/blockchain/<chain>/vault_integration_test.go). Each
withdrawal test runs the whole k-of-n quorum in-process — it holds N local
sign.KeySigners and drives Pack → Validate → Sign → Merge → Submit → VerifyExecution itself, so no p2p mesh is needed.
The TypeScript SDK integration tests live under sdk/ts/test and run through
the same make integration target.
Run
make devnet # anvil + bitcoind + rippled + solana-test-validator; blocks until all answer RPC
npm --prefix sdk/ts ci
make integration # Go blockchain integrations + TS EVM, Solana, XRPL, and Bitcoin integration
make devnet-down
make devnet returns only once every node answers (the devnet/wait probe).
After Node dependencies are installed, make integration needs no env. The
tests self-provision against the devnet and are idempotent: each run uses
fresh keys / accounts / a freshly-deployed contract, so re-running is a clean
run. Only each node's funder persists (anvil account 0, the bitcoind coinbase
wallet, the XRPL genesis master).
What each test provisions
- EVM — deploys a fresh
Custodyvault over N freshly-generated signer keys (funded from anvil account 0), deposits native ETH, then runs the quorum withdrawal. The TypeScript EVM integration test also deploys freshCustodyandMockERC20contracts and runs native ETH + ERC-20 deposit coverage. - BTC — creates a legacy wallet, mines to maturity, generates a fresh vault
- depositor, watch-imports their addresses, funds the depositor, deposits to
the per-account P2WSH address, then runs the quorum withdrawal (mining to
confirm between steps). The TypeScript Bitcoin integration test also creates
fresh local signers, funds the P2WPKH depositor address, submits a native BTC
deposit to the per-account P2WSH address, verifies
pending, mines, and verifiesconfirmed.
- depositor, watch-imports their addresses, funds the depositor, deposits to
the per-account P2WSH address, then runs the quorum withdrawal (mining to
confirm between steps). The TypeScript Bitcoin integration test also creates
fresh local signers, funds the P2WPKH depositor address, submits a native BTC
deposit to the per-account P2WSH address, verifies
- XRPL — funds a fresh vault + depositor from the genesis master,
SignerListSets the vault over fresh signer keys,TicketCreates a ticket, then deposits and runs the quorum withdrawal. Standalone rippled does not auto-close ledgers, so the test callsledger_acceptafter each submit. The TypeScript XRPL integration test creates fresh accounts, submits native XRP and issued-currency deposits, verifies each returned transaction reference, and asserts theynet-accountmemo carried the deposit destination. - Solana — the validator preloads the custody program upgradeable at its
fixed id (
--upgradeable-program), upgrade authority = the vendoreddevnet/sol-upgrade-authority.json. The test airdrop-funds the authority + depositor,Initializes the Config once (idempotent; gated on the upgrade authority), deposits native SOL, then runs the quorum withdrawal. The Config PDA is a singleton, so the signer set is fixed across runs and only the withdrawalID is fresh — re-runs stay clean without a validator restart. The TypeScript Solana integration test creates and funds local signers, submits native SOL and SPL deposits, and verifies each returned transaction reference. The validator image is multi-arch (noplatform:pin — the Agave validator needs AVX, which isn't emulable on Apple silicon).
For focused local iteration:
make devnet-evm
npm --prefix sdk/ts run test:integration:evm
make devnet-sol
npm --prefix sdk/ts run test:integration:sol
make devnet-xrpl
npm --prefix sdk/ts run test:integration:xrpl
make devnet-btc
npm --prefix sdk/ts run test:integration:btc
Optional overrides
Defaults target the devnet; override the endpoints if pointing elsewhere:
| env | default |
|---|---|
EVM_RPC_URL / EVM_DEPLOYER_KEY |
http://127.0.0.1:8545 / anvil account 0 |
BTC_RPC_URL / BTC_RPC_USER / BTC_RPC_PASS |
http://127.0.0.1:18443 / sdk / sdk |
XRPL_RPC_URL |
http://127.0.0.1:5005 |
XRPL_WS_URL / XRPL_ADMIN_RPC_URL |
ws://127.0.0.1:6006 / http://127.0.0.1:5005 |
SOL_RPC_URL |
http://127.0.0.1:8899 |
Notes
- The tests double as the executable spec for the adapter interfaces: the
withdrawal flow shows exactly how a custody node calls the SDK
(
Pack/Validate/Sign/Merge/Submit/VerifyExecution); the only piece left to the caller is collecting the quorum's signatures over its mesh. - The rippled image is
linux/amd64(pinned viaplatform:); on Apple silicon it runs under emulation — works, just slower to start.
Directories
¶
| Path | Synopsis |
|---|---|
|
Command wait blocks until every devnet node answers RPC, then exits 0 — so `make devnet` returns only once the infra is ready to drive.
|
Command wait blocks until every devnet node answers RPC, then exits 0 — so `make devnet` returns only once the infra is ready to drive. |