Skip to content

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

bash
pnpm add @paygate/client-x402-rpc

Quick Start

Ethereum (SIWE)

ts
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)

ts
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

ts
new X402RpcClient(config: ClientConfig)

ClientConfig:

FieldTypeRequiredDescription
appUrlstringYesYour application URL (used in auth messages)
gatewayUrlstringYesx402 gateway base URL
evmChainIdstringNoEVM chain ID for wallet auth (e.g. "1")
cosmosChainIdstringNoCosmos chain ID for wallet auth (e.g. "osmosis-1")
cosmosPrefixstringNoBech32 prefix for Cosmos addresses (e.g. "osmo")
x402ChainIDstringYesChain used for x402 payment settlement
x402EcosystemstringYesPayment ecosystem ("evm" or "cosmos")
pricingPlanIDnumberYesPricing plan the session is bound to

Properties

PropertyTypeDescription
authAuthManagerHandles wallet sign-in (SIWE/SIWC)
rpcRpcClientExecutes RPC calls with x402 credit enforcement
creditsCreditsClientQueries credit balances
historyHistoryClientRetrieves RPC usage history
paymentsPaymentClientRetrieves payment transaction history
networksSupportedNetworksClientLists 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:

  1. Fetches a one-time nonce from /auth/nonce
  2. Builds an EIP-4361 sign-in message
  3. Signs the message with the wallet
  4. Posts credentials to /auth/login
  5. Stores the JWT for all subsequent requests
ts
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):

  1. Fetches a one-time nonce from /auth/nonce
  2. Builds a Cosmos sign-in message (includes bech32 prefix)
  3. Signs the message with the Cosmos provider
  4. Posts credentials (including pubkey) to /auth/login
  5. Stores the JWT for all subsequent requests
ts
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.

ts
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:

FieldTypeRequiredDescription
ecosystemstringYesTarget blockchain ecosystem ("evm", "cosmos")
chain_idstringYesTarget chain ID (e.g. "1", "osmosis-1")
resourcestringYesURL path appended to the provider base URL (e.g. "/", "/cosmos/bank/v1beta1/balances/...")
methodstringYesHTTP method ("POST", "GET")
transport"rpc" | "rest"YesTransport type
payloadanyYesRequest body forwarded to the provider

Behavior:

  • JWT token from loginEVM / loginCosmos is attached automatically as Authorization: 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.

ts
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.

ts
const history = await client.history.get("0xAbc...", 0, 20);

Calls GET /history/{wallet}?offset={offset}&limit={limit}.

HistoryItem:

FieldTypeDescription
idnumberRecord ID
wallet_addressstringWallet that made the request
resourcestringURL resource path
chain_idstringChain targeted
networkstringNetwork name
methodstringHTTP method used
costnumberCredits deducted
successbooleanWhether the request succeeded
status_codenumberUpstream HTTP status code
latency_msnumberRound-trip latency in milliseconds
ip_addressstringClient IP
request_idstringUnique request identifier
created_atstringISO 8601 timestamp

PaymentClient

get(wallet: string, offset?: number, limit?: number): Promise<any>

Returns paginated payment transaction history for a wallet.

ts
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.

ts
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:

ts
// Access the underlying HttpClient to inject an existing token
client.auth // → AuthManager, which uses HttpClient internally

Error Handling

The HTTP client throws errors on non-2xx responses. Errors include:

  • status — HTTP status code
  • data — parsed response body
ts
try {
  await client.rpc.execute(req);
} catch (err: any) {
  console.error(err.status, err.data);
}

Types Reference

ts
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";
}

Built on open standards — JSON-RPC 2.0, HTTP 402, SIWx.