Getting started

Quickstart

Put a price on an HTTP endpoint, then pay for it from an agent. Both sides use the standard x402 v2 packages pointed at Arcus.

Sell an endpoint

Install the x402 server packages, register the exact EVM scheme for Arc and point the facilitator client at Arcus. Arc has no SDK default asset yet, so price routes with an explicit USDC amount.

  1. 1
    Install
    terminal
    sh
    npm i express @x402/express @x402/core @x402/evm
  2. 2
    Wrap a route with the payment middleware
    server.ts
    ts
    import express from 'express';
    import { paymentMiddleware } from '@x402/express';
    import { x402ResourceServer, HTTPFacilitatorClient } from '@x402/core/server';
    import { ExactEvmScheme } from '@x402/evm/exact/server';
    
    const facilitator = new HTTPFacilitatorClient({
      url: 'https://facilitator.arcusnetwork.co',
    });
    
    const server = new x402ResourceServer(facilitator)
      .register('eip155:5042', new ExactEvmScheme());
    
    const app = express();
    
    app.use(paymentMiddleware({
      'GET /weather': {
        accepts: {
          scheme: 'exact',
          network: 'eip155:5042',          // Arc mainnet
          payTo: '0xYourMerchantAddress',
          price: {
            amount: '10000',               // 0.01 USDC (6 decimals)
            asset: '0x3600000000000000000000000000000000000000',
            extra: { name: 'USDC', version: '2' },
          },
        },
        description: 'Current weather',
      },
    }, server));
    
    app.get('/weather', (_req, res) => res.json({ temp: 24 }));
    app.listen(4021);
  3. 3
    Check the 402

    An unpaid request returns 402 with the price encoded in the PAYMENT-REQUIRED header.

    terminal
    sh
    curl -i http://localhost:4021/weather
    # HTTP/1.1 402 Payment Required
    # PAYMENT-REQUIRED: eyJ4NDAyVmVyc2lvbiI6Mi...

Order of operations inside the middleware: verify the payment, run your handler, then settle. If the handler throws or returns an error, nothing is settled and the buyer keeps their USDC.

Pay for one

Any x402 v2 client works. Arc USDC is not yet one of the SDK's default assets, so allowlist it in spendControls. The wallet only signs; it needs USDC on Arc and no gas.

terminal
sh
npm i @x402/fetch @x402/evm viem
agent.ts
ts
import { privateKeyToAccount } from 'viem/accounts';
import { x402Client, wrapFetchWithPayment } from '@x402/fetch';
import { ExactEvmScheme } from '@x402/evm/exact/client';

const account = privateKeyToAccount(process.env.AGENT_KEY as `0x${string}`);
const USDC = '0x3600000000000000000000000000000000000000';

// Arc USDC isn't an SDK default asset yet — allowlist it explicitly.
const client = x402Client.fromConfig({
  schemes: [{ network: 'eip155:5042', client: new ExactEvmScheme(account) }],
  spendControls: {
    allowedAssets: [
      { network: 'eip155:5042', asset: USDC, maxAmountPerPayment: '1000000' }, // ≤ 1 USDC
    ],
  },
});

const pay = wrapFetchWithPayment(fetch, client);
const res = await pay('https://api.example.com/weather');

Prefer a smaller surface? The Arcus client package wraps this with a per-payment cap and a hard budget in one call.

Test on Arc testnet

Swap eip155:5042 for eip155:5042002 on both sides. The USDC address and EIP-712 domain are identical on both networks. Testnet USDC comes from the official Arc testnet faucet.

Settlements on testnet are real transactions on Arc testnet. Use it to watch the full verify and settle cycle before going to mainnet.

Pricing in USDC

Amounts are raw USDC units with 6 decimals: 10000 is 0.01 USDC and 1000000 is 1 USDC. The asset is the native USDC predeploy at 0x3600000000000000000000000000000000000000 and the EIP-712 domain is name USDC, version 2. Full details are on the Networks page.