Stellar Multisend is a dashboard for sending one batch of payments to many recipients on Stellar testnet. It is built for fast operator workflows: connect Freighter, upload a CSV, review recipients, choose XLM or a custom asset, and submit multisend batches with live progress and post-send insights.
The app is currently optimized for Stellar testnet usage, including custom asset testing, recipient validation, CSV-based payout preparation, and batch-level transaction visibility.
The repo also includes a Soroban claim-campaign path:
- a shared multi-campaign distributor contract under
contracts/ - a claim-mode UI that can export draft or deploy-ready campaign packages
- an off-chain Merkle artifact generator for campaign manifests and proofs
Light mode |
Dark mode |
Batch Insights tracks timings, totals, fees, attempted and completed batches, plus paginated transaction hashes.
- Connects to Freighter for wallet access and signing
- Imports recipients from CSV with
address,amountformat - Supports XLM and custom Stellar assets
- Validates recipient accounts and trustlines before send
- Splits large multisends into transaction batches
- Tracks progress during signing and submission
- Shows batch insights for time, fees, totals, attempted/completed batches, and submitted transaction hashes
- Displays XLM/USD estimates for balances, totals, and fees
- Includes light and dark mode UI
yarn install
yarn devUse the built-in generator to create upload-ready recipients CSV:
yarn generate:csv --count 20 --mode fixed --amount 3 --output ./recipients.csvRandom amount example:
yarn generate:csv --count 20 --mode random --min 1 --max 8 --decimals 5 --output ./recipients.csvHelp:
yarn generate:csv --helpIn claim mode, the app can export:
*.campaign.jsondraft files for manual or scripted artifact generation*.package.jsondeploy-ready packages that already include the Merkle root, proof set, andcreate_campaignpayload
The fastest path is:
- Build the campaign in the app
- Click
Export Campaign Package - Resolve and deploy it with the helper below
The app also includes a deployment workspace in claim mode. If you fill in the shared contract id, source account, token contract, metadata URI, and network settings, it can:
- preview the resolved
create_campaignJSON payload - generate the exact
stellar contract invoke ...command - export
*.resolved.jsondirectly from the browser
After exporting a claim campaign draft JSON from the app, generate the Merkle root and proofs:
yarn generate:claim-campaign --draft ./my-campaign.campaign.jsonOptional output directory:
yarn generate:claim-campaign --draft ./my-campaign.campaign.json --out-dir ./claim-campaignsThis writes:
campaign-manifest.jsondeployment.jsonproofs.jsonproofs/<address>.json
Notes:
campaign_idfor the contract is derived assha256(campaign.campaignId)- amounts are converted into Stellar 7-decimal base units
- Merkle hashing matches the shared contract in
contracts/shared-claim-distributor
Run help:
yarn generate:claim-campaign --helpTake either the app-exported *.package.json or the generated deployment.json, fill the runtime values, and print the exact Stellar CLI invoke command:
Directly from the app package:
yarn deploy:claim-campaign \
--package ./march-payroll.package.json \
--contract-id C... \
--source-account alice \
--token C... \
--metadata-uri ipfs://march-payroll \
--days-from-now 30 \
--network testnetFrom the generator output:
yarn deploy:claim-campaign \
--deployment ./claim-campaigns/sample-campaign/deployment.json \
--contract-id C... \
--source-account alice \
--token C... \
--metadata-uri ipfs://sample-campaign \
--days-from-now 30 \
--network testnetThis writes *.resolved.json next to the input file and prints the command.
To execute immediately, add --exec:
yarn deploy:claim-campaign \
--deployment ./claim-campaigns/sample-campaign/deployment.json \
--contract-id C... \
--source-account alice \
--token C... \
--metadata-uri ipfs://sample-campaign \
--days-from-now 30 \
--network testnet \
--execIf you are not using a named Stellar CLI network, pass explicit RPC settings:
yarn deploy:claim-campaign \
--deployment ./claim-campaigns/sample-campaign/deployment.json \
--contract-id C... \
--source-account alice \
--token C... \
--metadata-uri ipfs://sample-campaign \
--days-from-now 30 \
--rpc-url https://soroban-testnet.stellar.org \
--network-passphrase "Test SDF Network ; September 2015"Generate token-ready recipients (auto-funded + trustline ready):
yarn generate:token-ready-csv --issuer-secret SA... --code TESTUSD --count 50 --mode fixed --amount 3This outputs:
recipients-token-ready.csv(upload to multisend app)recipients-token-ready.secrets.csv(test wallet secrets)
Help:
yarn generate:token-ready-csv --helpCreate a custom Stellar testnet asset (issuer + distributor) and mint supply:
yarn mint:testnet-token --code TESTUSD --amount 50000This prints:
Asset CodeAsset Issuer(use in app custom asset issuer field)DISTRIBUTOR_SECRET(import to Freighter wallet to send tokens)- tx hash + Stellar Expert link
Help:
yarn mint:testnet-token --helpMint to a specific wallet:
yarn mint:to --issuer-secret SA... --code TESTUSD --to GBIGKXLLOIS3SYVVTRLEUFQYEY52DTSPQDFUS6ACZTOTLGJHHW2BDBV4 --amount 5000Notes for mint:to:
- Destination account must exist on Stellar testnet
- Destination must already trust
TESTUSDfrom the issuer
Help:
yarn mint:to --help- Install the Freighter wallet extension before using the app.
- Use Stellar Friendbot to fund testnet wallets.
- CSV format:
address,amount
GA...,10
GB...,5.5MIT

