Step-by-step guide to running the x402 Cardano payment facilitator on the Cardano Preview testnet.
- Go to blockfrost.io and create a free account
- Create a new project, select Cardano Preview testnet
- Copy the project ID (starts with
preview...)
You need a 24-word seed phrase. If you don't already have one for testing:
- Option A: Generate one with cardano-cli or any Cardano wallet (Eternl, Nami, etc.)
- Option B: Use an existing test wallet seed phrase you already have
Then fund it:
- Get the wallet's receive address
- Go to the Cardano Preview Faucet
- Request test ADA (you need at least 5 ADA -- 2 for payment + fees + min UTXO)
cd ~/Documents/CODE/cardano402
pnpm docker:upThis starts Redis on port 6379.
cp config/config.example.json config/config.jsonThen edit config/config.json:
{
"server": { "host": "0.0.0.0", "port": 3000 },
"logging": { "level": "debug", "pretty": true },
"env": "development",
"chain": {
"network": "Preview",
"blockfrost": {
"projectId": "previewYOUR_KEY_HERE",
"tier": "free"
},
"facilitator": {
"seedPhrase": "your 24 word seed phrase here"
},
"cache": { "utxoTtlSeconds": 60 },
"reservation": { "ttlSeconds": 120, "maxConcurrent": 20 },
"redis": { "host": "localhost", "port": 6379, "db": 0 },
"verification": {
"graceBufferSeconds": 30,
"maxTimeoutSeconds": 300,
"feeMinLovelace": 150000,
"feeMaxLovelace": 5000000
}
},
"storage": {
"backend": "fs",
"fs": { "dataDir": "./data/files" }
}
}Key differences from the example config:
logging.level:"debug"(see everything during testing)logging.pretty:true(human-readable logs)env:"development"(not production)redis.host:"localhost"(notredis-prod)redis.password: removed (dev Redis has no auth)sentry: removed (not needed for testing)
pnpm devYou should see logs showing:
- Server starting on port 3000
- Redis connected
- Chain provider initialized (Lucid + Blockfrost)
- Routes registered
Test it quick:
curl http://localhost:3000/health | python3 -m json.tool
curl http://localhost:3000/supported | python3 -m json.toolHealth should show {"status":"ok","dependencies":{"redis":"up","chain":"up","storage":"up"}}.
In a separate terminal:
BLOCKFROST_KEY="previewYOUR_KEY_HERE" \
SEED_PHRASE="your 24 word seed phrase here" \
npx tsx examples/client.tsThis runs the full 7-step flow:
- Health check
- Query /supported
- POST /upload without payment -> gets 402
- Parse payment requirements from 402 response
- Build + sign a real Cardano transaction with Lucid
- Retry upload with Payment-Signature header -> settlement on-chain -> 200
- Download the file back and verify integrity
Step 6 is the big one -- it submits a real transaction to the Cardano preview blockchain and polls for confirmation. Expect it to take 20-60 seconds for the transaction to confirm.
After the client prints the transaction hash, verify it on a block explorer:
https://preview.cardanoscan.io/transaction/YOUR_TX_HASH
In the server logs (the pnpm dev terminal):
- CBOR deserialization succeeding
- All 10 verification checks passing
- Blockfrost submission returning a tx hash
- Confirmation polling succeeding
Once the happy path works, try these scenarios:
- Expired transaction -- should fail TTL check
- Replay the same transaction -- should hit SHA-256 dedup
- Wrong amount -- should fail amount check
- Wrong recipient address -- should fail recipient check