SDK Overview
Detailed overview of the Mass Payout SDK architecture and available operations.
What the SDK Does
The Mass Payout SDK is a TypeScript library for interacting with the LifeCycle Cash Flow smart contract on Hedera. It provides two core functionalities:
- Contract Interaction: Create and execute transactions with the LifeCycle Cash Flow contract
- Transaction Signing: Sign transactions using custodial wallet providers (DFNS)
Transaction Signing with Custodial Wallets
The SDK uses the Hedera Custodians Library for secure transaction signing. Instead of managing private keys directly, transactions are signed remotely by DFNS.
How Transaction Signing Works
Your Application
│
▼
SDK creates unsigned transaction
│
▼
Transaction sent to DFNS API
│
▼
DFNS signs with secure private key
│
▼
Signed transaction submitted to Hedera
│
▼
Transaction receipt returned
Benefits:
- Private keys never leave the custodial provider's infrastructure
- Enterprise-grade audit trails and access controls
- Compliance with regulatory requirements
Available Operations
Commands (Write Operations)
Commands modify blockchain state and require transaction signing:
DeployCommand- Deploy new LifeCycle Cash Flow contractExecuteDistributionCommand- Execute payment distribution (paginated)ExecuteDistributionByAddressesCommand- Execute distribution for specific addressesExecuteAmountSnapshotCommand- Create fixed-amount snapshot (paginated)ExecuteAmountSnapshotByAddressesCommand- Create fixed-amount snapshot for specific addressesExecutePercentageSnapshotCommand- Create percentage-based snapshot (paginated)ExecutePercentageSnapshotByAddressesCommand- Create percentage snapshot for specific addressesExecuteBondCashOutCommand- Execute bond maturity cash-out (paginated)ExecuteBondCashOutByAddressesCommand- Execute bond cash-out for specific addressesPauseCommand- Pause contract (emergency stop)UnpauseCommand- Resume contract operations
Queries (Read Operations)
Queries read contract state without transactions:
GetPaymentTokenQuery- Get payment token addressGetPaymentTokenDecimalsQuery- Get payment token decimalsIsPausedQuery- Check if contract is paused
Usage Examples
Deploy a Contract
import { DeployCommand } from "@hashgraph/mass-payout-sdk";
const command = new DeployCommand({
tokenAddress: "0.0.789012", // Asset token address
paymentTokenAddress: "0.0.429274", // Payment token (e.g., USDC)
});
const result = await commandBus.execute(command);
console.log("Contract deployed at:", result.contractId);
Execute a Distribution
import { ExecuteDistributionCommand } from "@hashgraph/mass-payout-sdk";
const command = new ExecuteDistributionCommand({
contractId: "0.0.123456",
holderAddresses: ["0xabc...", "0xdef...", "0xghi..."],
amounts: ["100", "200", "150"], // In smallest unit (e.g., cents for USDC)
startIndex: 0,
endIndex: 100, // For pagination with large holder lists
});
const receipt = await commandBus.execute(command);
console.log("Distribution executed:", receipt.transactionId);
Create a Snapshot (Fixed Amount)
import { ExecuteAmountSnapshotCommand } from "@hashgraph/mass-payout-sdk";
const command = new ExecuteAmountSnapshotCommand({
contractId: "0.0.123456",
holderAddresses: ["0xabc...", "0xdef..."],
amounts: ["100", "100"], // Same amount for all holders
startIndex: 0,
endIndex: 50,
});
await commandBus.execute(command);
Create a Snapshot (Percentage-based)
import { ExecutePercentageSnapshotCommand } from "@hashgraph/mass-payout-sdk";
const command = new ExecutePercentageSnapshotCommand({
contractId: "0.0.123456",
holderAddresses: ["0xabc...", "0xdef..."],
balances: ["1000", "2000"], // Token balances for each holder
totalAmount: "300", // Total amount to distribute proportionally
startIndex: 0,
endIndex: 50,
});
await commandBus.execute(command);
Execute Bond Cash-Out
import { ExecuteBondCashOutCommand } from "@hashgraph/mass-payout-sdk";
const command = new ExecuteBondCashOutCommand({
contractId: "0.0.123456",
holderAddresses: ["0xabc...", "0xdef..."],
amounts: ["1000", "2000"], // Maturity amounts
startIndex: 0,
endIndex: 100,
});
await commandBus.execute(command);
Query Contract State
import { GetPaymentTokenQuery, IsPausedQuery } from "@hashgraph/mass-payout-sdk";
// Get payment token
const paymentToken = await queryBus.execute(new GetPaymentTokenQuery({ contractId: "0.0.123456" }));
// Check if paused
const isPaused = await queryBus.execute(new IsPausedQuery({ contractId: "0.0.123456" }));
Pause/Unpause Contract
import { PauseCommand, UnpauseCommand } from "@hashgraph/mass-payout-sdk";
// Emergency pause
await commandBus.execute(new PauseCommand({ contractId: "0.0.123456" }));
// Resume operations
await commandBus.execute(new UnpauseCommand({ contractId: "0.0.123456" }));
Pagination for Large Distributions
When distributing to many holders, use startIndex and endIndex to paginate:
// Distribute to first 100 holders
await commandBus.execute(
new ExecuteDistributionCommand({
contractId: "0.0.123456",
holderAddresses: allHolders,
amounts: allAmounts,
startIndex: 0,
endIndex: 100,
}),
);
// Distribute to next 100 holders
await commandBus.execute(
new ExecuteDistributionCommand({
contractId: "0.0.123456",
holderAddresses: allHolders,
amounts: allAmounts,
startIndex: 100,
endIndex: 200,
}),
);
For small lists, use the ByAddresses variants which don't require pagination.
Error Handling
import { CommandError } from "@hashgraph/mass-payout-sdk";
try {
await commandBus.execute(command);
} catch (error) {
if (error instanceof CommandError) {
console.error("Command failed:", error.message);
console.error("Details:", error.details);
}
throw error;
}
Architecture
The SDK uses a clean architecture pattern:
- Commands/Queries: High-level operations for contract interaction
- Adapters: Pluggable implementations for transaction signing (DFNS, future providers)
- Services: Network management, contract handling, events
This design allows swapping custodial providers without changing your application code.
Best Practices
- Never hardcode private keys - Always use custodial wallets in production
- Use pagination - For distributions with >100 holders, use startIndex/endIndex
- Test on testnet first - Validate all operations before mainnet deployment
- Handle errors properly - Implement retry logic for transient failures
- Monitor gas costs - Each transaction costs HBAR (~$0.0001 per transaction)
Additional Resources
- Hedera Custodians Library - Official library for custodial wallet integrations
- DFNS Documentation - DFNS provider documentation
- Hedera Documentation - Hedera network documentation
Related Guides
- SDK Integration - Quick integration guide
- Backend Integration - How the backend uses the SDK
- Smart Contracts - LifeCycle Cash Flow contract details