@celorodrigues/agentkit-firewall
v1.0.2
Published
Coinbase AgentKit ActionProvider for Automaton Pre-Flight AI Firewall: simulation, anti-honeypot and MEV safe slippage guard on Base.
Maintainers
Readme
@celorodrigues/agentkit-firewall
Coinbase AgentKit ActionProvider for Automaton Pre-Flight AI Firewall on Base.
Provides autonomous on-chain transaction guards for AI agents. Simulates execution against Base chain tip, checks for reverts, scans bytecode for honeypot traps and transfer taxes, and calculates anti-MEV safe slippage bounds before sending any trade.
Install
npm install @celorodrigues/agentkit-firewall @coinbase/agentkit viem zod@^3Quickstart
import { AgentKit, ViemWalletProvider } from '@coinbase/agentkit';
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { base } from 'viem/chains';
import { automatonFirewallActionProvider } from '@celorodrigues/agentkit-firewall';
// An EOA wallet on Base that holds a little USDC (0.02 USDC per paid call). No ETH is needed.
const account = privateKeyToAccount(process.env.AGENT_PRIVATE_KEY as `0x${string}`);
const walletProvider = new ViemWalletProvider(
createWalletClient({ account, chain: base, transport: http() })
);
const agentkit = await AgentKit.from({
walletProvider,
actionProviders: [automatonFirewallActionProvider()]
});
// The action the LLM sees:
const action = agentkit.getActions().find(a => a.name.endsWith('simulate_and_guard_transaction'));
const verdict = await action!.invoke({
targetContract: '0x...', // contract the agent is about to call
calldata: '0x...' // the exact calldata it is about to send
});Use an EOA wallet provider such as ViemWalletProvider or CdpEvmWalletProvider. Smart-contract wallets (CdpSmartWalletProvider) are not tested: the endpoint's EIP-3009 verifier on X-PAYMENT-AUTH accepts only a 65-byte ECDSA signature, which a smart-wallet signature is not.
Action exposed to the LLM
simulate_and_guard_transaction(registered by AgentKit asCustomActionProvider_simulate_and_guard_transaction): simulates a transaction before execution and returns a verdict (SAFE,WARNING,REJECT), gas estimation, honeypot analysis and anti-MEV slippage limits.
Input: targetContract (required), calldata, fromAddress, valueWei, tokenAddress.
Payment flow (x402)
- The provider POSTs the arguments to
/v2/firewall/simulate-tx. - If the endpoint answers HTTP 402, the provider reads the challenge (
payment-requiredheader, or the body) and picks theaccepts[]entry withscheme: exact,network: eip155:8453, USDC on Base and the Automaton treasury aspayTo. - Before anything is signed, it refuses the payment when the amount exceeds
maxAmountUnits(default20000= 0.02 USDC), when no entry matches that network and asset, or whenpayTois not the treasury0x71DEAc098914A009E3720524642A6bE6F65EE528. - It asks the wallet for an EIP-712
TransferWithAuthorization(EIP-3009) signature and retries the same POST with the FLAT envelope{ x402Version: 2, scheme: "exact", network, payload: { from, to, value, validAfter, validBefore, nonce }, signature }, base64-encoded, inX-PAYMENT-AUTH(and the same value inX-PAYMENT).
The agent needs USDC, not ETH: settlement is broadcast by the facilitator.
The endpoint also serves a limited free-trial allowance before billing: a call taken from the trial answers HTTP 200 with the verdict and carries x-free-trial: true plus x-free-trial-remaining: <n>. Once the allowance is exhausted, the endpoint answers HTTP 402 and the provider pays and retries as above.
Options
automatonFirewallActionProvider({
maxAmountUnits: 20000, // per-call signing cap in USDC base units (6 decimals)
baseUrl: 'https://api.automaton-sovereign.workers.dev',
dryRun: false // true: return the 402 without paying
});Results that are not a verdict
{"status":"payment_refused","verdict":null,"riskScore":null,"error":"amount_above_cap" | "no_supported_requirement" | "payto_not_allowed" | "bad_amount" | "bad_cap"}: the challenge failed a guard; nothing was signed.{"status":"unavailable","verdict":null,"riskScore":null,"error":"firewall_unavailable"}: the firewall could not be reached. This is not aREJECT: no risk was measured, so none is reported.
