Skip to content

The elizaOS x402 payment plugin

elizaOS agents get a budget-bound payment wallet with PipRail: they can pay x402-gated APIs, data feeds, and AI services on their own, across every supported chain, and they cannot spend more than the cap you set.

Unlike the OpenClaw and Hermes integrations (which wire the @piprail/mcp server over stdio), elizaOS gets a native plugin, @piprail/elizaos-plugin. It wraps the SDK’s paymentTools directly into six elizaOS actions. It has no payment logic of its own; it delegates to the published @piprail/sdk, so the agent’s own key signs against your own RPC: self-custody, no facilitator, no fee, and a spend policy the model cannot exceed.

Terminal window
npm install @piprail/elizaos-plugin

List the plugin in your character and give it a funded wallet key + caps:

{
"name": "PayBot",
"plugins": ["@piprail/elizaos-plugin"],
"settings": {
"PIPRAIL_CHAIN": "base",
"PIPRAIL_MAX_AMOUNT": "0.10", // per-payment cap
"PIPRAIL_MAX_TOTAL": "5.00", // lifetime cap
"secrets": { "PIPRAIL_PRIVATE_KEY": "0x-your-funded-key" }
}
}

In a TypeScript character you can instead import { piprailPlugin } from '@piprail/elizaos-plugin' and put the object in plugins: [piprailPlugin]. See character.example.json.

Wallet required. The plugin needs PIPRAIL_PRIVATE_KEY (a self-custodial key), and every action validates against the wallet, so set it before the agent will offer any PipRail action. (For a key-less read-only mode (discover / quote / budget / guide with no wallet) use the MCP server instead, which boots read-only.)

The plugin reads these from the character’s settings / settings.secrets (via runtime.getSetting):

SettingRequiredDefaultPurpose
PIPRAIL_PRIVATE_KEYyesnoneSelf-custodial wallet key (EVM 0x…, Solana base58, …). Put it in settings.secrets. Every action requires it. Not an API key.
PIPRAIL_CHAINnobaseWhich chain to pay on: any EVM, or solana/ton/tron/near/sui/aptos/algorand/stellar/xrpl.
PIPRAIL_MAX_AMOUNTno0.10Max per payment → policy.maxAmount
PIPRAIL_MAX_TOTALno5.00Lifetime budget → policy.maxTotal

The plugin pays with schemes: ['onchain-proof', 'exact'], so it also settles standard x402 servers (gasless for the buyer on the exact rail). Full policy surface: Payment policy.

ActionSimilesWhat it doesMoves money?
PIPRAIL_PAYPAY · BUY · PURCHASEPay a gated x402 URL and return the unlocked resourceyes
PIPRAIL_QUOTEPRICE · HOW_MUCH · COSTPrice a 402 URL without payingno
PIPRAIL_PLANCAN_I_AFFORD · AFFORDCheck affordability + the cheapest railno
PIPRAIL_DISCOVERFIND_API · SEARCH_X402Find x402-payable APIs matching a queryno
PIPRAIL_BUDGETSPENT · REMAININGWhat’s been spent / what remains under the policyno
PIPRAIL_GUIDEHOW_TO_PAY · PAYMENT_HELPExplain the payment tools + the spend policyno

Only PIPRAIL_PAY moves funds, and it’s offered only when the message contains a URL. These wrap six of the eight PipRail tools; the programmatic piprail_register + piprail_verify_receipt stay available via @piprail/sdk or @piprail/mcp.

discover → quote → plan → pay.

User: Find me a crypto price API I can pay for.
Agent: [PIPRAIL_DISCOVER] → 3 x402 resources found.
User: Can I afford the first one?
Agent: [PIPRAIL_PLAN(url)] → Payable. Best rail: eip155:8453.
User: Pay it.
Agent: [PIPRAIL_PAY(url)] → Paid (tx 0x…). <resource>

Point the plugin at the live demo (0.01 USDC on Base):

  1. Quote. PIPRAIL_QUOTE on https://piprail.com/x402/demoPrice: 0.01 USDC on eip155:8453.
  2. Pay. PIPRAIL_PAYPaid (tx 0x…). and the unlocked body.
  3. Budget holds. Set PIPRAIL_MAX_TOTAL below the price and confirm the agent is declined, no funds moved.

The runnable plugin lives at integrations/elizaos/piprail/: npm run build, npm run typecheck, npm run smoke. It’s proven on Base mainnet by driving the plugin’s own action handlers (a real on-chain settle, the budget cap enforced).