Documentation

WidgetPay APIPlayground

Product

cherum.ioOpen appDashboard
Docs/Widget

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.

index.html
<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.

index.html
<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.

App.tsx
// 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.

FieldTypeDefaultNotes
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.
integratoraddressYour EVM wallet. Receives your fee on-chain (Model A) and identifies you for non-EVM accrual (Model B).
integratorBpsnumber20Your 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.
accentstringBrand 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 #).
brandingbooleantrueReserved: hiding the “Powered by” footer unlocks on partner tiers — the flag is accepted but not applied yet.
lockSourcebooleanfalseLocks the pre-set source chain/token (checkout-style flows).
sourceobject{ chain, token, amount? } — prefill of the pay side. Iframe query: src=arbitrum.USDC&amt=1000 (dot between chain and token).
recipientsarrayPre-set fan-out destinations, see below. Iframe query: to=base.USDC,ton.USDT.
radiusnumber18Corner radius in px, 040 — applies inside the card and works in all three forms (iframe query: radius=12).
maxWidthnumber460Frame width cap (loader/React only; for the raw iframe set your own CSS).
fullpage1Hosted 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).

config
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.

index.html
<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 integratorBps up to 300 (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.USDC to pre-select the network and token, lockSource=1 to 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 integratorBps markup is collected by the Cherum contract and routed to your integrator wallet 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 needs frame-src https://app.cherum.io (and script-src https://cdn.cherum.io if you use the loader).
  • Auto-height uses postMessage with origin checks on both sides.
  • No trackers, no external fonts — everything is served from Cherum domains.