REST Client SDK — @paygate/client-x402-rpc
The @paygate/client-x402-rpc package is a TypeScript client for the x402 RPC Gateway REST API. It wraps all client-facing endpoints — authentication, credit management, RPC execution, and history — into a single composable class with built-in x402 payment handling.
Installation
pnpm add @paygate/client-x402-rpcQuick Start
Ethereum (SIWE)
import { X402RpcClient } from "@paygate/client-x402-rpc";
import { EthereumX402Client, InjectedWalletConnector } from "@paygate/client-ethereum";
const wallet = new InjectedWalletConnector();
const paymentClient = new EthereumX402Client({
walletConnector: wallet,
chainId: 1,
});
const client = new X402RpcClient({
appUrl: "https://myapp.example.com",
gatewayUrl: "https://gateway.example.com",
evmChainId: "1",
x402ChainID: "84532",
x402Ecosystem: "evm",
pricingPlanID: 1,
});
client.setEVMWalletProvider(paymentClient);
// Authenticate
await client.auth.loginEVM(wallet);
// Execute a JSON-RPC call
const result = await client.rpc.execute({
ecosystem: "evm",
chain_id: "1",
resource: "/",
method: "POST",
transport: "rpc",
payload: {
jsonrpc: "2.0",
id: 1,
method: "eth_blockNumber",
params: [],
},
});Cosmos (SIWC)
import { X402RpcClient } from "@paygate/client-x402-rpc";
import { CosmosX402Client, KeplrWalletProvider } from "@paygate/client-cosmos";
const wallet = new KeplrWalletProvider("osmosis-1");
const paymentClient = new CosmosX402Client({
walletProvider: wallet,
rpcEndpoint: "https://rpc.osmosis.zone",
chainId: "osmosis-1",
});
const client = new X402RpcClient({
appUrl: "https://myapp.example.com",
gatewayUrl: "https://gateway.example.com",
cosmosChainId: "osmosis-1",
cosmosPrefix: "osmo",
x402ChainID: "osmosis-1",
x402Ecosystem: "cosmos",
pricingPlanID: 2,
});
client.setCosmosClient(paymentClient);
// Authenticate
await client.auth.loginCosmos(wallet);
// Execute a Cosmos REST call
const result = await client.rpc.execute({
ecosystem: "cosmos",
chain_id: "osmosis-1",
resource: "/cosmos/bank/v1beta1/balances/osmo1abc...",
method: "GET",
transport: "rest",
payload: {},
});X402RpcClient
Constructor
new X402RpcClient(config: ClientConfig)ClientConfig:
| Field | Type | Required | Description |
|---|---|---|---|
appUrl | string | Yes | Your application URL (used in auth messages) |
gatewayUrl | string | Yes | x402 gateway base URL |
evmChainId | string | No | EVM chain ID for wallet auth (e.g. "1") |
cosmosChainId | string | No | Cosmos chain ID for wallet auth (e.g. "osmosis-1") |
cosmosPrefix | string | No | Bech32 prefix for Cosmos addresses (e.g. "osmo") |
x402ChainID | string | Yes | Chain used for x402 payment settlement |
x402Ecosystem | string | Yes | Payment ecosystem ("evm" or "cosmos") |
pricingPlanID | number | Yes | Pricing plan the session is bound to |
Properties
| Property | Type | Description |
|---|---|---|
auth | AuthManager | Handles wallet sign-in (SIWE/SIWC) |
rpc | RpcClient | Executes RPC calls with x402 credit enforcement |
credits | CreditsClient | Queries credit balances |
history | HistoryClient | Retrieves RPC usage history |
payments | PaymentClient | Retrieves payment transaction history |
networks | SupportedNetworksClient | Lists supported x402 payment networks |
Methods
setEVMWalletProvider(client: EthereumX402Client): void
Registers an EVM x402 client for payment handling. Must be called before executing paid RPC calls on EVM chains.
setCosmosClient(client: CosmosX402Client): void
Registers a Cosmos x402 client for payment handling. Must be called before executing paid RPC calls on Cosmos chains.
WARNING
Exactly one wallet provider must be registered. Setting both EVM and Cosmos providers is not supported and will cause an error at execution time.
AuthManager
Handles the nonce → sign → JWT exchange.
loginEVM(connector: EVMWalletConnector): Promise<{ token: string; address: string }>
Authenticates using a SIWE (Sign-In with Ethereum) flow:
- Fetches a one-time nonce from
/auth/nonce - Builds an EIP-4361 sign-in message
- Signs the message with the wallet
- Posts credentials to
/auth/login - Stores the JWT for all subsequent requests
const { token, address } = await client.auth.loginEVM(walletConnector);loginCosmos(provider: CosmosWalletProvider): Promise<{ token: string; address: string }>
Authenticates using a SIWC (Sign-In with Cosmos) flow (ADR-036):
- Fetches a one-time nonce from
/auth/nonce - Builds a Cosmos sign-in message (includes bech32 prefix)
- Signs the message with the Cosmos provider
- Posts credentials (including
pubkey) to/auth/login - Stores the JWT for all subsequent requests
const { token, address } = await client.auth.loginCosmos(walletProvider);RpcClient
Executes blockchain RPC and REST calls through the gateway with x402 credit enforcement.
execute<T>(req: RpcProxyRequest): Promise<T>
Forwards a request to the upstream provider via the gateway. Credits are deducted atomically before execution. If the balance is zero, the x402 payment flow is triggered automatically using the configured payment client.
const result = await client.rpc.execute<{ result: string }>({
ecosystem: "evm",
chain_id: "1",
resource: "/",
method: "POST",
transport: "rpc",
payload: {
jsonrpc: "2.0",
id: 1,
method: "eth_getBalance",
params: ["0xAbc...", "latest"],
},
});RpcProxyRequest:
| Field | Type | Required | Description |
|---|---|---|---|
ecosystem | string | Yes | Target blockchain ecosystem ("evm", "cosmos") |
chain_id | string | Yes | Target chain ID (e.g. "1", "osmosis-1") |
resource | string | Yes | URL path appended to the provider base URL (e.g. "/", "/cosmos/bank/v1beta1/balances/...") |
method | string | Yes | HTTP method ("POST", "GET") |
transport | "rpc" | "rest" | Yes | Transport type |
payload | any | Yes | Request body forwarded to the provider |
Behavior:
- JWT token from
loginEVM/loginCosmosis attached automatically asAuthorization: Bearer <token> - If the gateway returns
402, the client triggers payment via the registered x402 client and retries transparently - Throws on non-2xx responses
CreditsClient
get(wallet: string): Promise<any>
Returns the credit balance for a wallet across all pricing plans.
const credits = await client.credits.get("0xAbc...");
// [{ pricing_plan_id: 1, remaining_credits: 9750 }]Calls GET /credits/{wallet}.
HistoryClient
get(wallet: string, offset?: number, limit?: number): Promise<HistoryItem[]>
Returns paginated RPC usage history for a wallet.
const history = await client.history.get("0xAbc...", 0, 20);Calls GET /history/{wallet}?offset={offset}&limit={limit}.
HistoryItem:
| Field | Type | Description |
|---|---|---|
id | number | Record ID |
wallet_address | string | Wallet that made the request |
resource | string | URL resource path |
chain_id | string | Chain targeted |
network | string | Network name |
method | string | HTTP method used |
cost | number | Credits deducted |
success | boolean | Whether the request succeeded |
status_code | number | Upstream HTTP status code |
latency_ms | number | Round-trip latency in milliseconds |
ip_address | string | Client IP |
request_id | string | Unique request identifier |
created_at | string | ISO 8601 timestamp |
PaymentClient
get(wallet: string, offset?: number, limit?: number): Promise<any>
Returns paginated payment transaction history for a wallet.
const payments = await client.payments.get("0xAbc...", 0, 30);Calls GET /payments/{wallet}?offset={offset}&limit={limit}.
SupportedNetworksClient
getSupported(): Promise<any>
Returns the list of x402 payment networks and assets supported by the gateway.
const networks = await client.networks.getSupported();
// { kinds: [{ scheme: "exact", network: "base-sepolia", asset: "0xUSDC..." }] }Calls GET /x402/supported.
Token Storage
The JWT is stored in localStorage under the key x-402-gateway-token and is automatically attached to all subsequent requests via the Authorization: Bearer header. You can pre-load an existing token:
// Access the underlying HttpClient to inject an existing token
client.auth // → AuthManager, which uses HttpClient internallyError Handling
The HTTP client throws errors on non-2xx responses. Errors include:
status— HTTP status codedata— parsed response body
try {
await client.rpc.execute(req);
} catch (err: any) {
console.error(err.status, err.data);
}Types Reference
type RpcTransport = "rpc" | "rest";
interface RpcProxyRequest {
ecosystem: string;
chain_id: string;
resource: string;
method: string;
transport: RpcTransport;
payload: any;
}
interface ClientConfig {
appUrl: string;
gatewayUrl: string;
evmChainId?: string;
cosmosChainId?: string;
cosmosPrefix?: string;
x402ChainID: string;
x402Ecosystem: string;
pricingPlanID: number;
}
interface HistoryItem {
id: number;
wallet_address: string;
resource: string;
chain_id: string;
network: string;
method: string;
cost: number;
success: boolean;
status_code: number;
latency_ms: number;
ip_address: string;
request_id: string;
created_at: string;
}
interface WalletAdapter {
getAddress(): Promise<string>;
signMessage(message: string): Promise<string>;
getChainType(): "cosmos" | "evm";
}