Skip to content

docs(x402): add a guide for adding Celo to an existing endpoint - #2420

Open
artugrande wants to merge 2 commits into
mainfrom
artugrande/x402-add-celo
Open

artugrande wants to merge 2 commits into
mainfrom
artugrande/x402-add-celo

Conversation

@artugrande

@artugrande artugrande commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

The hole, and the fix

The x402 pages explain how to start selling on Celo, but not how to add Celo to an endpoint that already sells on another network. That seller has a few Celo-specific ways to fail: one facilitator configured instead of two, the EIP-712 extra.name copied from another network, the dashboard host used as the facilitator URL.

This PR adds build/agents/x402-add-celo.mdx, a guide for that seller:

  • A route that keeps its existing network and adds USDC, USDT and USA₮ offers on Celo, with both facilitators on one resource server.
  • A self-check with npx @celo/buy quote, which needs no wallet and signs nothing.
  • How to keep an upstream API key on the server, including when the buyer is and is not charged if the upstream fails.
  • Troubleshooting with the exact error strings.

The page is in the nav, listed on /build/agents/overview and /build/agents/ai-resources (AGENTS.md section 8), and linked from Related on both x402 pages.

What this does NOT do / residual risk

  • No real mainnet settlement has run against this example yet. The paid flow below used fake facilitators, so nothing proves settlement through api.x402.celo.org with this exact code. I'll post the transaction hash here before this merges. A real USDC payment settled through api.x402.celo.org, see 0x125121df... under Verification evidence.
  • USDT and USA₮ were checked with buy quote, not settled. USDC, USDT and USA₮ use the same EIP-3009 path, but a domain problem specific to those two offers would only show on a real payment.
  • Not previewed with mint dev. mint broken-links passes, and it does not validate anchors, so I checked those by hand.
  • The Base offer was run against fake and third-party facilitators only, and no payment settled on Base.

Judgement calls

  • USDC, USDT and USA₮ addresses are in the example because a code block has to run. Everything else links to the x402 page instead of restating it.
  • The example uses Base as the existing network since that's where most sellers come from. It only says what to configure and compares nothing.
  • Kept the page to the 6-decimal EIP-3009 tokens and linked the Permit2 section for local-currency tokens.

Issues

Refs none.

Stacking / conflicts

Branched off current main, independent of other open PRs. build/agents/x402.mdx and x402-get-discovered.mdx only gain a line under Related.

Verification evidence

Run with @x402/express, @x402/core, @x402/evm and @x402/fetch 2.29.0, Node 22. The ts blocks were extracted from the page, with only payTo and the port replaced.

  • tsc --noEmit --strict on both blocks: passes.
  • Unpaid GET /rates with the Celo facilitator and PayAI as the existing one: 402, and the decoded header carries the Base and three Celo offers.
  • BUY_HOME=$(mktemp -d) npx @celo/buy quote <url> --token USDC|USDT|USAT (0.8.5, empty home): payable yes — matches --token X on celo for each.
  • Paid flow with a throwaway buyer key and local fake facilitators and upstream, no funds:
Case Buyer sees Facilitator calls
Celo USA₮, upstream 200 200 Celo: verify, settle, with X-API-Key
Celo USA₮, upstream 500 502 Celo: verify only, no settle
Base, upstream 200 200 Base: verify, settle, no Celo key sent
  • Real payment on Celo mainnet (42220), the page's first ts block with payTo from an env var and port 3010, paid with npx @celo/buy curl --token USDC --max-amount 0.01 (0.8.5): HTTP 200, 0x125121dff7d31875431ef81319b5729f0c5eead5b6b413b8ce37503a772a1c4d, block 81637407, status success. The USDC Transfer is 0.01 from the buyer to the payTo address. The transaction sender is 0x0d74D5Cefd2e7F24E623330ebE3d8D4cB45fFB48, the signer /supported lists for the facilitator, and the buyer holds 0 CELO.
  • Error strings, each provoked rather than copied. invalid_exact_evm_payload_signature and insufficient_funds came from the live /verify with an unfunded throwaway key. Facilitator does not support scheme..., Facilitator supported returned invalid JSON, the EIP-712 parameters error and the v1 buy quote line came from running each misconfiguration. The 401 row is taken from the x402 page.
  • Upstream key: not present in the unpaid 402 response.
  • Token addresses against Celo mainnet via eth_call: name() returns USDC, Tether USD, Tether America USD, decimals() returns 6 for all three, all EIP-55 valid.
  • npx mint broken-links: success no broken links found.

Remaining ops steps

Questions for the maintainer

@szapelao two things I found on x402.mdx while testing, left out of this PR since they're separate changes:

  1. The warning that price: "$0.01" throws No default asset configured for network eip155:42220 looks out of date. With @x402/evm 2.29.0 the shorthand works on Celo: the 402 is served and the payment reaches the facilitator, and the package's default-asset table has eip155:42220 with USDC first. Should the warning go, or say which version fixed it?
  2. "Check that it works" says the unpaid 402 has an empty {} body. On 2.29.0 the body is {"error":"Payment required"}.

Happy to send a small PR for both.

🤖 Generated with Claude Code

Covers the Celo offers and second facilitator, the buy quote self-check,
keeping an upstream API key on the server, and the exact errors a seller
coming from another network hits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@artugrande
artugrande requested a review from a team as a code owner November 1, 2026 12:48

@viral-sangani viral-sangani left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice guide, Celo setup checks out. 2 things before merge:

  • L46: put the Celo facilitator first, SDK picks the first match so the existing one can grab Celo payments
  • L35: rebuilding the existing client from its URL drops createAuthHeaders, tell people to reuse their configured client

nits: list tested versions on the page (L26), say to replace the old /rates handler (L107), and change "well formed" to "matches Buy's network/token/scheme" (L99)

…ient

- The resource server uses, for each network, the first facilitator that
  supports it, so a facilitator that also lists Celo and comes first takes
  the Celo payments. The example puts the Celo one first, and
  Troubleshooting has the symptom.
- The existing facilitator line says to reuse the configured client, since
  rebuilding it from its URL drops createAuthHeaders.
- Tested versions, the upstream handler replacing the /rates one, and what
  a "yes" from buy quote checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@artugrande

Copy link
Copy Markdown
Contributor Author

Thanks @viral-sangani, all addressed in fb3b8fa:

  • Celo facilitator first. Confirmed in @x402/core 2.29.0: initialize() keeps the first facilitator that lists a network and scheme. Ran the page's code with two local fake facilitators, the existing one listing Base and Celo. With the old order, a USA₮ payment on Celo was verified and settled by the existing facilitator. With the Celo one first, it went to the Celo facilitator with the API key, and a Base payment still went to the existing one. Added a Troubleshooting row for this.
  • Reuse the configured client. The existingFacilitator line now says it stands in for the client you already have, and that rebuilding it from its URL drops createAuthHeaders.
  • Nits. Tested versions in Prerequisites (@x402/* 2.29.0, express 5.3.0), the upstream section says its handler replaces /rates, and "well formed" is now "matches the network, token and scheme Buy pays with".

buy quote still reports payable yes for USDC, USDT and USA₮ against the updated code, and mint broken-links is clean.

@viral-sangani viral-sangani left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all addressed, thanks. heads up #2425 touches the same docs.json / overview / ai-resources lines, so whoever merges second needs a small rebase

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants