Skip to content

Spike: x402 build shape — hand-rolled EIP-3009 vs x402-rs, and prove the fully-local facilitator loop #206

Description

@hellno

Standalone spike for the x402 track (#31#32#34). Time-boxed; throwaway code; feeds two decisions into #34 before it starts.

Question 1 — build shape: hand-rolled EIP-3009 vs x402-rs (dep decision)

The trust core needs to sign the x402 exact payload: an EIP-3009 TransferWithAuthorization as EIP-712 typed data (from, to, value, validAfter, validBefore, nonce). Two candidate shapes; new deps require explicit approval (DoD rule 4), so decide with evidence:

  • Hand-roll the typed data via alloy sol! in deckard-core — the cow_types precedent (EIP-712 via alloy, KAT-gated against a reference implementation).
  • Depend on x402-types/x402-reqwest (github.com/x402-rs/x402-rs, Apache-2.0, alloy-based, supports v1+v2).

Compare: surface area pulled into the trust core, audit load, serde/wire fit, and who owns header parsing (v1 X-PAYMENT body-JSON vs v2 PAYMENT-REQUIRED/PAYMENT-SIGNATURE base64 headers, CAIP-2 network ids). Default lean: hand-roll in the core, use x402-rs only in demo fixtures — but let the spike overturn it.

Question 2 — prove the fully-local loop on OUR demo world

Neither hosted facilitator serves Ethereum Sepolia (CDP: Base/Polygon/Arbitrum/World/Solana; x402.org testnet: Base Sepolia et al.) — self-hosting is required, and it is architecturally plausible but undocumented upstream. Prove it:

  1. anvil fork of Ethereum Sepolia (the existing demo world, block 10822990).
  2. Self-hosted facilitator — x402-rs facilitator or second-state/x402-facilitator — configured with an eip155:11155111 chain entry pointing at the fork RPC. Note: x402-rs takes a JSON config with per-chain rpc entries keyed by CAIP-2 id (env vars only override values), not RPC_URL_* vars.
  3. The real Circle USDC on Sepolia (0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238) — verified on Etherscan as FiatTokenV2_2 with transferWithAuthorization/receiveWithAuthorization/cancelAuthorization — so the fork carries genuine EIP-3009 bytecode.
  4. Buyer signs with a throwaway key; facilitator /verify then /settle against the fork; assert the USDC balance moved and the nonce is consumed.

Deliverables

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions