-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
javascriptPull requests that update javascript codePull requests that update javascript codepythonPull requests that update python codePull requests that update python codetutorials
Description
Summary
Update all tutorial agents to use the new x402 access token flow instead of the legacy JWT-based flow. The x402 implementation provides a simpler developer experience with delegated session keys that enable auto-ordering of credits.
Important: Tutorials should follow the x402 transport specifications for each integration type.
Background
The Nevermined API has migrated from the old protocol module (initializeAgentRequest / redeemCredits with JWT tokens) to a new x402-based solution. The SDKs (@nevermined-io/payments and payments-py) have been updated with the necessary functionality.
Key x402 Advantages
- No pre-purchase required: Subscribers don't need to check balance or order plans in advance
- Delegated permissions: x402 tokens include "order" (auto top-up) and "burn" (redeem credits) session keys
- Smart Account integration: Uses ERC-4337 Account Abstraction for seamless transactions
x402 Transport Specifications
Each tutorial type should follow the corresponding x402 transport spec:
| Tutorial Type | x402 Transport Spec |
|---|---|
| HTTP (financial-agent, medical-agent) | specs/transports-v2/http.md |
| A2A (a2a-agent-client-example) | specs/transports-v2/a2a.md |
| MCP (weather-mcp, weather-mcp-py) | specs/transports-v2/mcp.md |
Migration Details
Old Flow (to be replaced)
// Client
const credentials = await payments.agents.getAgentAccessToken(planId, agentId);
// Server
const agentRequest = await payments.requests.startProcessingRequest(agentId, authHeader, url, httpVerb);
if (!agentRequest.balance.isSubscriber || agentRequest.balance.balance < 1n) {
return res.status(402).json({ error: "Payment Required" });
}
await payments.requests.redeemCreditsFromRequest(requestId, token, credits);New x402 Flow
// Client - much simpler, no balance check needed
const result = await payments.x402.getX402AccessToken(planId, agentId);
const x402Token = result.accessToken;
// Server
import { decodeAccessToken } from '@nevermined-io/payments'
const x402Token = authHeader.replace(/^Bearer\s+/i, "");
const decoded = decodeAccessToken(x402Token);
const verification = await payments.facilitator.verifyPermissions({
planId,
x402AccessToken: x402Token,
subscriberAddress: decoded.subscriberAddress,
maxAmount: BigInt(expectedCredits),
});
if (!verification.success) {
return res.status(402).json({ error: "Payment Required" });
}
// ... do work ...
const settlement = await payments.facilitator.settlePermissions({
planId,
x402AccessToken: x402Token,
subscriberAddress: decoded.subscriberAddress,
maxAmount: BigInt(actualCreditsUsed),
});Tutorials to Update
Phase 1: HTTP Tutorials (follow http.md)
-
financial-agent/agent/index_nevermined.ts- Server-side -
financial-agent/client/index_nevermined.ts- Client-side -
medical-agent/agent/index_nevermined.ts- Server-side -
medical-agent/client/index_nevermined.ts- Client-side
Phase 2: A2A Tutorial (follow a2a.md)
-
a2a-examples/a2a-agent-client-example/- Full migration
Phase 3: MCP Tutorials (follow mcp.md)
-
mcp-examples/weather-mcp/- TypeScript MCP server -
mcp-examples/weather-mcp-py/- Python MCP server
Reference Code & E2E Tests
TypeScript SDK (@nevermined-io/payments)
- E2E Test:
tests/e2e/test_x402_e2e.test.ts - FacilitatorAPI:
src/x402/facilitator-api.ts - X402TokenAPI:
src/x402/token.ts - decodeAccessToken:
src/utils.ts
Python SDK (payments-py)
- E2E Test:
tests/e2e/test_x402_e2e.py - PayAsYouGo E2E:
tests/e2e/test_pay_as_you_go_x402_e2e.py - FacilitatorAPI:
payments_py/x402/facilitator_api.py - X402TokenAPI:
payments_py/x402/token.py
API Implementation (nvm-monorepo)
- Controller spec:
apps/api/src/x402/x402.controller.external.spec.ts - Service:
apps/api/src/x402/x402.service.ts - Controller:
apps/api/src/x402/x402.controller.ts
Key SDK Methods
Subscriber (Client-side)
| Method | TypeScript | Python |
|---|---|---|
| Get x402 token | payments.x402.getX402AccessToken(planId, agentId) |
payments.x402.get_x402_access_token(plan_id, agent_id) |
Agent (Server-side)
| Method | TypeScript | Python |
|---|---|---|
| Decode token | decodeAccessToken(token) |
decode_access_token(token) |
| Verify | payments.facilitator.verifyPermissions({...}) |
payments.facilitator.verify_permissions(...) |
| Settle | payments.facilitator.settlePermissions({...}) |
payments.facilitator.settle_permissions(...) |
Optional Parameters
The getX402AccessToken method supports optional parameters:
redemptionLimit: Max number of interactions allowedorderLimit: Max spend limit in token units (wei)expiration: ISO 8601 expiration date (e.g., "2025-02-01T10:00:00Z")
Acceptance Criteria
- All tutorials use x402 flow instead of JWT flow
- Tutorials follow the corresponding x402 transport specs (HTTP, A2A, MCP)
- Client-side code is simplified (no balance checks or pre-purchase)
- Server-side uses
facilitator.verifyPermissions()andsettlePermissions() - README files updated with new flow explanation
- Environment variable documentation updated
- All tutorials tested end-to-end
Related Documentation
Metadata
Metadata
Labels
javascriptPull requests that update javascript codePull requests that update javascript codepythonPull requests that update python codePull requests that update python codetutorials