Documentation

The Stripe of Web3 payments.

CronPay turns recurring stablecoin billing into a single React hook. No backend, no cron jobs, no custody — the protocol streams payments on-chain while your app just reads the balance.

Non-custodialBase L2Sepolia testnet

Why CronPay

Every subscription business rebuilds the same plumbing: a billing server, a scheduler, webhooks, retries, PCI paperwork. CronPay deletes all of it. You add one hook; the smart contract does the recurring work.

No server to run
Streams execute on-chain via Base L2 + Chainlink automation. Nothing to deploy or babysit.
One line to revenue
useRainStream() is the whole integration. Ship in an afternoon, not a sprint.
Never hold funds
Money moves wallet-to-wallet. CronPay meters the flow — it never takes custody.

How it works

A payer opens a stream to your merchant address. The protocol releases funds per second according to the rate. Your dApp subscribes to the stream and receives a live balance that ticks up in real time — the same "rain" you see in the dashboard console.

payer → stream (rate/sec) → your wallet → your dApp reads balance

Install

Add the React SDK to your Next.js project.

bash
npm install @cronpay/react

Quickstart

Import the hook and point it at your merchant address. That is the entire server-side of your billing.

TypeScriptapp/pricing/page.tsx
import { useRainStream } from '@cronpay/react';
 
const { startStream } = useRainStream({
merchant: "0xFcdC...7e92",
ratePerSecond: 0.00005,
token: "USDC",
});
Streams run autonomously — no cron job on your side.
No server required
There is no CronPay backend to configure. The hook talks directly to the contract at 0xFcdC…7e92 on Sepolia. Swap the address for mainnet when you launch.

Live data & callbacks

To reproduce the dashboard's live console in your own dApp, read the reactive balance value or subscribe to per-drip events. Both update every time the protocol releases funds.

TypeScript
const { balance } = useRainStream({
merchant: "0xFcdC...7e92",
token: "USDC",
onDrip: (e) => setTotal(e.total), // fires on every drip
onError: (err) => console.error(err),
});
 
// `balance` re-renders live — drop it straight into your JSX
return <span>${balance.toFixed(6)}</span>;
onDrip fires on each release; balance re-renders automatically.

What you get back

  • balance — reactive number, re-renders on every drip.
  • onDrip(e) — callback per release; e.total, e.amount, e.from.
  • startStream() / pauseStream() — imperative controls.

useRainStream API

Configuration options for the hook.

OptionTypeDescription
merchantstringRecipient wallet or factory contract address.
token"USDC" | "USDT"Stablecoin to stream. Defaults to USDC.
ratePerSecondnumberStream rate. Optional for read-only subscriptions.
onDrip(e) => voidFires on every on-chain release. e.total is the running balance.
onError(err) => voidFires on RPC or contract error.