Skip to main content
This guide wires x402 payments into an HTTP client so your agent pays for protected resources automatically. It uses Sui’s fetch integration.
Don’t want to write code? The tpay wallet gives any agent a drop-in tpay curl and an MCP pay tool that handle all of this for you. Use the SDK when you’re building payments into your own client.

Full example on GitHub

The complete, runnable version of this guide — examples/x402/exact/client.ts.

Prerequisites

  • A Sui wallet secret key with a stablecoin balance (use testnet to try it for free)
  • Node.js 24+ (or any runtime with WebCrypto and fetch)
  • An x402-protected endpoint to call — see Quickstart for sellers

1. Install dependencies

npm install @tentaclepay/sui-x402 @mysten/sui @x402/core @x402/fetch

2. Build a signer

A ClientSuiSigner is the agent’s wallet — an address and a function that signs transaction bytes. Build one from a Sui Ed25519Keypair:
client.ts
import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
import { fromBase64 } from "@mysten/sui/utils";

import type { ClientSuiSigner } from "@tentaclepay/sui-x402";

const keypair = Ed25519Keypair.fromSecretKey(process.env.CLIENT_PRIVATE_KEY!);

const signer: ClientSuiSigner = {
  address: keypair.toSuiAddress() as `0x${string}`,
  signTransaction: async (bytes: string) => {
    const { signature } = await keypair.signTransaction(fromBase64(bytes));
    return signature;
  },
};

3. Register the Sui scheme and wrap fetch

Register ExactSuiScheme for the network you pay on, then wrap fetch so payments are handled transparently:
client.ts
import { x402Client } from "@x402/core/client";
import { wrapFetchWithPayment } from "@x402/fetch";

import { ExactSuiScheme } from "@tentaclepay/sui-x402/exact/client";

const client = new x402Client();
client.register("sui:testnet", new ExactSuiScheme(signer));

const fetchWithPayment = wrapFetchWithPayment(fetch, client);

4. Make the request

Call the protected endpoint as you normally would. When the server returns 402, the wrapped fetch signs the payment and retries automatically:
client.ts
const response = await fetchWithPayment("http://localhost:3000/weather", {
  method: "GET",
  headers: { "Content-Type": "application/json" },
});

const data = await response.json();
console.log("Response:", data);

5. Read the payment receipt

The settlement result comes back in the response headers. Use x402HTTPClient to read the transaction digest and link to an explorer:
client.ts
import { x402HTTPClient } from "@x402/core/client";

if (response.ok) {
  const httpClient = new x402HTTPClient(client);
  const paymentResponse = httpClient.getPaymentSettleResponse((name) =>
    response.headers.get(name)
  );
  console.log(
    "Transaction:",
    `https://testnet.suivision.xyz/txblock/${paymentResponse.transaction}`
  );
}
On mainnet, link to https://suivision.xyz/txblock/<digest> instead. Register "sui:mainnet" on the client to pay on mainnet.

Next steps

Supported networks

Networks and tokens you can pay with.

Pay across chains

Use the same Sui wallet to pay services on other chains.