Arcon Docs

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 viem

Robot 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

On this page