LLM Context
This document provides comprehensive documentation for the MNEE SDK, designed to give LLMs full context for working with the SDK.
# MNEE SDK Complete Reference
This document provides comprehensive documentation for the MNEE SDK, designed to give LLMs full context for working with the SDK.
## Table of Contents
1. [Setup and Configuration](#setup-and-configuration)
2. [Core Methods](#core-methods)
3. [Batch Operations](#batch-operations)
4. [HD Wallet](#hd-wallet)
5. [Type Definitions](#type-definitions)
6. [Webhook Support](#webhook-support)
## Setup and Configuration
### Installation and Initialization
```typescript
import Mnee from '@mnee/ts-sdk';
// Initialize MNEE SDK
const mnee = new Mnee({
environment: 'production', // or 'sandbox' (required)
apiKey: 'your-api-key' // optional but recommended
});
// All types are also exported from the main module
import {
MNEEBalance,
MNEEUtxo,
TransferResponse,
HDWallet
// ... and more
} from '@mnee/ts-sdk';
```
#### SdkConfig Type
```typescript
type SdkConfig = {
environment: 'production' | 'sandbox';
apiKey?: string;
};
```
### Configuration
The `config()` method retrieves the current MNEE service configuration including fee structure and system addresses.
```typescript
const config = await mnee.config();
```
#### Response Structure
```typescript
interface MNEEConfig {
approver: string; // Cosigner public key
feeAddress: string; // Fee collection address
burnAddress: string; // Burn operations address
mintAddress: string; // Mint operations address
fees: FeeTier[]; // Fee structure tiers
}
interface FeeTier {
min: number; // Minimum amount (atomic units)
max: number; // Maximum amount (atomic units)
fee: number; // Fee amount (atomic units)
}
```
## Core Methods
### Balance Operations
#### Single Address Balance
```typescript
const balance = await mnee.balance('address');
// Returns: { address: string, amount: number, decimalAmount: number }
```
#### Multiple Address Balances
```typescript
const balances = await mnee.balances(['address1', 'address2']);
// Returns: MNEEBalance[]
```
### UTXO Operations
```typescript
// Single address (returns up to 10 UTXOs by default)
const utxos = await mnee.getUtxos('address');
// With pagination
const utxos = await mnee.getUtxos('address', 0, 100, 'desc');
// Parameters: address, page, size (max 1000), order ('asc' | 'desc')
// Multiple addresses
const utxos = await mnee.getUtxos(['address1', 'address2'], 0, 50);
// Returns: MNEEUtxo[]
// Get just enough UTXOS for a specific amount (optimized for transfers)
const requiredAmount = mnee.toAtomicAmount(5.0); // Convert 5 MNEE to atomic units
const enoughUtxos = await mnee.getEnoughUtxos('address', requiredAmount); // Returns: MNEEUtxo[] - stops fetching once sufficient amount is reached
// Get all Utxos for an address (comprehensive wallet view)
const allUtxos = await mnee.getAllUtxos('address'); // Returns: MNEEUtxo[] - fetchtes every UTXO for the address
```
#### UTXO Structure (BSV21)
```typescript
interface MNEEUtxo {
txid: string;
vout: number;
outpoint: string; // "txid_vout"
satoshis: number;
accSats: number;
script: string;
owners: string[];
data: {
types: string[];
insc: {
json: any;
text: string;
words: string[];
file: {
hash: string;
size: number;
type: string;
};
};
map: { [key: string]: any };
b: {
hash: string;
size: number;
type: string;
};
sigmas: Array<{ algorithm: string; address: string; signature: string; index?: number }>;
list: {
payout: Array<{ address: string; value: number }>;
lock: { until: number };
};
bsv20: { [key: string]: any };
bsv21: {
id: string; // Token ID
p: string; // Protocol
op: string; // Operation
amt: number; // Amount in atomic units
sym: string; // Symbol
icon: string; // Icon URL
dec: number; // Decimals
};
};
}
```
### Transfer Operations
#### Simple Transfer
```typescript
const recipients: SendMNEE[] = [
{ address: 'recipient1', amount: 10.5 },
{ address: 'recipient2', amount: 5.25 }
];
const response = await mnee.transfer(
recipients,
'sender-private-key-wif',
{ broadcast: true, callbackUrl: 'https://your-api.com/webhook' } // optional
);
// Returns: TransferResponse
// Get transaction ID from status
const status = await mnee.getTxStatus(response.ticketId);
console.log('Transaction ID:', status.tx_id);
```
#### Multi-Source Transfer
```typescript
const options: TransferMultiOptions = {
inputs: [
{ txid: 'txid1', vout: 0, wif: 'wif1' },
{ txid: 'txid2', vout: 1, wif: 'wif2' }
],
recipients: [
{ address: 'recipient1', amount: 15.75 },
{ address: 'recipient2', amount: 8.50 }
],
changeAddress: 'change-address' // optional
};
const response = await mnee.transferMulti(options, { broadcast: true });
// Returns: TransferResponse
// Get transaction ID from status
const status = await mnee.getTxStatus(response.ticketId);
console.log('Transaction ID:', status.tx_id);
```
#### Transfer Response
```typescript
interface TransferResponse {
ticketId?: string; // Ticket ID for tracking (only if broadcast is true)
rawtx?: string; // The raw transaction hex (only if broadcast is false)
}
```
#### Transaction Status
```typescript
const status = await mnee.getTxStatus(ticketId);
// Returns: TransferStatus
interface TransferStatus {
id: string;
tx_id: string;
tx_hex: string;
action_requested: 'transfer';
status: 'BROADCASTING' | 'SUCCESS' | 'MINED' | 'FAILED';
createdAt: string;
updatedAt: string;
errors: string | null;
}
```
### Transaction Validation
```typescript
const isValid = await mnee.validateMneeTx(rawTxHex);
// Or with expected recipients
const isValid = await mnee.validateMneeTx(rawTxHex, recipients);
// Returns: boolean
```
### Submit Raw Transaction
```typescript
const response = await mnee.submitRawTx(rawTxHex, {
broadcast: true,
callbackUrl: 'https://your-api.com/webhook' // optional
});
// Returns: TransferResponse with ticketId
// Get transaction ID from status
const status = await mnee.getTxStatus(response.ticketId);
console.log('Transaction ID:', status.tx_id);
```
### Unit Conversion
```typescript
// Convert MNEE to atomic units (1 MNEE = 100,000 atomic)
const atomic = mnee.toAtomicAmount(1.5); // Returns: 150000
// Convert atomic units to MNEE
const mneeAmount = mnee.fromAtomicAmount(150000); // Returns: 1.5
```
### Transaction History
#### Single Address History
```typescript
const history = await mnee.recentTxHistory(address, fromScore, limit);
// Returns: TxHistoryResponse
```
#### Multiple Address Histories
```typescript
const params: AddressHistoryParams[] = [
{ address: 'address1', limit: 100 },
{ address: 'address2', fromScore: 850000, limit: 50 }
];
const histories = await mnee.recentTxHistories(params);
// Returns: TxHistoryResponse[]
```
#### History Response Structure
```typescript
interface TxHistoryResponse {
address: string;
history: TxHistory[];
nextScore: number;
}
interface TxHistory {
txid: string;
height: number; // 0 for unconfirmed
status: 'confirmed' | 'unconfirmed';
type: 'send' | 'receive';
amount: number; // Atomic units
counterparties: Array<{ address: string; amount: number }>;
fee: number;
score: number; // For pagination
}
```
### Transaction Parsing
#### Parse by Transaction ID
```typescript
const parsed = await mnee.parseTx(txid);
// With extended data
const parsed = await mnee.parseTx(txid, { includeRaw: true });
// Returns: ParseTxResponse | ParseTxExtendedResponse
```
#### Parse from Raw Transaction
```typescript
const parsed = await mnee.parseTxFromRawTx(rawTxHex);
// With extended data
const parsed = await mnee.parseTxFromRawTx(rawTxHex, { includeRaw: true });
```
#### Parse Response Structure
```typescript
interface ParseTxResponse {
txid: string;
environment: 'production' | 'sandbox';
type: string; // 'transfer', 'burn', etc.
inputs: Array<{ address: string; amount: number }>;
outputs: Array<{ address: string; amount: number }>;
isValid: boolean;
inputTotal: string; // String to preserve precision
outputTotal: string; // String to preserve precision
}
interface ParseTxExtendedResponse extends ParseTxResponse {
raw: {
txHex: string;
inputs: Array<{
txid: string;
vout: number;
scriptSig: string;
sequence: number;
satoshis: number;
address: string;
tokenData: any;
}>;
outputs: Array<{
value: number;
scriptPubKey: string;
address: string;
tokenData: any;
}>;
version: number;
lockTime: number;
size: number;
hash: string;
};
}
```
### Script Parsing
#### Parse Inscription
```typescript
import { Script } from '@bsv/sdk';
const script = Script.fromHex('...');
const inscription = mnee.parseInscription(script);
// Returns: Inscription | undefined
```
#### Parse Cosigner Scripts
```typescript
const scripts = [Script.fromHex('...'), Script.fromHex('...')];
const cosigners = mnee.parseCosignerScripts(scripts);
// Returns: ParsedCosigner[]
```
#### Inscription Structure
```typescript
interface Inscription {
file?: {
hash: string;
size: number;
type: string;
content: number[];
};
fields?: { [key: string]: any };
parent?: string;
}
interface ParsedCosigner {
cosigner: string; // Public key
address: string; // Bitcoin address
}
```
## Batch Operations
### Setup
```typescript
const batch = mnee.batch();
```
### Batch Configuration
```typescript
interface BatchOptions {
chunkSize?: number; // Max items per API call (default: 20)
requestsPerSecond?: number; // Rate limit (default: 3)
continueOnError?: boolean; // Continue on error (default: false)
maxRetries?: number; // Max retries per chunk (default: 3)
retryDelay?: number; // Retry delay in ms (default: 1000)
onProgress?: (completed: number, total: number, errors: number) => void;
}
```
### Batch Methods
#### Get UTXOs
```typescript
const result = await batch.getUtxos(addresses, options);
// Returns: BatchResult<BatchUtxoResult>
```
#### Get Balances
```typescript
const result = await batch.getBalances(addresses, options);
// Returns: BatchResult<MNEEBalance>
```
#### Get Transaction Histories
```typescript
const params = addresses.map(addr => ({ address: addr, limit: 100 }));
const result = await batch.getTxHistories(params, options);
// Returns: BatchResult<TxHistoryResponse>
```
#### Parse Transactions
```typescript
const result = await batch.parseTx(txids, {
parseOptions: { includeRaw: true },
...batchOptions
});
// Returns: BatchResult<BatchParseTxResult>
```
### Batch Response Structure
```typescript
interface BatchResult<T> {
results: T[];
errors: BatchError[];
totalProcessed: number;
totalErrors: number;
}
interface BatchError {
items: string[];
error: {
message: string;
code?: string;
};
retryCount: number;
}
interface BatchUtxoResult {
address: string;
utxos: MNEEUtxo[];
}
interface BatchParseTxResult {
txid: string;
parsed: ParseTxResponse | ParseTxExtendedResponse;
}
```
## HD Wallet
### Setup
```typescript
import Mnee, { HDWallet } from '@mnee/ts-sdk';
const mnee = new Mnee({
environment: 'production', // required
apiKey: 'your-api-key' // optional but recommended
});
```
### Static Methods
```typescript
// Static methods can be accessed via Mnee.HDWallet or imported HDWallet
import Mnee, { HDWallet } from '@mnee/ts-sdk';
// Generate new mnemonic (12 words)
const mnemonic = HDWallet.generateMnemonic();
// or
const mnemonic = Mnee.HDWallet.generateMnemonic();
// Validate mnemonic
const isValid = HDWallet.isValidMnemonic(mnemonic);
// or
const isValid = Mnee.HDWallet.isValidMnemonic(mnemonic);
```
### Create HD Wallet
```typescript
const hdWallet = mnee.HDWallet(mnemonic, {
derivationPath: "m/44'/236'/0'", // BIP44 path
cacheSize: 1000 // Optional cache size
});
```
### Derive Addresses
#### Single Address
```typescript
// Receive address (change = false)
const addressInfo = hdWallet.deriveAddress(0, false);
// Change address (change = true)
const changeInfo = hdWallet.deriveAddress(0, true);
// AddressInfo structure
{
address: string; // Bitcoin address
privateKey: string; // WIF format
path: string; // Full derivation path
}
```
#### Multiple Addresses
```typescript
const addresses = await hdWallet.deriveAddresses(0, 10, false);
// Returns: AddressInfo[]
```
### Get Private Keys
```typescript
// Get private keys for specific addresses
const result = hdWallet.getPrivateKeysForAddresses(addresses, {
maxScanReceive: 10000,
maxScanChange: 10000,
scanStrategy: 'parallel' // or 'sequential'
});
// Returns: { privateKeys: {}, paths: {} }
// Simplified version
const privateKeys = hdWallet.getPrivateKeys(addresses, options);
// Returns: { [address: string]: string }
```
### Scan with Gap Limit
```typescript
const checkAddressUsed = async (address) => {
const balance = await mnee.balance(address);
return balance.amount > 0;
};
const discovered = await hdWallet.scanAddressesWithGapLimit(
checkAddressUsed,
{
gapLimit: 20,
scanChange: true,
maxScan: 10000
}
);
// Returns: { receive: AddressInfo[], change: AddressInfo[] }
```
### Cache Management
```typescript
hdWallet.clearCache();
const cacheSize = hdWallet.getCacheSize();
```
## Important Notes
### Unit System
- 1 MNEE = 100,000 atomic units
- All blockchain operations use atomic units
- User-facing amounts should be in MNEE (decimal)
- SDK methods expecting amounts use MNEE values (not atomic)
### Address Validation
- Bitcoin addresses starting with 1, 3, or bc1
- Invalid addresses in batch operations are handled based on `continueOnError` setting
### Error Handling
The SDK throws standard JavaScript Error objects with descriptive messages. Common error scenarios:
#### Initialization Errors
- `"Invalid environment. Must be either 'production' or 'sandbox'"` - Invalid environment parameter
- `"MNEE API key cannot be an empty string"` - Empty API key provided
- `"Invalid API key"` - API key authentication failed
#### Validation Errors
- `"Invalid Bitcoin address: <address>"` - Address format validation failed
- `"No valid Bitcoin addresses provided"` - No valid addresses in batch
- `"Invalid transaction ID: empty or not a string"` - Invalid transaction ID format
- `"Invalid transaction ID format: <txid>"` - Transaction ID not 64 hex characters
#### Batch Operation Errors
- `"Input must be an array of addresses"` - Non-array input to batch methods
- `"Input must be an array of transaction IDs"` - Non-array input to parseTx
- `"Max retries exceeded"` - Batch operation failed after all retries
#### HD Wallet Errors
- `"Invalid mnemonic phrase"` - Invalid BIP39 mnemonic
- `"Failed to derive private key for path: <path>"` - Derivation failure
- `"Could not find private keys for <n> address(es)"` - Address not found in HD wallet scan
#### Transfer/Submit Errors (POST methods)
- `"Config not fetched"` - Failed to get cosigner configuration
- `"Insufficient MNEE balance"` - Not enough tokens for transfer
- `"Failed to broadcast transaction"` - Cosigner rejected transaction
- `"Failed to submit raw transaction"` - Submit raw tx failed
#### Error Handling Patterns
```typescript
// Basic error handling
try {
const result = await mnee.transfer(recipients, wif);
} catch (error) {
console.error('Transfer failed:', error.message);
}
// Batch operations with continueOnError
const result = await batch.getBalances(addresses, {
continueOnError: true // Continue processing on errors
});
// Check for partial failures
if (result.errors.length > 0) {
result.errors.forEach(error => {
console.log(`Failed addresses: ${error.items.join(', ')}`);
console.log(`Error: ${error.error.message}`);
});
}
// Handle API authentication errors
try {
const result = await mnee.transfer(recipients, wif);
} catch (error) {
if (error.message === 'Invalid API key') {
// Handle authentication failure (401/403)
} else if (error.message.includes('HTTP error! status:')) {
// Handle other HTTP errors
}
}
```
Note: When methods make POST requests to the cosigner API (transfer, transferMulti, submitRawTx), they handle HTTP 401/403 as "Invalid API key" and other HTTP errors as "HTTP error! status: {code}".
## Webhook Support
Transactions can be tracked via webhook callbacks for real-time status updates.
### Webhook Response Format
```typescript
interface TransferWebhookResponse {
id: string; // The ticket ID
tx_id: string; // The blockchain transaction ID
tx_hex: string; // The raw transaction hex
action_requested: 'transfer'; // Always 'transfer' for MNEE transactions
callback_url: string; // Your webhook URL (for verification)
status: 'BROADCASTING' | 'SUCCESS' | 'MINED' | 'FAILED';
createdAt: string; // ISO timestamp when ticket was created
updatedAt: string; // ISO timestamp of this update
errors: string | null; // Error details if status is FAILED
}
```
### Using Webhooks
```typescript
// Transfer with webhook
const response = await mnee.transfer(recipients, wif, {
broadcast: true,
callbackUrl: 'https://your-api.com/webhook'
});
// TransferMulti with webhook
const response = await mnee.transferMulti(options, {
broadcast: true,
callbackUrl: 'https://your-api.com/webhook'
});
// Submit raw transaction with webhook
const response = await mnee.submitRawTx(rawTxHex, {
broadcast: true,
callbackUrl: 'https://your-api.com/webhook'
});
```
### Webhook Status Flow
- **BROADCASTING** → Transaction is being broadcast to the network
- **SUCCESS** → Transaction successfully broadcast and accepted by the network
- **MINED** → Transaction has been mined into a block
- **FAILED** → Transaction failed (check `errors` field for details)
### Performance
- Batch operations automatically chunk requests
- Rate limiting prevents API throttling
- Progress callbacks report chunk completion, not individual items
- HD wallet caches derived addresses for performance
### Security
- Never store private keys or mnemonics in plain text
- Use WIF format for private keys
- HD wallet follows BIP32/BIP44 standards
- Cosigner validation available via config and script parsing
Last updated