arc-preflight
[ PREFLIGHT CHECK ]

Know if a USDC transfer will revert on Arc, before you pay gas.

Simulates Arc's blocklist and native transfer rules with one  eth_call. No backend. No API key. OFAC snapshot v2026-09-18.

from 0xf39F…2266 (test account, no balance needed)
Read-only. No wallet needed.
This session: 0 checks0 blockedgas saved 0 USDC

What runs when you press the button

Four layers, cheapest first. The first three prove a blocklist hit; the simulation is ground truth.

1
OFAC SDN snapshotOFFLINE

Embedded address list (v2026-09-18). Synchronous, no network.

2
Blocklist event cacheLOCAL

Backfills USDC Blacklisted/UnBlacklisted events via eth_getLogs.

3
USDC.isBlacklisted()VIEW CALL

One view call to the USDC predeploy for sender + recipient.

4
Native send simulationSIMULATION

eth_call with virtual balance via stateOverride. Ground truth.

Try it on-chain

Connect a wallet on Arc Testnet. Send with the guard on, then bypass it and watch the revert on the explorer.

Send with a real wallet
Testnet only. Watch the guard stop a transfer, then bypass it and watch the chain revert it.
Connect a wallet on Arc Testnet to try it. The read-only check above needs no wallet.

Pay many, skip the bad ones

One blocked payee reverts a normal batch and you lose the gas for all of them. PreflightPayout pays everyone Arc accepts and refunds the rest in the same transaction. Preflight predicts the split; the contract enforces it.

Batch payout through PreflightPayout
Contract 0xDcCa…BcDA, same address on Arc mainnet and testnet.
Reading contract…

Real USDC. The first line is your wallet once connected, so trying it costs only gas. Blocklisted payees are left out of the transaction, never sent to the contract; the contract still refuses anyone Arc blocks by the time it lands.

Preview needs no wallet. Connect one on Arc to pay.

Two lines to add it

Wrap your wallet client. Every sendTransaction is checked first.

npm i arc-preflight viem

import { withPreflight, PreflightError } from 'arc-preflight'

const wallet = withPreflight(walletClient, publicClient)

try {
  await wallet.sendTransaction({ to, value })
} catch (err) {
  if (err instanceof PreflightError) {
    // err.reasonCode: BLOCKLIST | ZERO_ADDRESS | PRECOMPILE | …
    // err.layer:      sanctions | cache | isBlacklisted | simulation
  }
}

// batch payouts: preview off-chain, settle through PreflightPayout
const plan = await planPayout(payer, [{ to, amount }, …], publicClient)
await wallet.sendTransaction(plan.tx)   // blocked payees are skipped, not reverted

# or from a shell, no code at all
npx arc-preflight 0xd882cFc20F52f2599D84b8e8D58C7FB62cfE344b