Integrate the fan-out widget
Drop cross-chain disperse into your product: your users send to many wallets, across 26 networks (EVM + TON, Solana, Bitcoin, XRP and more), in one signature — and you earn on every swap. Non-custodial, no KYB, no forms: your wallet address is the whole registration.
Quick start — iframe¶
The simplest path: copy, replace integrator with your wallet, done. The listener auto-sizes the frame as the widget grows.
<iframe id="cherum-widget"
src="https://app.cherum.io/en/embed?integrator=0xYourWalletAddress&integratorBps=20&theme=dark&accent=%238B6FE6"
style="width:100%;max-width:460px;height:600px;border:0;border-radius:18px"
allow="clipboard-write" loading="lazy"></iframe>
<script>
window.addEventListener('message', function (e) {
if (e.origin !== 'https://app.cherum.io') return;
if (e.data && e.data.type === 'cherum-embed:height') {
document.getElementById('cherum-widget').style.height = e.data.height + 'px';
}
});
</script>Try configurations live in the playground — it generates this snippet for you.
Quick start — script tag¶
One tag, auto-height included. The loader mounts the same secure iframe under the hood and wires the resize listener for you.
<script src="https://cdn.cherum.io/widget.js" async></script>
<div id="cherum-widget"></div>
<script>
window.addEventListener('load', function () {
Cherum.mount('#cherum-widget', {
integrator: '0xYourWalletAddress', // your wallet — receives your fee
integratorBps: 20, // your cut · default 20 (0.2%) · cap 500
theme: 'dark',
accent: '#8B6FE6' // any hex — your brand color
});
});
</script>Quick start — React¶
The typed component wraps the same embed. Config maps 1:1 to the script loader.
// npm install @cherum/widget-react
import { CherumWidget } from '@cherum/widget-react';
export default function Pay() {
return (
<CherumWidget
integrator="0xYourWalletAddress"
integratorBps={20}
theme="dark"
accent="#8B6FE6"
source={{ chain: 'arbitrum', token: 'USDC', amount: '1000' }}
recipients={[
{ chain: 'base', token: 'USDC' },
{ chain: 'ton', token: 'USDT' },
]}
/>
);
}Parameters¶
Same fields in all three forms (URL query for the raw iframe, config object for the loader and React). Everything is optional except integrator — required to earn.
| Field | Type | Default | Notes |
|---|---|---|---|
mode | 'payouts' | — | Switches the card from swap/fan-out to mass payouts (one token on one network to a list of address + amount rows). See Payouts widget. |
integrator | address | — | Your EVM wallet. Receives your fee on-chain (Model A) and identifies you for non-EVM accrual (Model B). |
integratorBps | number | 20 | Your EVM markup in basis points. Cap 500 (5%). Baked into your snippet — nothing stored server-side. |
theme | 'dark' | 'light' | 'dark' | Fixes the card theme regardless of the host page. |
accent | string | — | Brand accent as free HEX (#RRGGBB, #RGB or #RRGGBBAA); hover and text shades derive automatically. Invalid values are ignored. Iframe query: accent=%238B6FE6 (URL-encode the #). |
branding | boolean | true | Reserved: hiding the “Powered by” footer unlocks on partner tiers — the flag is accepted but not applied yet. |
lockSource | boolean | false | Locks the pre-set source chain/token (checkout-style flows). |
source | object | — | { chain, token, amount? } — prefill of the pay side. Iframe query: src=arbitrum.USDC&amt=1000 (dot between chain and token). |
recipients | array | — | Pre-set fan-out destinations, see below. Iframe query: to=base.USDC,ton.USDT. |
radius | number | 18 | Corner radius in px, 0–40 — applies inside the card and works in all three forms (iframe query: radius=12). |
maxWidth | number | 460 | Frame width cap (loader/React only; for the raw iframe set your own CSS). |
fullpage | 1 | — | Hosted checkout page: open the embed URL directly (no iframe needed) — the card centers on a full page. Combine with bg (page background, HEX like accent) and title (your brand line above the card, ≤64 chars). Example: /en/embed?integrator=0x…&fullpage=1&bg=%23081018&title=Acme%20Pay. |
Source & recipients¶
Pre-set destinations are chain × token pairs — the user fills addresses and split percentages inside the widget (they must confirm where their money goes; that stays in their hands).
source: { chain: 'arbitrum', token: 'USDC', amount: '1000' },
recipients: [
{ chain: 'base', token: 'USDC' },
{ chain: 'ton', token: 'USDT' },
{ chain: 'tron', token: 'USDT' },
]Gas on arrival. On supported routes every recipient lands with a little native coin, ready to transact — no separate top-up.
Payouts widget¶
The same card, switched to mass payouts: your users send one token on one network to a list of address + amount rows — typed in, or pasted as CSV straight from a spreadsheet. Large lists are split into batches automatically (up to 546 recipients per transaction on Base), with pause and resume between batches. Safe multisigs work as senders out of the box: the card detects a contract wallet, queues the batch for co-signers and picks the result up from the chain.
<iframe id="cherum-payouts"
src="https://app.cherum.io/en/embed?mode=payouts&integrator=0xYourWalletAddress&integratorBps=30&theme=dark"
style="width:100%;max-width:460px;height:520px;border:0;border-radius:18px"
allow="clipboard-write" loading="lazy"></iframe>
<script>
window.addEventListener('message', function (e) {
if (e.origin !== 'https://app.cherum.io') return;
if (e.data && e.data.type === 'cherum-embed:height') {
document.getElementById('cherum-payouts').style.height = e.data.height + 'px';
}
});
</script>Pricing is flat and public — no tiers, no calls, no forms:
- Cherum fee: 0.10% of the batch total. That’s it. A $10,000 payroll batch costs $10 — compare that to per-batch flat fees elsewhere that run into hundreds of dollars.
- Your markup: 100% yours. Set
integratorBpsup to300(3%) — the contract pays it to your wallet in the same transaction as the payout. Verify every settlement in the block explorer; you never have to trust our reports. - The payer sees both lines before signing: our fee, your fee, and the exact total to pay. No surprises after the fact.
- Use
src=base.USDCto pre-select the network and token,lockSource=1to pin them.
Recipients stay in the payer’s hands. The embed config cannot pre-fill recipient addresses — the person signing types or pastes the list themselves and confirms the totals. Your page styles the card; it never controls where the money goes.
Fees & integrator¶
Two models, two rails — they never blend, and your earnings never come out of Cherum’s fee (or vice versa):
- EVM (Model A): your
integratorBpsmarkup is collected by the Cherum contract and routed to yourintegratorwallet on-chain, in the same transaction as the swap. Settled the moment the swap settles — nothing to withdraw. - non-EVM (Model B): for swaps from TON, Solana, Bitcoin, XRP, Cardano and other non-EVM sources there is no contract to split on, so your markup accrues off-chain — set your rate in the cabinet (default 0.2%, up to 1%) and withdraw in USDC on Base.
Same wallet everywhere. Sign in to the cabinet with the wallet you set as integrator — attribution keys on it.
Cabinet & payouts¶
- Sign in at dashboard.cherum.io with your integrator wallet — signature only, no email or password.
- Dashboard: earnings by chain, swap history with transactions, your non-EVM rate setting, embed snippets with your wallet baked in.
- Payouts: request a withdrawal once your non-EVM balance reaches $50 — paid in USDC on Base to your integrator wallet.
CSP & embedding¶
- The widget runs in an isolated iframe on
app.cherum.io— no styles or scripts leak into your page, and your page cannot touch user funds. - Allow framing: nothing needed on your side — the embed sends
frame-ancestors *. Your CSP needsframe-src https://app.cherum.io(andscript-src https://cdn.cherum.ioif you use the loader). - Auto-height uses
postMessagewith origin checks on both sides. - No trackers, no external fonts — everything is served from Cherum domains.
Next
Playground
Configure the card live and copy the snippet it generates.