fix(agentic-payments): align skill with @x402/* v2.12 and clarify setup#26
Merged
Merged
Conversation
The x402 section's seller and buyer samples no longer ran against the
published @x402/* v2.12 packages, and the OZ Channels testnet facilitator
now requires an API key. Rewrites Part 1 against the current API and
fixes the onboarding gaps that came up while standing up a working
service end to end.
Code changes:
- Seller: paymentMiddleware + x402ResourceServer with new ExactStellarScheme().
Route config uses accepts:{scheme:"exact",...}. OZ_API_KEY is required.
- Buyer: wrapFetchWithPaymentFromConfig with new ExactStellarScheme(signer).
createEd25519Signer takes the raw S... secret and the CAIP-2 ID directly;
drops the Keypair indirection and the getNetworkPassphrase double-call.
Documentation:
- Testnet runbook is now an ordered checklist over two accounts (payer and
recipient), with trustlines on BOTH, and a setup.js sketch for the
deterministic steps.
- Calls out that the Circle faucet and OZ key gen are manual web steps.
- New "Two USDC addresses" section distinguishes classic issuer (G...) from
SAC contract (C...). References USDC_TESTNET_ADDRESS / USDC_PUBNET_ADDRESS
exported by @x402/stellar.
- Pitfalls: adds trustline-on-recipient, browser-signing gap, and the
Keypair/passphrase argument mistakes. Updates the OZ Channels 401 entry
to reflect that the key is required on testnet too.
Verified end to end on Stellar testnet: server boots, client paid \$0.001
USDC, settled through OZ Channels, returned 200. Closes stellar#25.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Updates the agentic-payments skill’s x402 (Part 1) documentation and code samples to match the current @x402/* v2.12 API and revised OZ Channels requirements, so users can copy/paste the Seller (Express) and Buyer (client) examples and complete the testnet setup successfully.
Changes:
- Rewrites Seller and Buyer code samples to use the v2.12 entry points (
paymentMiddleware+x402ResourceServer,wrapFetchWithPaymentFromConfig, correctcreateEd25519Signerusage). - Updates setup guidance to reflect that OZ Channels now requires an API key on testnet and mainnet, and restructures the testnet runbook + adds a
setup.jssketch. - Clarifies USDC address concepts (classic issuer vs SAC contract) and references exported constants.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+222
to
+224
| node server.js | ||
| # in another terminal | ||
| node client.js |
Comment on lines
+80
to
+84
| // OZ Channels requires Bearer auth on both testnet and mainnet | ||
| createAuthHeaders: async () => { | ||
| const h = { Authorization: `Bearer ${process.env.OZ_API_KEY}` }; | ||
| return { verify: h, settle: h, supported: h }; | ||
| }, |
| | Funding | Real USDC on mainnet (CEX, DEX, or bridge) | | ||
|
|
||
| Always test on testnet first. Switch by changing `network` and `FACILITATOR_URL`. | ||
| Always test on testnet first. Switch by changing `network` and `FACILITATOR_URL`. Both networks require an OZ Channels API key in the `Authorization: Bearer` header. |
…uard, NETWORK const) - Add `import "dotenv/config"` to both seller and buyer samples so the .env step the runbook describes actually takes effect. - Throw an explicit error at server startup when OZ_API_KEY is missing, instead of letting createAuthHeaders emit `Bearer undefined` and 401. - Drive the CAIP-2 network ID from a single NETWORK const in both samples (env-overridable via STELLAR_NETWORK). The network is now referenced in one place per file: register(NETWORK), accepts.network, createEd25519Signer second arg, and schemes[].network. Mainnet switch is .env-only, no code edits. Add STELLAR_NETWORK to the runbook .env example and rewrite the mainnet checklist note accordingly. Re-verified end to end on Stellar testnet: missing-key path throws a clear message; happy path settles $0.001 USDC and returns 200. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Thanks for the review — all three items addressed in 45c0518.
Re-verified end to end on Stellar testnet with the updated samples copied verbatim into a fresh sandbox: missing-key path throws the explicit error; happy path settles $0.001 USDC and returns |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
@x402/*v2.12 API. The skill's prior samples threw at startup (server) and at the first request (client).channels.openzeppelin.com/x402/testnet/supportednow returns 401 withoutAuthorization: Bearer.setup.jssketch for the parts that can be scripted.G...) from SAC (C...), and references theUSDC_TESTNET_ADDRESS/USDC_PUBNET_ADDRESSexports.createEd25519Signerargument mistakes that the prior samples encoded.The MPP half of the skill (Part 2) is untouched — this PR is scoped to x402.
Closes #25.
What changed in the code samples
Server
paymentMiddlewareFromConfig({ facilitator, schemes })→paymentMiddleware(routes, resourceServer)withnew x402ResourceServer(facilitator).register(network, new ExactStellarScheme()).accepts: { scheme: "exact", price, network, payTo }.createAuthHeadersis unconditional (key required on both networks).Client
x402HTTPClient({ ... })(a class, not a callable) →wrapFetchWithPaymentFromConfig(fetch, { schemes: [{ network, client: new ExactStellarScheme(signer) }] }).createEd25519Signer(Keypair.fromSecret(s), getNetworkPassphrase(n))→createEd25519Signer(s, "stellar:testnet"). The signer takes the rawS...string and the CAIP-2 network ID; bothKeypair.fromSecretandgetNetworkPassphraseare done internally, so pre-wrapping causedTypeError: encoded argument must be of type StringorUnknown Stellar network: ....Test plan
@x402/*v2.12.0 +@stellar/stellar-sdkin a fresh sandbox.server.jsandclient.js..envat a fresh testnet payer (with USDC trustline + 20 USDC from Circle) and recipient (with USDC trustline), and a freshly generated OZ Channels testnet API key.node server.js— boots clean, no facilitator init errors.node client.js—status: 200, weather payload returned, $0.001 USDC settled through OZ Channels.OZ_API_KEYthe server crashes at startup withFailed to initialize: no supported payment kinds loaded from any facilitator, which is exactly the message users were hitting under the prior "optional on testnet" guidance.🤖 Generated with Claude Code