cherum developers
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
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.

Fees & integrator

Two models, two rails — they never blend, and your earnings never come out of Cherum's fee (or vice versa):

Same wallet everywhere. Sign in to the cabinet with the wallet you set as integrator — attribution keys on it.

Cabinet & payouts

CSP & embedding