Payment to 100+ New Addresses (Minimum 2 ADA Each)
This guide demonstrates how to build high-fanout payment transactions in Hydra where each new recipient gets at least 2 ADA.
Goal
- Pay to more than 100 recipient addresses.
- Enforce at least
2_000_000lovelace per output. - Submit in safe chunks to avoid transaction size limits.
Prerequisites
- Node.js environment
libcardanoandlibcardano-walletinstalled- An active Hydra Head in
Openstate - Source wallet funded for total transfer + fees
Example strategy
- Build a recipient list (100+ addresses).
- Split into chunks (example: 40 outputs per tx).
- Submit each chunk sequentially.
import { KuberHydraApiProvider } from "kuber-client";
import { CardanoKeyAsync } from "libcardano";
import { ShelleyWallet, SimpleCip30Wallet } from "libcardano-wallet";
import { readFileSync } from "fs";
const MIN_PER_OUTPUT = 2_000_000;
const CHUNK_SIZE = 40;
function chunk<T>(items: T[], size: number): T[][] {
const chunks: T[][] = [];
for (let i = 0; i < items.length; i += size) {
chunks.push(items.slice(i, i + size));
}
return chunks;
}
async function runBulkPaymentExample() {
const hydra = new KuberHydraApiProvider("http://localhost:8082");
const signingKey = await CardanoKeyAsync.fromCardanoCliJson(
JSON.parse(
readFileSync(
process.env.HOME + "/.cardano/preview/hydra-0/credentials/funds.sk",
"utf-8",
),
),
);
const shelleyWallet = new ShelleyWallet(signingKey);
const wallet = new SimpleCip30Wallet(hydra, hydra, shelleyWallet, 0);
const changeAddress = (await wallet.getChangeAddress()).toBech32();
const headState = await hydra.queryHeadState();
if (headState.state !== "Open") {
throw new Error(`Hydra head is ${headState.state}. Expected Open.`);
}
// Replace with real generated/imported recipient addresses.
const recipients = Array.from({ length: 105 }).map(
(_, i) => `addr_test1...recipient_${i}`,
);
const batches = chunk(recipients, CHUNK_SIZE);
for (let batchIndex = 0; batchIndex < batches.length; batchIndex += 1) {
const outputs = batches[batchIndex].map((address) => ({
address,
value: String(MIN_PER_OUTPUT),
}));
const txBuilder = {
outputs,
changeAddress,
};
const txHash = await hydra.buildAndSubmitWithWallet(wallet, txBuilder);
console.log(`Batch ${batchIndex + 1}/${batches.length} submitted:`, txHash);
}
}
runBulkPaymentExample().catch((err) => {
console.error("Bulk payment flow failed:", err);
});
Validation checklist
- All intended recipient addresses were included.
- Every output value is at least 2 ADA.
- All chunks were accepted by the Hydra head.
- Source wallet balance decreased by expected total.
