Retainer/DocsBASE SEPOLIA

What Retainer is

Recurring and usage-based USDC billing on Base, where the biller never holds the money.

Retainer is a charge engine. A customer signs one spend permission; Retainer registers it on-chain, charges against it on a schedule for whatever the period actually cost, routes each charge from the customer to the merchant's treasury in a single atomic transaction, and marks the charge paid only after the on-chain events confirm it.apps/worker/src/charger.js

The problem it solves

Card rails give merchants recurring billing by letting a processor hold funds and reverse them. Onchain, the usual substitutes are worse in one of two ways: either the merchant is handed an unbounded ERC-20 allowance and asked to be trusted with it, or a third party sits in the flow and custodies money on the way through. Base spend permissions are a different primitive — a capped, self-resetting, revocable authorisation enforced by a contract — and Retainer is the billing layer that turns that primitive into something a merchant can run a business on: schedules, retries, failure classification, and reconciliation.

What it does, and what backs each claim

The integration, in three lines

merchant/billing.ts
// 1. The customer signs once. Retainer registers it on-chain and pays the gas.
const permission = await requestSpendPermission({
  account, spender: RETAINER_ROUTER, token: USDC,
  allowance: 20_000_000n,        // 20 USDC per period — a ceiling, not a price
  periodInDays: 30,              // resets on-chain; nothing carries over
  extraData: encodeExtraData(executor, merchantTreasury),
  provider,
});

// 2. Charge whatever this period actually cost, up to the cap, when it's due.
await enqueueCharge({ permission, amount: usageThisPeriod });

// 3. "Paid" means the on-chain events say so — never that a transaction was sent.

The first call is Coinbase's Base Account SDK; the second is Retainer's queue. The signing page at /sign and the API route behind it are the real implementation of step 1. apps/web/app/api/permissions/route.js

Where it runs
Base Sepolia only, chain 84532. There is no mainnet deployment and no production claim. The limitations page lists what else is not true yet.