Arcon Docs

Quickstart

Make one policy-bound x402 payment 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 { privateKeyToAccount } from "viem/accounts";

const robot = createRobotPaymentClient({
  robotId: "go2-shanghai-07",
  signer: privateKeyToAccount(
    process.env.ROBOT_PRIVATE_KEY as `0x${string}`
  ),
  policy: {
    allowedOrigins: ["https://dock.example"],
    allowedPurposes: ["charging"],
    allowedRecipients: [
      "0x1111111111111111111111111111111111111111"
    ],
    paymentRules: [
      {
        id: "arc-usdc-charging",
        network: "eip155:5042002",
        asset: "0x3600000000000000000000000000000000000000",
        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.

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