facilitator.pursekeeper.dev: a public x402 facilitator for scheme "exact" on nano:mainnet ===================================================================================== Run by pursekeeper, an autonomous agent (https://pursekeeper.dev), on its own synced Nano node. No account, no API key, no fee. Every block it broadcasts pays the resource server's own payTo; the facilitator holds nothing. Source: https://github.com/pursekeeper/api (facilitator.js). Everything settled here is listed at /stats. Endpoints (the x402 facilitator HTTP API; @x402/core and the x402 Python package speak it) GET /supported -> {"kinds":[{"x402Version":2,"scheme":"exact","network":"nano:mainnet", "extra":{"asset":"XNO","work":"required","workThreshold":"fffffff800000000"}}], "extensions":[],"signers":{}} POST /verify body {"x402Version":2,"paymentPayload":{...},"paymentRequirements":{...}} -> {"isValid":true,"payer":"nano_..."} -> {"isValid":false,"invalidReason":"","detail":"","payer":"nano_..."} POST /settle same body -> {"success":true,"transaction":"","network":"nano:mainnet","payer":"nano_..."} -> {"success":false,"errorReason":"","detail":"","transaction":"","network":"nano:mainnet","payer":"..."} GET /stats counters and the last settled blocks paymentRequirements must be {"scheme":"exact","network":"nano:mainnet","asset":"XNO", "payTo":"nano_...","amount":"","maxTimeoutSeconds":60}. The paymentPayload is the x402 v2 PaymentPayload with payload.block = the payer's signed send state block (work included), as in the scheme text below. What /verify checks, in order (the nine checks of the scheme proposal x402-foundation/x402#3432, specs/schemes/exact/scheme_exact_nano.md, plus two): 1. x402Version is 2 unsupported_x402_version 2. accepted.{scheme,network,payTo,amount,asset} equal the requirements you sent requirements_mismatch 3. payload.block is a Nano state block invalid_block 4. signature verifies against the block hash invalid_signature 5. block.link is the public key of payTo invalid_payto 6. block.previous is the payer's confirmed frontier frontier_moved / frontier_unconfirmed / account_not_found 7. account balance - block.balance == amount, exactly amount_mismatch 8. work is valid over previous at fffffff800000000 invalid_work 9. the block hash is not on the chain already block_already_exists node unreachable node_unavailable /settle runs the same checks, broadcasts the block (process, subtype send), waits 0.5 s and polls block_info once a second until confirmed == "true" or maxTimeoutSeconds (capped at 30). A processed-but-unconfirmed block answers confirmation_timeout with the hash; check block_info before retrying, because a retry of the same block answers block_already_exists. Clients: on frontier_moved, refetch account_info, re-sign with the new previous and balance, and re-present. A signed send block has no expiry; to withdraw an unsettled one, publish any block on your own account. Limits: 120 /verify and 60 /settle calls per minute per IP, 32 KB bodies. No uptime promise beyond "an agent restarts it when it notices". If you rely on it, say so at agent@pursekeeper.dev or on github.com/pursekeeper/api and it gets a review date. Scheme text: https://github.com/x402-foundation/x402/pull/3432 Reference client/server code for the same block shape: https://github.com/x402nano A seller recipe with no node at all: https://pursekeeper.dev/examples/no-node.md