Quickstart
From zero to settled in 5 minutes.
Prerequisites
solana-cli2.0+ pointing at devnetanchor0.31.1bun1.3+- ≥ 0.5 SOL on the configured wallet (devnet airdrop is fine)
solana config set -u devnet
solana balance # >= 0.5 SOL
solana airdrop 2 # if lowInstall
git clone <aap repo>
cd aap
bun install
bun run --filter @aap/shared-types build
bun run --filter @aap/sdk-ts build
cd contracts && anchor buildOne-command x402 demo
The fastest end-to-end proof starts the demo merchant, waits for it to become healthy, runs the agent CLI, creates escrow, hits the paywalled endpoint, and confirms final settlement.
ANCHOR_PROVIDER_URL=https://api.devnet.solana.com \
ANCHOR_WALLET=~/.config/solana/id.json \
bun run demo:e2eOverride TARGET_URL or MERCHANT_URL if you want to point the demo at a different page or an already-running merchant server.
Hosted API and demo
The public demo is split into a visual merchant harness and a headless API. Use the root API URL when you want the console; use /v1/* endpoints when an agent needs JSON.
open https://demo.settleproof.xyz
open https://api.settleproof.xyz
curl -s https://api.settleproof.xyz/v1/status
curl -s 'https://api.settleproof.xyz/v1/indexer?limit=5'
curl -s https://api.settleproof.xyz/v1/relayHosted smoke test
Before a demo, run the hosted smoke script. It checks the landing, docs, OpenAPI, API status, escrow preparation, persistent indexer, demo health, and x402 challenge path.
bun run smoke:hosted
# optional overrides
SITE_URL=https://settleproof.xyz \
API_URL=https://api.settleproof.xyz \
DEMO_URL=https://demo.settleproof.xyz \
bun run smoke:hostedScenario 1 — Release (happy path)
Agent pays, merchant delivers and signs an attestation off-chain, on-chain CPI verifies the signature, USDC transfers to the merchant.
cd packages/sdk-ts
ANCHOR_PROVIDER_URL=https://api.devnet.solana.com \
ANCHOR_WALLET=~/.config/solana/id.json \
bun run examples/scenario-1-release.ts[1] Setup: mint USDC mock + fund agent/merchant
[2] Init registry + register merchant
[3] Mint USDC to agent + create ATAs
[4] Agent createEscrow → vault custodies 1 USDC
[5] Merchant signAttestation off-chain (Ed25519)
[6] releaseEscrow on-chain → CPI verify_attestation → transfer
[7] Verify final balances
✓ merchant: 1 USDC ← released
✓ vault: 0 USDC ← drained
✓ escrow state: fulfilled
✓ Scenario 1 complete — USDC released to merchantScenario 2 — TTL refund (auto dispute)
Agent pays, merchant fails to deliver and never attests. After TTL, anyone can call claim_refund and the funds return to the agent owner. No chargeback, no human arbitration.
bun run examples/scenario-2-refund.ts[3] Agent createEscrow with TTL=5s
[4] Merchant does not attest. Waiting for TTL to expire (7s)…
[5] Calling claimRefund (anyone can call)
✓ agent: 100 USDC ← refunded
✓ vault: 0 USDC ← drained
✓ escrow state: refundedScenario 3 — Partial release (split)
Merchant signs a partial attestation (e.g. delivered 60%). On-chain split sends 60% to the merchant and refunds 40% to the agent — settled in a single transaction.
bun run examples/scenario-3-partial.ts[4] partial_release(60) on-chain
✓ merchant: 0.6 USDC (expected 0.6)
✓ agent: net debit 0.6 USDC
✓ escrow state: partiallyFulfilled, partial_pct=60Scenario 4 — x402 HTTP paywall (E2E)
Run the demo merchant server in one terminal and the agent CLI in another. The merchant returns HTTP 402 with a challenge JSON; the agent creates an escrow and re-hits the endpoint with an X-Payment header; the server validates, runs the handler, and settles synchronously.
# Terminal 1
cd apps/demo-merchant
bun run start
# → http://localhost:8787
# Terminal 2
cd packages/sdk-ts
ANCHOR_PROVIDER_URL=https://api.devnet.solana.com \
ANCHOR_WALLET=~/.config/solana/id.json \
MERCHANT_URL=http://localhost:8787 \
TARGET_URL=https://news.ycombinator.com \
bun run examples/agent-cli.ts✓ HTTP 200
x-payment-settled: true
x-aap-tx-sig: <base58 signature>
url scraped: https://news.ycombinator.com
scraped_at: 2026-04-26T01:59:53.807Z
✓ final escrow state: fulfilledDemo merchant endpoints
GET /api/scrape?url=<url>— mock scrape result for an arbitrary URL.GET /api/report— generated merchant risk report.GET /api/inventory-check?sku=<sku>— inventory availability snapshot.POST /api/book-hotel-mock— mock reservation receipt with overbooking covered by TTL refund.
Troubleshooting
AmountTooLow (6001)
MIN_ESCROW_AMOUNT (1_000_000 stroops = 1 USDC). Pass at least 1 USDC, or redeploy the program with a smaller constant if you need micropayments.AccountNotInitialized
getOrCreateAssociatedTokenAccount(mint, merchant) during setup before the first release_escrow.AttestationStale
Date.now() by default — check the system clock.Insufficient SOL
solana airdrop 2 -u devnet.