Quickstart
Make one policy-bound x402 USDC payment on Elysium Mainnet from a machine client.
This guide creates a Robot Pay client, allows one charging service, and makes a
single idempotent request. The SDK performs the initial request, evaluates the
402 response, signs an allowed payment, and replays the request once.
1. Install the SDK
bun add @arcon-network/robot-pay @x402/core @x402/evm viemRobot Pay is also available on npm.
2. Create a payment client
import { createRobotPaymentClient } from "@arcon-network/robot-pay";
import { toClientEvmSigner } from "@x402/evm";
import { createPublicClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(
process.env.ROBOT_PRIVATE_KEY as `0x${string}`
);
const publicClient = createPublicClient({
transport: http("https://rpc.elysium.kinetiq.xyz")
});
const robot = createRobotPaymentClient({
robotId: "go2-shanghai-07",
signer: toClientEvmSigner(account, publicClient),
policy: {
allowedOrigins: ["https://dock.example"],
allowedPurposes: ["charging"],
allowedRecipients: [
"0x1111111111111111111111111111111111111111"
],
paymentRules: [
{
id: "elysium-usdc-charging",
network: "eip155:99901",
asset: "0xb47c4C8F73F009CC0C0d3f92B388d13E293F0B65",
maxAmountPerPayment: "500000",
maxAmountPerWindow: "5000000",
maxPaymentsPerWindow: 20,
windowMs: 86_400_000
}
]
}
});Amounts are integer strings in the token's atomic unit. USDC uses six decimals,
so 500000 means 0.5 USDC.
This example uses bridged USDC on Elysium Mainnet (chain ID 99901). The service
must offer x402 v2 exact payments with extra.assetTransferMethod: "permit2"
and the eip2612GasSponsoring extension. USDC's signing domain is USDC, version
1. The public client lets the SDK read allowances and nonces; the first payment
may require an additional permit signature. The facilitator pays network fees in
HYPE. The standard x402 exact Permit2 proxy is already deployed on Elysium;
see the network and service guide for its address and server setup.
Never place a robot private key in frontend code or commit it to the repository. Load it from the machine's secret store, hardware-backed signer, or edge wallet process.
3. Make a paid request
const result = await robot.fetch({
input: "https://dock.example/v1/stations/dock-01/sessions",
init: {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
robotId: "go2-shanghai-07",
missionId: "inspection-204",
requestedWh: 50
})
},
context: {
purpose: "charging",
missionId: "inspection-204",
idempotencyKey: "inspection-204-charge-1"
}
});
if (!result.response.ok) {
throw new Error(`Charging request failed: ${result.response.status}`);
}
if (result.paid) {
console.log(result.receipt);
}
const session = await result.response.json();Use a stable idempotency key for one logical purchase. Do not generate a new key when retrying after an ambiguous network failure.
4. Handle policy denials
import { RobotPaymentPolicyError } from "@arcon-network/robot-pay";
try {
await robot.fetch(request);
} catch (error) {
if (error instanceof RobotPaymentPolicyError) {
console.error(error.decision.violations);
}
throw error;
}A denial is the expected result when the service changes its recipient, asset, network, resource URL, or price beyond the configured policy. Do not silently relax policy in response to a denial.
Next steps
- Configure a paid service using the Elysium integration guide.
- Define the full Robot Pay policy.
- Add a durable ledger and approval flow using the production guide.