JavaScript SDK (@paynodelabs/sdk-js)
The PayNode JavaScript SDK provides a seamless integration for both AI Agents (to pay) and Merchants (to accept payments). It handles the complete x402 lifecycle: intercepting 402 responses, on-chain execution via ethers, and stateless verification.
๐ค For AI Agents (Client)
The PayNodeAgentClient intercepts HTTP 402 and handles the payment handshake automatically.
๐ Recommended: Auto-Select (requestGate)
The PayNodeAgentClient automatically handles the 402 handshake. It parses the merchantโs accepts array and selects the best payment method (e.g., preferring EIP-3009 if available).
import { PayNodeAgentClient } from '@paynodelabs/sdk-js';
const agent = new PayNodeAgentClient(process.env.AGENT_PRIVATE_KEY);
// SDK automatically chooses between On-chain or EIP-3009
const response = await agent.requestGate('https://api.merchant.com/premium-data');
const data = await response.json();
console.log(data);Manual: On-chain (agent.pay())
If you want full control over the transaction, you can manually call the pay method. This executes an on-chain transaction immediately.
import { PayNodeAgentClient } from '@paynodelabs/sdk-js';
const agent = new PayNodeAgentClient(process.env.AGENT_PRIVATE_KEY);
// On-chain: agent pays gas, immediate settlement
const txHash = await agent.pay(
'0xRouterAddress...',
'0xUSDCAddress...',
'0xMerchantWallet...',
10000n, // Amount in atomic units (6 decimals for USDC)
'order_123'
);
console.log(`Payment successful: ${txHash}`);Manual: EIP-3009 (agent.signTransferWithAuthorization())
For gasless payments, the agent signs an authorization off-chain, which the merchant then submits on-chain.
import { PayNodeAgentClient } from '@paynodelabs/sdk-js';
const agent = new PayNodeAgentClient(process.env.AGENT_PRIVATE_KEY);
// signs a transfer authorization
const { signature, authorization } = await agent.signTransferWithAuthorization(
'0xUSDCAddress...',
'0xMerchantWallet...',
10000n,
validAfter, // (Math.floor(Date.now() / 1000))
validBefore, // (+ 3600)
nonce // (ethers.randomBytes(32))
);
console.log("Signature generated:", signature);๐ช For Merchants (Express)
The x402Gate middleware provides instant protection for your API routes.
import express from 'express';
import { x402Gate } from '@paynodelabs/sdk-js';
const app = express();
// 2-parameter minimalist initialization (Defaults to Base Mainnet USDC)
app.get('/api/protected', x402Gate({
merchantAddress: '0xYourWalletAddress',
price: '1.00' // 1.00 USDC
}), (req, res) => {
res.json({ message: 'Success! You paid for this data.' });
});๐ก๏ธ Token Whitelist
The Verifier includes a built-in token whitelist to prevent fake-token attacks. By default, it accepts:
| Network | Chain ID | Accepted Token (USDC) |
|---|---|---|
| Base Mainnet | 8453 | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 |
| Base Sepolia | 84532 | 0x65c088EfBDB0E03185Dbe8e258Ad0cf4Ab7946b0 (Sandbox) |
Customization
import { PayNodeVerifier, ACCEPTED_TOKENS } from "@paynodelabs/sdk-js";
// Use chain default (auto-detected from chainId)
const verifier = new PayNodeVerifier({
rpcUrls: ["https://mainnet.base.org"],
chainId: 8453
// acceptedTokens is auto-loaded from ACCEPTED_TOKENS[8453]
});
// Custom whitelist (e.g. only accept DAI)
const verifier = new PayNodeVerifier({
rpcUrls: ["https://mainnet.base.org"],
chainId: 8453,
acceptedTokens: ["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"] // USDC on Base
});
// Explicitly disable whitelist (testing only)
const verifier = new PayNodeVerifier({
rpcUrls: ["http://localhost:8545"],
acceptedTokens: [] // No whitelist check
});๐ Production: Redis Idempotency
For production multi-instance deployments, use RedisIdempotencyStore instead of the default in-memory store:
import Redis from "ioredis";
import { x402Gate, RedisIdempotencyStore } from "@paynodelabs/sdk-js";
const redis = new Redis(process.env.REDIS_URL);
app.get(
"/api/data",
x402Gate({
// ...other options
store: new RedisIdempotencyStore(redis, "paynode:tx:")
}),
handler
);๐ Interactive Demo
The source repository contains a ready-to-use demo suite in packages/sdk-js/examples/. This is the fastest way to test the full x402 payment lifecycle on Base Sepolia.
1. Configuration (.env)
Create a .env file in the examples/ directory:
AGENT_PRIVATE_KEY=your_private_key_here
MERCHANT_ADDRESS=your_merchant_receiving_wallet
# Router is auto-loaded but can be overridden
PAYNODE_CONTRACT_ADDRESS=0x24cD8b68aaC209217ff5a6ef1Bf55a59f2c8Ca6F2. Run the Suite
Start the merchant server and agent client:
# Terminal A
npx ts-node packages/sdk-js/examples/express-server.ts
# Terminal B
npx ts-node packages/sdk-js/examples/agent-client.tsThe demo will output the handshake, on-chain transaction logs, and the final successful response with the nested payment_info object.
๐ก Webhook Notifications
See the dedicated Webhooks page for setup instructions.