How to Use Ace Data Cloud SDK with X402 Payments

Ace Data Cloud supports an X402 payment flow that lets the SDK pay for a request after the server responds with 402 Payment Required. Instead of providing an API token, configure a payment handler. The handler signs the server-provided payment envelope locally, and the SDK retries the original request with a PAYMENT-SIGNATURE header.
Understand the X402 request flow
The flow begins when a request such as /openai/v1/chat/completions is sent without an Authorization header. The server returns 402 Payment Required and an accepts array. The SDK calls your local payment hook with:
paymentHandler({ url, method, body, accepts })
Your handler returns headers containing PAYMENT-SIGNATURE. The SDK then resends the original request with that header. After verification and settlement, the server returns the normal 200 business response.
The payment envelope includes fields such as x402Version: 2, an accepted scheme and network, and a payload. An example accepted value uses scheme: 'upto' with network: 'eip155:8453'. The payload can contain permit2.permitted token and amount information, plus a nonce, deadline, witness, and signature.
Choose the correct payment scheme
Two schemes are available:
exactis for a fixed price.uptois for metered billing, including chat and token types.
Use preferScheme in TypeScript or prefer_scheme in Python to select among schemes offered by the server. If the server exposes only exact, the preference is ignored. If upto is requested but unavailable, selection falls back to the first matching item. Chat types must use preferScheme: 'upto' or prefer_scheme='upto'.
Set up TypeScript in a browser wallet
Install the Ace Data Cloud SDK and X402 client package:
npm install @acedatacloud/sdk @acedatacloud/x402-client
The documented tested versions are @acedatacloud/sdk@2026.504.2 and @acedatacloud/x402-client@2026.531.3. For Base in a browser, request an account, switch to chain ID 0x2105, and create the handler with the injected EIP-1193 provider.
import { AceDataCloud } from '@acedatacloud/sdk'
import { createX402PaymentHandler } from '@acedatacloud/x402-client'
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' })
const userAddress = accounts[0]
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: '0x2105' }],
})
const client = new AceDataCloud({
paymentHandler: createX402PaymentHandler({
network: 'base',
evmProvider: window.ethereum,
evmAddress: userAddress,
preferScheme: 'upto',
}),
})
const response = await client.openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [{ role: 'user', content: 'hi' }],
max_tokens: 20,
})
Do not pass apiToken in X402 mode. The TypeScript handler supports solana, base, and skale. Solana requires solanaWallet; Base and SKALE require both an EIP-1193 evmProvider and evmAddress.
On the first EVM browser call, expect two signature prompts. The first is a one-time USDC Permit2 approval using MaxUint256 that is written on-chain. The second is an EIP-712 X402 envelope signature and is not written on-chain. Later calls require only the second signature.
Use Node with viem
The TypeScript X402 client accepts EIP-1193 providers rather than raw private keys. A standard Node approach is to create a viem wallet client with privateKeyToAccount, the Base chain, and http(BASE_RPC_URL). Pass walletClient as any as evmProvider and pass account.address as evmAddress. This is stable, but using as any removes type checking.
Use Solana from TypeScript
const handler = createX402PaymentHandler({
network: 'solana',
solanaWallet: { publicKey, signTransaction },
})
Solana currently exposes only the exact scheme, so preferScheme does not apply there. Solana also does not use Permit2.
Set up Python payments
Install the Python packages:
pip install acedatacloud acedatacloud-x402
The documented tested versions are acedatacloud==2026.4.26.1 and acedatacloud-x402==2026.5.31.3. For Base, create an EVM signer from an environment-provided private key and use the metered chat scheme.
import os
from acedatacloud import AceDataCloud
from acedatacloud_x402 import create_x402_payment_handler, EVMAccountSigner
signer = EVMAccountSigner.from_private_key(os.environ['EVM_PRIVATE_KEY'])
client = AceDataCloud(
payment_handler=create_x402_payment_handler(
network='base',
evm_signer=signer,
prefer_scheme='upto',
)
)
res = client.openai.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': 'hi'}],
max_tokens=20,
)
print(res['choices'][0]['message']['content'])
You can perform the one-time EVM Permit2 approval explicitly. Solana does not need this step.
from acedatacloud_x402 import approve_permit2
tx_hash = approve_permit2(
evm_signer=signer,
rpc_url=os.environ['BASE_RPC_URL'],
)
For Solana, create a signer with SolanaKeypairSigner.from_secret_key_base58(os.environ['SOLANA_PRIVATE_KEY']), then call create_x402_payment_handler with network='solana', solana_signer=signer, and optionally rpc_url='https://api.mainnet-beta.solana.com'.
Test wiring before spending USDC
You can verify local wiring without an end-to-end on-chain payment. Constructing AceDataCloud with a payment handler and no apiToken should succeed, and createX402PaymentHandler should return a function. The handler is called only after the SDK receives a 402. A real end-to-end on-chain test consumes real USDC.
When troubleshooting, separate payment failures from normal API failures. A failed 402 handler can surface as an X402SignError, whose type varies by chain. Normal business errors, including 401, 422, and 5xx, are different failures.
For the complete SDK and X402 payment reference, see the Ace Data Cloud SDK + X402 Payment Hook documentation.
Comments
Post a Comment