[ Executable x402 v2 buyer // Base Mainnet ]

Discover. Constrain. Pay. Verify. Use.

One runnable agent recipe goes from Coinbase Bazaar discovery to a source-linked Maha Context Pack. It supports CDP Server Wallets and plain Viem accounts, and it will not sign if the live terms exceed $0.005 or differ from the expected $0.001 purchase.

Gate 1

Search Bazaar

Use semantic search with Base, USDC, exact-payment, and maxUsdPrice=0.005 filters. If the asynchronous semantic index has not refreshed, use Bazaar merchant discovery as the exact indexed fallback.

Gate 2

Inspect the contract

Read the discovered input example plus input and output JSON Schemas. Refuse missing or malformed discovery metadata.

Gate 3

Apply policy before signing

Require Base Mainnet, native Base USDC, the published Maha payee, exactly 1,000 base units, and a hard ceiling of 5,000 base units.

Gate 4

Pay once

Load either a plain Viem account or a named CDP Server Wallet only after discovery and policy checks pass. Re-check the live 402 terms before producing a signature.

Gate 5

Verify settlement

Require PAYMENT-RESPONSE success, a Base transaction hash, the expected network, and the signing wallet as payer.

Gate 6

Use the Context Pack

Validate the paid response shape and produce a downstream prompt that preserves source-linked passage citations.

[ Run the machine flow ]

Discovery is free. Payment is an explicit flag.

Dry discovery

npm run recipe:bazaar-payment

Searches Bazaar, inspects schemas, and evaluates terms. It never loads a wallet.

Plain Viem wallet

X402_BUYER_PRIVATE_KEY=0x… npm run recipe:bazaar-payment -- --pay --wallet=viem

Uses a dedicated limited-balance EOA. The key stays in the process environment.

CDP Server Wallet

npm install --save-dev @coinbase/cdp-sdk
CDP_ACCOUNT_NAME=maha-agent npm run recipe:bazaar-payment -- --pay --wallet=cdp

Also requires CDP_API_KEY_ID, CDP_API_KEY_SECRET, and CDP_WALLET_SECRET in the environment.

Fund only the selected Base account with the USDC needed for the test. Do not commit wallet secrets, use a personal high-balance wallet, or remove the local policy checks.

[ Local policy ]

The catalog never gets signing authority.

The recipe evaluates the catalog requirement, then independently evaluates the live PAYMENT-REQUIRED challenge immediately before signing. A changed price, asset, network, payee, or scheme fails closed.

After the API responds, the recipe decodes PAYMENT-RESPONSE and binds the success receipt to the wallet, Base network, and on-chain transaction before using the body.

function assertSpendPolicy(requirement) {
  if (requirement.scheme !== 'exact') throw new Error('scheme')
  if (requirement.network !== 'eip155:8453') throw new Error('network')
  if (requirement.asset.toLowerCase() !== BASE_USDC) throw new Error('asset')
  if (requirement.payTo.toLowerCase() !== MAHA_PAYEE) throw new Error('payee')

  const amount = BigInt(requirement.amount)
  if (amount > 5_000n) throw new Error('spend ceiling')
  if (amount !== 1_000n) throw new Error('unexpected price')
}

Operational boundaries

  • One paid retry: the buyer answers one 402 once; it does not loop wallet prompts.
  • Discovery fallback: semantic results can lag settlement metadata. Bazaar merchant discovery provides the deterministic indexed fallback.
  • Receipt verification: the recipe verifies the signed response metadata. The transaction link is printed for independent Base explorer inspection.
  • Context boundary: source coverage means sources represented in selected passages, not guaranteed fact retention or downstream answer correctness.