npm package: @smart_ex/multisender-sdk
Description: TypeScript SDK for Multisender Enterprise API - mass token distributions across EVM chains
Author: Multisender
Latest version: 1.0.0

# Multisender SDK

[![npm version](https://img.shields.io/npm/v/@multisender/sdk.svg)](https://www.npmjs.com/package/@multisender/sdk)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.5-blue.svg)](https://www.typescriptlang.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

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

```bash
npm install @multisender/sdk
```

Or with yarn:

```bash
yarn add @multisender/sdk
```

Or with Bun:

```bash
bun add @multisender/sdk
```

## Quick Start

```typescript
import { Multisender } from '@multisender/sdk';

// Initialize the SDK
const multisender = new Multisender({
  apiKey: 'your-api-key-here',
});

// Create a token distribution
const distribution = await multisender.distributions.distribute({
  chainId: 1, // Ethereum mainnet
  tokenAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
  tokenSymbol: 'USDC',
  recipients: [
    ['0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6', '100'],
    ['0x1234567890123456789012345678901234567890', '200'],
  ],
});

console.log('Distribution created:', 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

```bash
# Regenerate SDK client/types from OpenAPI
bun run generate:api

# Verify generated artifacts are committed and up to date
bun run generate:api:check
```

### Release 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.

## API Reference

### Initialize SDK

```typescript
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

```typescript
const distribution = await multisender.distributions.distribute({
  chainId: number;          // Blockchain chain ID
  tokenAddress: string;     // Token contract address
  tokenSymbol: string;      // Token symbol
  recipients?: [string, string][]; // Array of [address, amount] tuples
  csv?: string;             // Or CSV string with recipients
  account?: string;         // Optional: Sender wallet address
  idempotencyKey?: string;  // Optional: Prevent duplicates
});
```

#### List Distributions

```typescript
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

```typescript
const distribution = await multisender.distributions.get('dist_123');
```

#### Get Distribution Statistics

```typescript
const stats = await multisender.distributions.getStats('dist_123');
// Returns: totalRecipients, totalAmount, completedTransactions, etc.
```

#### Cancel Distribution

```typescript
await multisender.distributions.cancel('dist_123');
```

### Lists

#### Create Recipient List

```typescript
const list = await multisender.lists.create({
  name: 'VIP Customers',
  notes?: 'Optional notes',
});
```

#### List All Lists

```typescript
const lists = await multisender.lists.list({
  page?: number;
  limit?: number;
});
```

#### Get List

```typescript
const list = await multisender.lists.get('list_123');
```

#### Update List

```typescript
const list = await multisender.lists.update('list_123', {
  name?: 'Updated Name',
  notes?: 'Updated notes',
});
```

#### Delete List

```typescript
await multisender.lists.delete('list_123');
```

#### Add Recipients

```typescript
// 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' },
  ],
});
```

### Project

#### Get Project Info

```typescript
const project = await multisender.project.getInfo();
```

#### Manage API Keys

```typescript
// List API keys
const keys = await multisender.project.listApiKeys();

// Create API key
const key = await multisender.project.createApiKey({
  name: 'Production Key',
  scopes: ['read:lists', 'write:distributions'],
});

// Delete API key
await multisender.project.deleteApiKey('key_123');
```

### Catalogs

```typescript
// Get supported chains
const chains = await multisender.catalogs.getChains();

// Get tokens
const tokens = await multisender.catalogs.getTokens('1'); // Chain ID

// Search tokens
const results = await multisender.catalogs.searchTokens('USDC', '1');
```

## CSV Support

### Parse CSV

```typescript
import { parseCsv } from '@multisender/sdk';

const recipients = parseCsv(csvString, {
  hasHeader: true,
  delimiter: ',',
  skipRows: 0,
});
```

### Generate CSV

```typescript
import { toCsv } from '@multisender/sdk';

const csv = toCsv([
  ['0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6', '100'],
  ['0x1234567890123456789012345678901234567890', '200'],
], true); // includeHeader
```

### CSV Format

```csv
address,amount
0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8b6,100
0x1234567890123456789012345678901234567890,200
```

## CLI Usage

The SDK includes a command-line interface for quick operations.

### Install Globally

```bash
npm install -g @multisender/sdk
```

### Commands

#### Distribute Tokens

```bash
multisender distribute \
  --api-key YOUR_API_KEY \
  --chain 1 \
  --token 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
  --symbol USDC \
  --recipients recipients.csv
```

#### List Distributions

```bash
multisender distributions list --api-key YOUR_API_KEY
```

#### Get Distribution Details

```bash
multisender distributions get dist_123 --api-key YOUR_API_KEY
```

#### Manage Lists

```bash
# 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_KEY
```

#### Local development

To use the CLI against a local API (e.g. `http://localhost:3000`), pass `--base-url`:

```bash
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:3000
```

## Supported Chains

| Chain | Chain ID |
|-------|----------|
| Ethereum | 1 |
| Optimism | 10 |
| Polygon | 137 |
| Base | 8453 |
| Arbitrum | 42161 |

## Error Handling

```typescript
import { ApiError, NetworkError, ValidationError } from '@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](./examples) directory for complete examples:

- [Basic Node.js Script](./examples/node-script.ts)
- [CSV Distribution](./examples/csv-distribution.ts)
- [Managing Lists](./examples/manage-lists.ts)
- [React App](./examples/react-app.tsx)

## Development

Use Bun for package and script management.

```bash
bun install
bun run build
bun run test
bun run test:coverage
bun run typecheck
bun run lint
```

## Browser 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](./LICENSE) file for details.

## Links

- [API Documentation](https://docs.multisender.app)
- [GitHub Repository](https://github.com/multisender/sdk)
- [NPM Package](https://www.npmjs.com/package/@multisender/sdk)
- [Issue Tracker](https://github.com/multisender/sdk/issues)

## Support

For support, email support@multisender.app or open an issue on GitHub.