| name | swap |
| description | Perform a cross-chain atomic swap with detailed lifecycle timing. Use when the user wants to execute a test swap between two EVM networks. |
| disable-model-invocation | true |
Cross-Chain Swap
Perform an end-to-end cross-chain atomic swap using the Train solver, with detailed timing instrumentation to measure each phase of the swap lifecycle.
Prerequisites
The swap tool lives at tools/swap-cli/. Before first use, install dependencies:
cd tools/swap-cli && npm install
Wallet Setup
The tool uses a local ethers.js wallet stored at tools/swap-cli/.wallet.json (gitignored).
Check if wallet exists:
cd tools/swap-cli && node wallet.mjs address
If no wallet exists, create one:
cd tools/swap-cli && node wallet.mjs create
Then tell the user their wallet address and ask them to fund it with test ETH on the source network.
Check balance before swapping:
cd tools/swap-cli && node wallet.mjs balance <sourceChainRpcUrl>
If balance is zero or insufficient for the swap amount + gas, tell the user the wallet address and ask them to send funds.
Arguments
$ARGUMENTS should contain:
- Source network slug (e.g.,
arb-sepolia)
- Destination network slug (e.g.,
eth-sepolia)
- Amount in ETH (e.g.,
0.001)
- AdminAPI URL
- Source chain RPC URL (can use a public RPC from chainlist)
The user may provide these inline or you may need to ask for missing values. Destination RPC is auto-resolved from the AdminAPI network config.
Execution
Parse the arguments and run:
cd tools/swap-cli && node swap.mjs \
--admin-api <adminApiUrl> \
--source-network <sourceNetwork> \
--dest-network <destNetwork> \
--amount <amountInEth> \
--rpc-url <sourceChainRpcUrl> \
[--dest-rpc-url <destChainRpcUrl>] \
[--source-token <tokenContract>] \
[--dest-token <tokenContract>] \
[--include-reward]
Omit --source-token and --dest-token for native ETH swaps.
Use --include-reward so the solver redeems on the destination chain for the user (otherwise the user must submit their own redeem tx and needs gas on the dest chain).
Flow
The script will:
- Load the wallet and check source balance (asks for funds if insufficient)
- Snapshot destination balance (for verification)
- Get a quote from AdminAPI
- Generate a cryptographic secret and hashlock
- Build the user lock transaction via AdminAPI
- Sign and submit the lock transaction to the source chain
- Poll the order status until the solver locks on the destination chain
- Reveal the secret to the solver
- Attempt to redeem on dest chain (if user has gas there); otherwise solver redeems via reward
- Continue polling until the swap completes
- Verify destination balance increased by expected amount
- Print a detailed timing breakdown
After Swap
After the swap completes, analyze the timing report and share insights:
- Which phase took the longest?
- Is the bottleneck in chain confirmation, event detection, or solver processing?
- Compare against the theoretical minimum (block times on both chains)
Troubleshooting
- "No quotes available": Check that routes are active between the two networks
- "Insufficient balance": Fund the wallet address shown in the error
- Quote expired: The swap took too long — retry
- Signature verification failed: Check that rewardTimelock is passed as delta (seconds), not absolute timestamp
- Redeem on dest failed (insufficient funds): Use
--include-reward so solver redeems for you
- TIMEOUT: Increase poll count or check solver logs