← Back to Plugins
Tools

SpraayBatch

Plag Tech By Plag Tech 👁 4 views ▲ 0 votes

Batch USDC payments on Base for AI agents. Pay up to 200 recipients in one atomic transaction, gasless via CDP Paymaster. Non-custodial auto-wallets and per-agent budget caps.

Homepage GitHub

Install

openclaw plugins install clawhub:spraay-batch

Configuration Example

{
  "plugins": {
    "entries": {
      "spraay-batch": {
        "enabled": true
      }
    }
  }
}

README

# SpraayBatch

**Agent-native, gasless USDC payments on Base — for [OpenClaw](https://github.com/BlockRunAI/ClawRouter).**
An autonomous agent gets its own non-custodial wallet and can pay one or many recipients in a
single atomic transaction — holding **only USDC, zero ETH** (gas is sponsored via the Coinbase
CDP Paymaster). Set per-agent budget caps so a parent agent can bound what each sub-agent spends.

```bash
npm install spraay-batch
```

<p align="center">
  <img src="docs/demo.gif" alt="SpraayBatch demo — gasless USDC batch payout from an agent" width="720">
</p>

---

## Why SpraayBatch

|                              | **SpraayBatch** | Manual sends | Multisig (e.g. Safe) | Payroll SaaS |
| ---------------------------- | :-----------: | :----------: | :------------------: | :----------: |
| **Gasless** (zero-ETH sender) |  ✅ CDP Paymaster |      ❌       |          ❌          |  ⚠️ varies   |
| **Batch** (N recipients, 1 atomic tx) |      ✅       |   ❌ one-by-one   |      ⚠️ manual       |      ✅      |
| **Budget caps** (per agent)  |      ✅       |      ❌       |    ⚠️ policy module   |   ⚠️ seat-based |
| **Non-custodial** (key stays local) |      ✅       |      ✅       |          ✅          |  ❌ custodial |
| **Agent-native** (programmatic tools) |      ✅       |      ❌       |          ❌          |      ❌      |

## How it works

- **Non-custodial wallet.** On first run SpraayBatch creates an EVM wallet at `~/.spraay/.session`
  (or reuses one). The private key never leaves your machine and is never logged.
- **Batch payout.** "Pay N recipients" becomes a single atomic transaction via the on-chain
  Spray contract — `sprayEqual` when everyone gets the same amount (cheaper), `sprayToken` for
  per-recipient amounts. The USDC approval is sized to `payout + protocol fee`, so it can't
  revert on a short allowance.
- **Gasless (opt-in).** Point SpraayBatch at a Coinbase CDP Paymaster URL and the agent can pay
  with **zero ETH**: payouts run as sponsored ERC-4337 UserOperations from a Coinbase Smart
  Account owned by your key. When gasless is on, the address you fund with USDC is the smart
  account (shown by `spraay-batch info`).
- **Budgets.** A parent agent caps each sub-agent (`agent_id → limit`); once the cap is hit,
  that agent's payouts are blocked. Caps and spend persist locally.
- **Ledger.** Every payment is appended to `~/.spraay/ledger.jsonl` with a Basescan link;
  `spraay-batch receipts` prints recent spend.

## Quick start

```bash
npm install spraay-batch                                 # installs the OpenClaw plugin
spraay-batch info                                        # show your wallet address + network
# → fund that address with USDC on Base (Base Sepolia by default)
```

Then, from your agent, call the `spraay_batch_pay` tool — or test by hand:

```bash
spraay-batch pay 10 0xRecipientA 0xRecipientB --dry-run     # preview cost + fee, no send
spraay-batch pay 10 0xRecipientA 0xRecipientB               # pay each 10 USDC in one tx
```

## Agent tools

Agents are the primary consumer. The plugin registers these tools (`contracts.tools`):

| Tool | What it does |
| --- | --- |
| `spraay_wallet_info` | Funding address, owner, network, gasless status, funding link |
| `spraay_balance` | Live USDC balance of the funding address |
| `spraay_budget_set` | Set/clear a sub-agent's spend cap (USDC) |
| `spraay_budget_status` | Cap / spent / remaining for one or all agents |
| `spraay_batch_pay` | Pay N recipients in one atomic tx (`amount` = same to all, or `amounts` = per-recipient); `dry_run`, `agent_id`, `confirm_mainnet` |
| `spraay_receipts` | Recent payments from the local ledger |

## Slash-commands (for humans testing)

`/wallet` · `/balance` · `/budget set <id> <usdc>` · `/receipts` · `/pay <amountEach> <addr…> [--agent id] [--dry-run] [--confirm]`

## CLI

```
spraay-batch [info]                      Wallet address, network, file locations
spraay-batch balance                     Live USDC balance
spraay-batch budget set <id> <usdc>      Set a per-agent spend cap
spraay-batch budget clear <id>           Remove a cap
spraay-batch budget status [id]          Show cap(s)
spraay-batch pay <amountEach> <addr...>  Pay each address the same amount [--agent id] [--dry-run] [--confirm]
spraay-batch receipts [limit]            Recent payments
spraay-batch export-key                  Print the private key for backup (keep it secret)
```

## Configuration

Config lives at `~/.spraay/spraay-batch.json`. Via OpenClaw plugin config or these env vars:

| Setting | Env var | Notes |
| --- | --- | --- |
| Wallet key | `EVM_PRIVATE_KEY` | Optional; auto-generated at `~/.spraay/.session` if unset |
| Network | (config `network`) | `base-sepolia` (default) or `base` |
| CDP Paymaster URL | `CDP_PAYMASTER_URL` | Enables gasless; `https://api.developer.coinbase.com/rpc/v1/base/<KEY>` |
| RPC overrides | `SPRAAY_BASE_RPC_URL`, `SPRAAY_BASE_SEPOLIA_RPC_URL` | Optional |

**Mainnet safety:** mainnet (`base`) payouts require explicit confirmation (`confirm_mainnet`
tool param / `--confirm` flag); Base Sepolia is the default.

## Pricing

- **0.30% protocol fee on mainnet batches** — e.g. a 1000 USDC batch = **3 USDC** fee. The fee is
  added on top of the payout (the sender approves/holds `payout + fee`), and every payment records
  it in the ledger. Use `dry_run` / `--dry-run` to see the exact fee before sending.
- **Testnet (Base Sepolia) is free** (0% fee) — develop and smoke-test at no cost.
- No SpraayBatch subscription or per-seat pricing: you pay only gas (or nothing, when gasless via
  the CDP Paymaster) plus the on-chain protocol fee on mainnet.

## On-chain contracts

| Network | Spray contract | USDC |
| --- | --- | --- |
| Base mainnet | `0x1646452F98E36A3c9Cfc3eDD8868221E207B5eEC` | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` |
| Base Sepolia | `0xfb1B884E489B0296CefadA2d8Db7CFbD1ED62f7A` | `0x036CbD53842c5426634e7929541eC2318f3dCF7e` |

## Development

```bash
npm install
npm run typecheck    # tsc --noEmit
npm run lint         # eslint
npm test             # vitest unit tests
npm run build        # tsup -> dist/
npm run smoke        # live smoke test on Base Sepolia (needs test USDC + a little ETH)
```

Run one test file: `npx vitest run test/payout.test.ts`.
Mainnet smoke: `SMOKE_NETWORK=base SMOKE_CONFIRM=1 npm run smoke` (spends real funds).

## Security

- The private key never leaves your machine and is never logged. Back it up with
  `spraay-batch export-key`.
- Payouts are signed locally — never routed through a gateway.
- Amounts, fee, recipient count, and `paused` state are validated on-chain before signing.

## License

[MIT](LICENSE)
payments batch-payments usdc base x402 gasless agent-payments defi crypto

Comments

Sign in to leave a comment

Loading comments...