Arcus facilitator
A public x402 v2 facilitator for the exact scheme on Arc. It verifies EIP-3009 USDC authorizations and settles them on-chain. No account or API key needed.
https://facilitator.arcusnetwork.ioQuickstart
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.
npm i @x402/express @x402/core @x402/evmimport 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.io',
});
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);On the paying side, any x402 v2 client works. Arc USDC is not yet one of the SDK's default assets, so allowlist it in spendControls.
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');eip155:5042002 and get testnet USDC from the Circle faucet.Networks
- CAIP-2
- eip155:5042
- Chain ID
- 5042
- USDC
- 0x3600000000000000000000000000000000000000
- Decimals
- 6
- EIP-712 domain
- name "USDC", version "2"
- Explorer
- www.arcexplorer.org
- CAIP-2
- eip155:5042002
- Chain ID
- 5042002
- USDC
- 0x3600000000000000000000000000000000000000
- Decimals
- 6
- EIP-712 domain
- name "USDC", version "2"
- Explorer
- testnet.arcscan.app
List supported kinds
/supportedReturns the payment kinds Arcus accepts and the relayer address that submits settlements.
curl https://facilitator.arcusnetwork.io/supported{
"kinds": [
{ "x402Version": 2, "scheme": "exact", "network": "eip155:5042" },
{ "x402Version": 2, "scheme": "exact", "network": "eip155:5042002" }
],
"extensions": [],
"signers": { "eip155:*": ["0xRelayer"] }
}Verify a payment
/verifyChecks the signature, amount, recipient, validity window and payer balance. It does not change chain state, so call it before doing expensive work.
POST https://facilitator.arcusnetwork.io/verify
Content-Type: application/json
{
"x402Version": 2,
"paymentPayload": {
"x402Version": 2,
"accepted": { /* the requirement the client chose */ },
"payload": {
"authorization": {
"from": "0xPayer", "to": "0xMerchant",
"value": "10000",
"validAfter": "0", "validBefore": "1760000000",
"nonce": "0x…"
},
"signature": "0x…"
}
},
"paymentRequirements": {
"scheme": "exact",
"network": "eip155:5042",
"amount": "10000",
"asset": "0x3600000000000000000000000000000000000000",
"payTo": "0xMerchant",
"maxTimeoutSeconds": 60,
"extra": { "name": "USDC", "version": "2" }
}
}{ "isValid": true, "payer": "0xPayer" }Settle a payment
/settleSame body as /verify. Arcus re-verifies, simulates, then submits transferWithAuthorization and waits up to 60 s for the receipt. USDC moves directly from payer to payTo.
{
"success": true,
"payer": "0xPayer",
"transaction": "0x5b1c…e9a2",
"network": "eip155:5042"
}Errors & limits
| Reason | Meaning |
|---|---|
| malformed_request | Body failed x402 v2 schema validation. |
| unsupported_x402_version | Only x402Version 2 payloads are accepted. |
| unsupported_network | Requirements must target eip155:5042 or eip155:5042002. |
| rate_limited | 120 requests per minute per IP, per endpoint. |
| invalid_exact_evm_* | Signature, amount, recipient, time window or balance check failed. |
| unexpected_*_error | RPC or relayer problem — safe to retry. |
Network health is published at /health and on the status page.