Airdrop a Token#

An airdrop sends a token to a list of addresses. On DecentralChain you send it with Mass Transfer transactions: one transaction pays up to 100 recipients and costs far less than 100 separate transfers.

Note

The sample is typechecked against @decentralchain/transactions@5.0.1. It has not been broadcast as part of this documentation pass.

Before You Start#

You need:

  • Node.js 24 or later, with the script saved as an ES module ("type": "module" in package.json).

  • A Testnet account that holds the token, and enough DCC for the fees. To issue a token first, see Issuing a Token; its ID is the ID of the Issue transaction.

  • The list of recipients, as addresses or aliases.

npm install @decentralchain/transactions@5.0.1

Send the Airdrop#

The script splits the recipient list into batches of 100 and sends one Mass Transfer transaction per batch:

import { massTransfer, broadcast, waitForTx, libs } from '@decentralchain/transactions';

const nodeUrl = 'https://testnet-node.decentralchain.io';
const issuerSeed = 'token holder secret seed phrase here';
const assetId = 'your token ID here'; // the ID of the token's Issue transaction; null sends DCC

const recipients = [
  '31LAqgqVTLySNCPuYqgLAYhcgS76wvBaLr9',
  '31ekkhvBGr91ygJf4st72hAEVU9BUBs3Ats',
  // ...as many addresses or aliases as you need
];
const amountEach = 1_000; // in the token's smallest unit: 10 tokens of a token with 2 decimals
const attachment = libs.crypto.base58Encode(libs.crypto.stringToBytes('Community airdrop'));

// One Mass Transfer transaction holds at most 100 transfers
for (let start = 0; start < recipients.length; start += 100) {
  const batch = recipients.slice(start, start + 100);
  const tx = massTransfer(
    {
      assetId,
      transfers: batch.map((recipient) => ({ recipient, amount: amountEach })),
      attachment,
      chainId: '!',
    },
    issuerSeed,
  );
  await broadcast(tx, nodeUrl);
  // Wait for each batch, so a failed run can restart from the first unconfirmed batch
  await waitForTx(tx.id, { apiBase: nodeUrl, timeout: 120_000 });
  console.log(`Batch from #${start}: ${batch.length} transfers, fee ${tx.fee} Decentralites, ID ${tx.id}`);
}
  • amount is in the token’s smallest unit. For a token with 2 decimals, 1_000 is 10.00 tokens. Each transfer in the list can have its own amount.

  • assetId: null airdrops DCC instead of a token.

  • attachment is optional: up to 140 bytes, base58-encoded, that every recipient sees on the transaction.

  • The fee is set by the builder: 0.001 DCC plus 0.0005 DCC per transfer, rounded up to the next 0.001 DCC. A full batch of 100 costs 0.051 DCC. For a smart asset, or a sender with an account script, add 0.004 DCC by passing fee yourself.

Check the Results#

Each batch is one transaction, so it either reaches every recipient in it or none of them. The script waits for each batch to be in a block before it sends the next, so if it stops part-way, every batch it logged is done and you can restart from the next one.

To check a recipient, read their balance of the token with node-api-js, as in Reading Blockchain Data (api.assets.fetchBalanceAddressAssetId(address, assetId)).