Grantex × x402 Playground

Explore official x402 v2 prepaid-wallet flow and legacy standalone GDT verification

@grantex/x402@0.4.1 and @grantex/sdk@0.8.2 are published and registry verified. External custody requires an operator adapter.

Key Generation Ed25519

GDT Issuance W3C VC 2.0

GDT Verification Ed25519 + Scope

x402 Flow Simulation HTTP 402

This visual simulation shows the managed prepaid flow. The GDT controls above are a separate legacy token demonstration and do not maintain wallet balance.

1
Agent requests the protected resourceOAuth access is DPoP-bound to /v1/prepaid-wallets
2
API returns official x402 v2 requirementsPAYMENT-REQUIRED: base64(JSON)
3
Grantex checks policy and reserves valueBalance + transaction + rolling + recipient + scope
4
Agent retries with one-time authorizationPAYMENT-SIGNATURE: base64(JSON)
5
Resource server verifies and settlesExact requirements and active reservation required
6
API returns data and settlement resultPAYMENT-RESPONSE: base64(JSON)

Code Examples TypeScript

import { generateKeyPair, issueGDT } from '@grantex/x402'; const principal = generateKeyPair(); const agent = generateKeyPair(); const gdt = await issueGDT({ agentDID: agent.did, scope: ['weather:read', 'news:read'], spendLimit: { amount: 10, currency: 'USDC', period: '24h' }, expiry: '24h', signingKey: principal.privateKey, });
import { verifyGDT } from '@grantex/x402'; const result = await verifyGDT(gdtToken, { resource: 'weather:read', amount: 0.001, currency: 'USDC', }); if (result.valid) { console.log('Agent:', result.agentDID); console.log('Remaining:', result.remainingLimit); } else { console.error('Rejected:', result.error); }
import { PrepaidWalletAgentClient } from '@grantex/sdk'; import { createX402Agent } from '@grantex/x402'; const walletAgent = new PrepaidWalletAgentClient({ oauthClient, accessToken, }); const x402 = createX402Agent({ authorizePayment: walletAgent.x402Authorizer, }); // Automatic: PAYMENT-REQUIRED → reserve → PAYMENT-SIGNATURE const response = await x402.fetch( 'https://api.weather.xyz/forecast' );
import express from 'express'; import { x402Middleware } from '@grantex/x402'; const app = express(); app.use('/api/weather', x402Middleware({ requiredScopes: ['weather:read'], requiredAmount: 0.001, currency: 'USDC', })); app.get('/api/weather/forecast', (req, res) => { const { gdt } = req; res.json({ forecast: 'sunny', authorizedBy: gdt.principalDID, }); });