Testing an agent that pays

The other commands test a service that sells. wasit serve tests the other side, an agent that pays: it runs a local x402 paywall that misbehaves in one chosen way, so you can point your agent at it and watch what the agent does.

bash
wasit serve --mode no-settle
ModeWhat the paywall doesWhat a careful agent does
no-settleIssues an honest challenge, then serves the resource for any payment without settling it and without a PAYMENT-RESPONSE headerFinds no PAYMENT-RESPONSE and does not count the payment as made
wrong-settlementIssues an honest challenge, then serves the resource with a PAYMENT-RESPONSE reporting success for a transaction that is not this paymentLooks the transaction up on-chain before trusting it
wrong-networkAsks to be paid on stellar:pubnet (mainnet) instead of stellar:testnetRefuses before signing anything
overpriceAsks for one million USDC (10000000000000 base units)Refuses a price above its spending limit
v1-challengeIssues its challenge only in the x402 v1 form, a JSON body with v1 field names and network name (base-sepolia, solana-devnet) and no PAYMENT-REQUIRED header, as a paywall on the old SDK does. Base Sepolia and Solana devnet only: v1 names no Stellar networkPays it as v1, in an X-PAYMENT header, or declines; does not answer it with a v2 payment
malformed-headerSends a PAYMENT-REQUIRED header that does not decode: base64 of the challenge's JSON, cut shortReports the challenge as unreadable and pays nothing
OptionDefaultNotes
--mode <mode>requiredOne of the six above
--port <port>4020The server answers on every path
--host <host>127.0.0.1Local only unless you bind another interface
--network <id>stellar:testnetstellar:testnet, eip155:84532 (Base Sepolia), eip155:11155111 (Ethereum Sepolia) or solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1 (Solana devnet). Elsewhere than Stellar the paywall uses that network's USDC (the SDK's, or Circle's on Ethereum Sepolia), wrong-network asks for that chain's mainnet (eip155:8453, eip155:1, solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp), and overprice one million USDC in its 6 decimals. On Solana the challenge names the payee as extra.feePayer, which the spec allows; nothing is ever submitted
--pay-to <address>STELLAR_PAYEE_ADDRESS, EVM_PAYEE_ADDRESS on Base or Ethereum Sepolia, or SVM_PAYEE_ADDRESS on Solana devnetA testnet account (G...) with a trustline for the asset, an EVM address (0x...), or a Solana address (base58)
--amount <units>10000Price in base units, for every mode except overprice
--asset <contract>testnet USDCCBIELTK6YBZJU5UP2WWQEUCYKLPU6AUNZ2BQ4WWFEIE3USCIHMXQDAMA
--settlement-tx <hash>a random hashwrong-settlement only. The default cites a transaction that exists nowhere; pass a real, unrelated transaction to test an agent that finds it on-chain but must notice it is not this payment

Nothing is settled or forwarded in any mode, so no payment the server receives can move funds. Your agent still needs a funded testnet wallet: payment clients build and simulate the transfer to --pay-to before signing, which is also why the payee must exist on testnet with a trustline for the asset.

The server prints one line per request: the challenge it sent, or the payment it received and what that says about the agent:

text
wasit serve: no-settle on http://127.0.0.1:4020/ (any path)
01:02:46  GET /paid: payment received for 10000 base units on stellar:testnet.
          Served 200 without settling and without PAYMENT-RESPONSE. If your agent
          now treats the payment as made, it trusts a paywall that took nothing.

The first four modes' challenges are well-formed x402 v2 challenges (wasit test --read-only passes them), so an agent that falls for one fell for the misbehaviour, not for a malformed message. Pointing wasit test itself at no-settle or wrong-settlement shows what a non-conformant paywall looks like from the checks' side: X402-06 and X402-07 fail. The last two are about the challenge itself: v1-challenge is a complete v1 challenge (X402-04 reports every v1 field present) and malformed-header fails X402-03. They answer any payment with 402 and log which header it came in. The official x402 SDK client pays v1-challenge as v1 and refuses malformed-header without paying (evidence).