@multisender.app/multisender-sdk
v0.1.1
Published
TypeScript SDK for Multisender Enterprise API - mass token distributions across EVM chains
Maintainers
Readme
Multisender SDK
TypeScript SDK for the Multisender Enterprise API - streamline mass token distributions across multiple EVM chains.
Features
- 🚀 Simple API - Intuitive methods for token distributions
- 📦 Full TypeScript Support - Complete type safety and IntelliSense
- 🔗 Multi-Chain - Support for Ethereum, Polygon, Arbitrum, Optimism, Base, and more
- 📊 CSV Support - Import recipients from CSV files
- 🛠️ CLI Tools - Command-line interface for quick operations
- ✅ Tested - Comprehensive test coverage with Bun test runner
- 🌐 Dual Builds - ESM and CommonJS support
Installation
npm install @multisender.app/multisender-sdkOr with yarn:
yarn add @multisender.app/multisender-sdkOr with Bun:
bun add @multisender.app/multisender-sdkQuick Start
import { Multisender } from '@multisender.app/multisender-sdk';
// Initialize the SDK
const multisender = new Multisender({
apiKey: 'your-api-key-here',
});
// Create a token distribution
const result = await multisender.distributions.distribute({
chainId: 1, // Ethereum mainnet
tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
tokenSymbol: 'USDC',
recipients: [
['0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6', '100'],
['0x1234567890123456789012345678901234567890', '200'],
],
});
console.log('Distribution created:', result.distribution.id);OpenAPI-First Workflow
This SDK is generated from an OpenAPI spec and committed under src/gen.
Environment placeholders
OPENAPI_SPEC_URL(required, points to the OpenAPI JSON endpoint)OPENAPI_SPEC_AUTH_HEADER(optional)OPENAPI_SPEC_AUTH_TOKEN(optional)
Commands
# Regenerate SDK client/types from OpenAPI
bun run generate:api
# Verify generated artifacts are committed and up to date
bun run generate:api:checkRelease policy
- Treat spec changes as the source of truth for SDK surface changes.
- Include spec revision/source in release notes when publishing.
- Document migration notes for any spec-driven breaking change.
Migration: OpenAPI-aligned generated operations
The generated client under src/gen now follows the OpenAPI operationId format resource_method. In the published generated entrypoint this becomes camelCase exports without a client prefix, for example projectGetProjectInfo, listsCreate, and distributionsPrepareTransactions.
This is a breaking change only for @multisender.app/multisender-sdk/generated. The high-level façade (Multisender and the *Service classes) keeps the same public method names and behavior.
Import the generated surface from @multisender.app/multisender-sdk/generated and use the new resource-based exports.
Removed generated export names:
clientApiKeysGetProjectInfoandclientApiKeysGetProjectMembersclientLists*,clientDistributions*, andclientCatalogs*- Older short names such as
create2,findAll2, andgetProjectInfo
Removed from the SDK (no longer in OpenAPI):
- Project API key CRUD (
listApiKeys,createApiKey,updateApiKey,deleteApiKey). - Token catalog methods (
getTokens,getToken,searchTokens).
Lists: Removing an entry from a list uses list item id and lists.removeListItem (path /recipients/items/{listItemId}), not recipient id on the old route.
Distributions: CreateDistributeRequest is a discriminated union of recipients or csv (exactly one); draft create uses CreateDistributionRequest (listId or recipients, not both per spec).
API Reference
Initialize SDK
const multisender = new Multisender({
apiKey: string; // Required: Your API key
baseUrl?: string; // Optional: Custom API base URL
timeout?: number; // Optional: Request timeout in ms (default: 30000)
headers?: Record<string, string>; // Optional: Additional headers
});Distributions
Create Distribution
Provide exactly one of recipients or csv (the API rejects requests with both or neither).
Recipients:
await multisender.distributions.distribute({
chainId: 1,
tokenAddress: '0x…',
tokenSymbol: 'USDC',
recipients: [
['0x…', '100'],
['0x…', '200'],
],
// account: '0x…', // optional sender wallet
// idempotencyKey: '…', // optional dedupe key
});CSV string:
await multisender.distributions.distribute({
chainId: 1,
tokenAddress: '0x…',
tokenSymbol: 'USDC',
csv: 'address,amount\n0x…,100\n',
// account: '0x…',
// idempotencyKey: '…',
});List Distributions
const distributions = await multisender.distributions.list({
page?: number; // Page number (default: 1)
limit?: number; // Items per page (default: 20)
orderBy?: string; // Field to order by
orderDir?: 'ASC' | 'DESC'; // Order direction
search?: string; // Search term
});Get Distribution
const distribution = await multisender.distributions.get('dist_123');Get Distribution Statistics
const stats = await multisender.distributions.getStats('dist_123');
// Returns: totalRecipients, totalAmount, completedTransactions, etc.Cancel Distribution
await multisender.distributions.cancel('dist_123');Lists
Create Recipient List
const list = await multisender.lists.create({
name: 'VIP Customers',
notes?: 'Optional notes',
});List All Lists
const lists = await multisender.lists.list({
page?: number;
limit?: number;
});Get List
const list = await multisender.lists.get('list_123');Update List
const list = await multisender.lists.update('list_123', {
name?: 'Updated Name',
notes?: 'Updated notes',
});Delete List
await multisender.lists.delete('list_123');Add Recipients
// Add single recipient
await multisender.lists.addRecipient('list_123', {
address: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6',
addressType: 'EVM',
label?: 'Customer A',
tags?: ['vip', 'early-adopter'],
});
// Add multiple recipients
await multisender.lists.addRecipientsBulk('list_123', {
items: [
{ address: '0x...', addressType: 'EVM', label: 'Customer A' },
{ address: '0x...', addressType: 'EVM', label: 'Customer B' },
],
});Remove list item
Removes a row from a list by list item id (the id of the list-item resource, not the recipient id on the legacy route):
const { message } = await multisender.lists.removeListItem('list_123', 'list_item_456');*Detailed() methods are removed; primary SDK methods now return the full detailed payload.
Project
Get Project Info
const project = await multisender.project.getInfo();Project members
const members = await multisender.project.getMembers();API key management (list/create/update/delete) is not part of this SDK’s OpenAPI surface anymore; manage keys in the Multisender product or your upstream API as documented there.
Catalogs
// Supported chains and chain metadata
const chains = await multisender.catalogs.getChains();
const chain = await multisender.catalogs.getChain('1');Token catalog HTTP endpoints are no longer exposed in the generated client; resolve token metadata via your own sources or the Multisender API docs if new endpoints are added to the spec.
CSV Support
Parse CSV
import { parseCsv } from '@multisender.app/multisender-sdk';
const recipients = parseCsv(csvString, {
hasHeader: true,
delimiter: ',',
skipRows: 0,
});Generate CSV
import { toCsv } from '@multisender.app/multisender-sdk';
const csv = toCsv([
['0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6', '100'],
['0x1234567890123456789012345678901234567890', '200'],
], true); // includeHeaderCSV Format
address,amount
0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6,100
0x1234567890123456789012345678901234567890,200CLI Usage
The SDK includes a command-line interface for quick operations.
Install Globally
npm install -g @multisender.app/multisender-sdkCommands
Distribute Tokens
multisender distribute \
--api-key YOUR_API_KEY \
--chain 1 \
--token 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
--symbol USDC \
--recipients recipients.csvList Distributions
multisender distributions list --api-key YOUR_API_KEYGet Distribution Details
multisender distributions get dist_123 --api-key YOUR_API_KEYManage Lists
# Create list
multisender lists create --api-key YOUR_API_KEY --name "My List"
# List all
multisender lists list --api-key YOUR_API_KEY
# Get list
multisender lists get list_123 --api-key YOUR_API_KEY
# Delete list
multisender lists delete list_123 --api-key YOUR_API_KEYLocal development
To use the CLI against a local API (e.g. http://localhost:3000), pass --base-url:
multisender lists list --api-key YOUR_API_KEY --base-url http://localhost:3000
multisender distributions list --api-key YOUR_API_KEY --base-url http://localhost:3000Supported Chains
| Chain | Chain ID | |-------|----------| | Ethereum | 1 | | Optimism | 10 | | Polygon | 137 | | Base | 8453 | | Arbitrum | 42161 |
Error Handling
import { ApiError, NetworkError, ValidationError } from '@multisender.app/multisender-sdk';
try {
await multisender.distributions.distribute({ /* ... */ });
} catch (error) {
if (error instanceof ApiError) {
console.error('API Error:', error.status, error.body);
} else if (error instanceof NetworkError) {
console.error('Network Error:', error.message);
} else if (error instanceof ValidationError) {
console.error('Validation Error:', error.message);
}
}Examples
See the examples directory for complete examples:
Development
Use Bun for package and script management.
bun install
bun run build
bun run test
bun run test:coverage
bun run typecheck
bun run lintBrowser Support
The SDK works in both Node.js (18+) and modern browsers that support native fetch.
Requirements
- Runtime: Node.js 18+ or Bun 1+ (for development and consumption)
- TypeScript 5+ (for development)
License
MIT License - see LICENSE file for details.
Links
Support
For support, email [email protected] or open an issue on GitHub.
