Skip to content

fix(agentic-payments): align skill with @x402/* v2.12 and clarify setup#26

Merged
kaankacar merged 2 commits into
stellar:mainfrom
oceans404:fix/agentic-payments-skill-v2
May 21, 2026
Merged

fix(agentic-payments): align skill with @x402/* v2.12 and clarify setup#26
kaankacar merged 2 commits into
stellar:mainfrom
oceans404:fix/agentic-payments-skill-v2

Conversation

@oceans404
Copy link
Copy Markdown
Contributor

Summary

  • Rewrites the x402 Seller and Buyer code samples against the current @x402/* v2.12 API. The skill's prior samples threw at startup (server) and at the first request (client).
  • Marks the OZ Channels testnet API key as required, since channels.openzeppelin.com/x402/testnet/supported now returns 401 without Authorization: Bearer.
  • Restructures the testnet runbook as an ordered checklist over two accounts (payer + recipient), with trustlines on both, a clear note that the Circle faucet and OZ key gen are web-only steps, and a setup.js sketch for the parts that can be scripted.
  • Adds a "Two USDC addresses" section to disambiguate classic issuer (G...) from SAC (C...), and references the USDC_TESTNET_ADDRESS / USDC_PUBNET_ADDRESS exports.
  • Updates "Common pitfalls" with: trustline-on-recipient, browser-signing gap, and the createEd25519Signer argument 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) with new x402ResourceServer(facilitator).register(network, new ExactStellarScheme()).
  • Route config moved under accepts: { scheme: "exact", price, network, payTo }.
  • createAuthHeaders is 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 raw S... string and the CAIP-2 network ID; both Keypair.fromSecret and getNetworkPassphrase are done internally, so pre-wrapping caused TypeError: encoded argument must be of type String or Unknown Stellar network: ....

Test plan

  • Installed @x402/* v2.12.0 + @stellar/stellar-sdk in a fresh sandbox.
  • Pasted the new Seller and Buyer code blocks verbatim from the edited SKILL.md into server.js and client.js.
  • Pointed .env at 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.
  • Ran node server.js — boots clean, no facilitator init errors.
  • Ran node client.jsstatus: 200, weather payload returned, $0.001 USDC settled through OZ Channels.
  • Confirmed without OZ_API_KEY the server crashes at startup with Failed 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

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>
Copilot AI review requested due to automatic review settings May 21, 2026 14:06
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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, correct createEd25519Signer usage).
  • 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.js sketch.
  • 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 };
},
Comment thread skills/agentic-payments/SKILL.md Outdated
| 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>
@oceans404
Copy link
Copy Markdown
Contributor Author

Thanks for the review — all three items addressed in 45c0518.

  1. Missing dotenv load (line 224). Both samples now import "dotenv/config" at the top, so the .env step described in the runbook actually takes effect.
  2. Silent Bearer undefined (line 84). Added an explicit throw new Error(...) at server startup when OZ_API_KEY is missing, with the generation URLs in the message. Verified by setting OZ_API_KEY= and re-running: the server now exits with a clear message instead of producing an opaque 401.
  3. Network ID hard-coded in three places (line 297). Centralized via a NETWORK const driven by STELLAR_NETWORK (defaulting to stellar:testnet). Both samples reference it everywhere the network appears (register(NETWORK), accepts.network, createEd25519Signer second arg, schemes[].network). Added STELLAR_NETWORK to the runbook .env example, and rewrote the mainnet checklist note: switching networks is now .env-only, no code edits.

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 200.

@kaankacar kaankacar merged commit c086ef7 into stellar:main May 21, 2026
3 checks passed
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.

agentic-payments SKILL.md is out of sync with @x402/* v2.12 (samples will not run)

3 participants