Quickstart
Get up and running in 5 minutes: install, connect wallet, purchase credits, and make your first API call.
Prerequisites
| Item | Requirement |
|---|---|
| Node.js | >= 18 |
| Package Manager | npm / pnpm / yarn |
| Wallet Private Key | EVM: 0x prefixed hex private key or Solana: Base58 key |
Security Notice:Your private key is only used for local signing (SIWE/SIWS + EIP-3009) and is never sent to the gateway. We recommend passing it via environment variables and never committing it to your repository.
Step 1: Installation
Install the SDK
npm install @zan_team/x402 viemSolana Optional Dependencies
If using Solana wallets for authentication and payment, install additional dependencies:
npm install @solana/web3.js @solana/spl-token bs58 tweetnaclStep 2: Initialize the Client
Option 1: EVM Wallet (Recommended)
Create the client directly with a private key, with pre-authentication support:
import { createX402Client } from '@zan_team/x402';
const client = await createX402Client({
gatewayUrl: 'https://x402.zan.top',
privateKey: process.env.PRIVATE_KEY as `0x${string}`,
autoPayment: true,
preAuth: true,
});Parameter Description:
gatewayUrl: ZAN x402 gateway URLprivateKey: Your EVM wallet private key (prefixed with0x)autoPayment: Automatically purchase credits when insufficientpreAuth: Complete SIWE + JWT authentication on creation, suitable for long-running services
Option 2: Using viem WalletClient
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { mainnet } from 'viem/chains';
import { X402Client } from '@zan_team/x402';
const wallet = createWalletClient({
account: privateKeyToAccount('0xYourPrivateKey'),
chain: mainnet,
transport: http(),
});
const client = new X402Client({
gatewayUrl: 'https://x402.zan.top',
wallet,
autoPayment: true,
});Option 3: Solana Wallet
const client = await createX402Client({
gatewayUrl: 'https://x402.zan.top',
svmPrivateKey: process.env.SVM_PRIVATE_KEY!,
autoPayment: true,
preAuth: true,
});The SDK automatically infers chainType (EVM or SVM) based on the key type provided.
Step 3: Discover Gateway Capabilities (Optional)
The following endpoints do not require authentication and are suitable for probing available networks and bundles at startup:
// Check gateway health status
const health = await client.health();
console.log('Gateway status:', health);
// List available networks
const { networks } = await client.listNetworks();
console.log(`Available networks: ${networks.length}`);
networks.forEach(n => console.log(` - ${n.ecosystem}/${n.network}`));
// List available bundles
const { bundles } = await client.listBundles();
console.log(`Available bundles: ${bundles.length}`);
// Query x402 capabilities
const capability = await client.getX402Capability();
console.log('x402 capabilities:', capability);Step 4: RPC Calls
Basic Call
// Get latest block number
const block = await client.call('eth', 'mainnet', 'eth_blockNumber');
console.log('Latest block:', block.result);
// Query account balance
const bal = await client.call('eth', 'mainnet', 'eth_getBalance', [
'0x742d35Cc6634C0532925a3b844Bc9e7595f2bD18', 'latest',
]);
console.log('ETH balance (wei):', bal.result);Call Format: client.call(ecosystem, network, method, params?)
| Parameter | Description | Example |
|---|---|---|
| ecosystem | Ecosystem | eth, solana |
| network | Network | mainnet, base, arbitrum |
| method | RPC method | eth_blockNumber, eth_getBalance |
| params | Method parameters | Optional |
Batch RPC Calls
const results = await client.rpc.batch('eth', 'mainnet', [
{ method: 'eth_blockNumber' },
{ method: 'eth_gasPrice' },
{ method: 'net_version' },
]);
results.forEach((r, i) => {
console.log(`Result ${i}:`, r.result);
});Step 5: Transparent Fetch
client.fetch() has the same signature as the native fetch API, automatically injecting JWT and handling 402 responses. Suitable for existing HTTP call chains or MCP Tool Server scenarios:
const res = await client.fetch('/rpc/eth/mainnet', {
method: 'POST',
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'eth_blockNumber',
params: [],
}),
});
const data = await res.json();
console.log('Result:', data.result);Step 6: Credit Management
Check Balance
const { balance, tier } = await client.getBalance();
console.log(`Current balance: ${balance} Tier: ${tier}`);Purchase Credits
// Purchase default bundle
const receipt = await client.purchaseCredits('default');
console.log(`Purchased ${receipt.creditsPurchased} credits`);
console.log(`Transaction hash: ${receipt.txHash}`);Query Usage Records
const usage = await client.getUsage({ limit: 10 });
usage.records.forEach((r) => {
console.log(`
Method: ${r.methodName}
Cost: ${r.creditCost} credits
Latency: ${r.latencyMs}ms
Time: ${r.timestamp}
`);
});Step 7: Error Handling
import {
InsufficientCreditsError,
InsufficientFundsError,
UpstreamError,
SessionExpiredError,
NetworkError,
AuthenticationError,
} from '@zan_team/x402';
try {
const result = await client.call('eth', 'mainnet', 'eth_blockNumber');
console.log('Result:', result.result);
} catch (err) {
if (err instanceof InsufficientCreditsError) {
console.error(`Insufficient credits: need ${err.required}, have ${err.balance}`);
// Can choose to auto-purchase or prompt user
} else if (err instanceof InsufficientFundsError) {
console.error('Insufficient on-chain USDC balance, please top up');
} else if (err instanceof SessionExpiredError) {
console.error('Session expired, re-authenticating...');
await client.authenticate();
} else if (err instanceof AuthenticationError) {
console.error('Authentication failed, please check wallet signature');
} else if (err instanceof NetworkError) {
console.error('Network error:', err.message);
} else if (err instanceof UpstreamError) {
console.error('Upstream provider error:', err.message);
} else {
console.error('Unknown error:', err);
}
}Complete Example: AI Agent On-Chain Settlement
import { createX402Client } from '@zan_team/x402';
async function main() {
// 1. Create client (EVM)
const client = await createX402Client({
gatewayUrl: 'https://x402.zan.top',
privateKey: process.env.PRIVATE_KEY as `0x${string}`,
autoPayment: true,
preAuth: true,
});
// 2. Discover available networks
const { networks } = await client.listNetworks();
console.log(`β
Available networks: ${networks.length}`);
// 3. Check balance
const { balance } = await client.getBalance();
console.log(`β
Current balance: ${balance}`);
// 4. Call RPC
const block = await client.call('eth', 'mainnet', 'eth_blockNumber');
console.log(`β
Latest block: ${block.result}`);
// 5. Use fetch call
const res = await client.fetch('/rpc/eth/mainnet', {
method: 'POST',
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'eth_getBlockByNumber',
params: ['latest', false],
}),
});
const blockData = await res.json();
console.log(`β
Block details: ${blockData.result.number}`);
console.log('\nπ All operations completed!');
}
main().catch(console.error);Environment Variables Example
# .env file
# EVM private key (do not commit to version control!)
PRIVATE_KEY=0xYourEVMPrivateKeyHere...
# Or Solana private key
# SVM_PRIVATE_KEY=YourSolanaBase58PrivateKeyHere...Next Steps
- View full configuration options β Introduction-En.md
- View error type details β Error Handling
- View test cases β tests/
FAQ
Q: Is my private key safe?
A: Your private key is only used for locally generating signatures (SIWE/SIWS + EIP-3009 authorization) and is never sent to the ZAN gateway. We recommend:
- Passing via environment variables
- Using a .env file and adding it to .gitignore
- Using a key management service in production
Q: Which wallets are supported?
A:
- EVM: MetaMask, Rabby, Coinbase Wallet, etc.
- SVM: Phantom, Backpack, etc.
Q: Which blockchains are supported?
A: Currently supports 30+ networks, including:
- EVM: Ethereum, Base, Arbitrum, Optimism, Polygon, Avalanche, BNB Chain, etc.
- SVM: Solana
- Others: Bitcoin, etc.
Q: How do I get testnet USDC?
A: You can get test tokens from Base Sepolia or Solana Devnet for testing.
Support
- GitHub Issues: https://github.com/ZanTeam/zanx402-sdk/issues
- For documentation issues, please contact us.
Updated about 2 hours ago
