Skip to main content
Choose your path: SDK quickstart · CLI quickstart Swap 1 USDCx for ETH on testnet. Each swap takes two transactions: a request and a claim. Your trade is complete when the claim succeeds and the returned token records are available. Choose a language below. The matching tabs will use your choice throughout the page.
Use Node.js 22 or later and npm with @provablehq/shield-swap-sdk 0.11.1.Create four files:
  • client.ts saves your account and configures the SDK.
  • fund.ts requests test tokens.
  • first-swap.ts quotes the trade, submits it, and claims the output.
  • verify.ts checks transaction acceptance and balances without submitting a trade.
To run these examples as JavaScript, use .js filenames, change local imports to "./client.js", and replace npx tsx with node in the run commands.This code always uses testnet, regardless of the network selected in the docs.
Keep funding in a separate script so you can retry it without submitting another trade.

1. Create the project and account

Create a project and install the SDK:
"type": "module" enables ES modules and top-level await. tsx runs TypeScript; you can skip that dependency if you use JavaScript.Create .gitignore before continuing:
Create client.ts. It generates a testnet account on first use and reuses the saved key on later runs.
The script prints your account address. It saves the private key to .shield-swap/testnet/private-key.txt and never prints the key.createAleoClient({ privateKey }) sets up the gateway, record scanner, delegated proving, and fee payment. You don’t need Provable API credentials or endpoint configuration. swapFileStore saves the data needed to recover claims. Use publicClient to check transaction status and the extended wallet client for swap and record actions.Keep .shield-swap/ between sessions and run all commands from this project directory. To use an existing testnet account, create .shield-swap/testnet/private-key.txt with your key before the first run.The sign-in message includes the current Terms of Use and related disclosures. Successful authentication records acceptance and grants API access. No invite code or .env file is required.

2. Fund the account

Delegated proving pays testnet fees, so the account does not need a public ALEO balance.
Create fund.ts. It signs in and checks your USDCx balance, then requests test tokens only if you need them.
Wait for Ready: ... USDCx available before continuing. The first run can take several minutes: confirmAirdrop waits for the faucet job and scans for its token records. If a transfer is incomplete or a rate limit leaves you short of USDCx, the balance check stops the script.If the API returns terms_required, run fund.ts again to sign in with a new challenge. Referral-code redemption does not grant API access. Funding never submits a swap.
fetch failed with cause UND_ERR_CONNECT_TIMEOUT means Node timed out while connecting to the API. Check the last progress message to see which stage failed. This error does not indicate an invalid key or failed terms acceptance.Check connectivity from the same terminal without loading your account:
A 200 response confirms that the public token endpoint is reachable. Rerun fund.ts. If the connection still times out, check your network, VPN or proxy configuration, and API availability. Increasing the faucet polling timeout or swap confirmation timeout does not change this connection timeout.
The airdrop delivers spendable token records. If a later swap needs one larger record, see Preparing token records.

3. Create the swap client

Add the code from steps 3 to 5 to one swap script, then run it at the end of step 5. This first step creates the client without submitting a swap.
Save this as first-swap.ts. Importing client.ts reuses the account and recovery store from step 1.

4. Quote and review

Append the code for your language to the swap script. Both SDKs can select a route through one to three pools. Slippage applies to the final output.
amountIn: "1" means one USDCx. Use a decimal string for token units or a bigint for raw base units; JavaScript numbers are not accepted.A quote needs a usable output estimate and a positive minimum output. It expires 60 seconds after the request starts. If it expires before submission, the SDK stops. Request and review a new quote without editing or extending the expired one.
50 basis points is 0.5% slippage. You haven’t submitted anything yet. A swap spends one token record, so a balance split across smaller records may need record preparation even if the total covers the trade.

5. Submit and claim

Append the code for your language to the swap script.
You can claim the output after the swap finalizes. If the script times out, check the transaction status before submitting again; the transaction may still succeed. Don’t rerun the swap script to finish an existing trade.
swap({ quote }) chooses single- or multi-hop execution and keeps the quoted minimum output. In this example, waitForSwapOutput polls for up to 60 seconds until the request is confirmed and its output is ready, without submitting a transaction. claimSwapOutput resolves program imports automatically.
Run the completed script:
The script prints Swap transaction:, Claim transaction:, and Received .... The claim returns the output amount and any unspent input as a refund. The scanner may take longer to find the returned records. If they remain unavailable, see Missing output records. Keep .shield-swap/, and do not resubmit an accepted claim.

6. Verify the result

Save both transaction IDs and the received amount. Check that the network accepted the transactions and that your account can find the returned records. Verification reads existing state, so running it won’t start another swap.
Create verify.ts:
Replace the two placeholders with the IDs printed by first-swap.ts:
Expect Swap: accepted and Claim: accepted. If you started with 10 USDCx and 0.006 ETH and had no other activity or refund, expect balances of 9 USDCx and 0.006 + received ETH. Use the amount you actually received; it can differ from the quote estimate.Call getConfirmedTransaction on publicClient; it isn’t available on client. If the lookup fails or times out, check your connection and transaction IDs, then rerun verification. Until you know the outcome, don’t submit another swap or claim.Run the settlement verifier to confirm that the claim belongs to this swap and its output record is unspent. It also checks that swap_outputs[swap_id] has been cleared.

Finish an interrupted swap

Use the same saved account and recovery data. Do not restart first-swap.ts or first-swap.py to recover a submitted trade.
Create recover.ts:
This script claims ready outputs without starting another swap. See Recover pending claims for history reconciliation.
An empty list alone doesn’t tell you whether the trade failed. The request may still be pending, or the output may already have been claimed. If you can’t confirm the outcome, follow Failures and recovery.

Next steps

See Trader workflow for the full integration lifecycle. For TypeScript, read Swap with the TypeScript SDK for recovery and concurrent swaps, or Connect a wallet. The Python SDK reference covers additional trading and liquidity methods.