📘 SimpleSDK API Reference

Complete API documentation for Sead SimpleSDK Web Integration

SDK Class Reference

SeadSimpleWithAPI

The main SDK class for B2B wallet integration with API support.

class SeadSimpleWithAPI {
    constructor(config: ApiConfig)
    backup(options: BackupOptionsWithAPI): Promise<BackupResult>
    restore(options: RestoreOptionsWithAPI): Promise<RestoreResult>
}

Constructor

new SeadSimpleWithAPI(config)
Parameters:
Parameter Type Required Description
config ApiConfig Yes SDK configuration object
ApiConfig Properties:
Property Type Required Description Example
apiUrl string Yes Backend API endpoint URL "https://b2bapi.sead.world/api/v1"
apiKey string Yes API authentication key "a1b2c3d4...xyz789.abc123...xyz890"
userId string Yes Unique user identifier "user_12345" or "0x742d35Cc..."
Example:
const sead = new SeadSimpleWithAPI({
    apiUrl: 'https://b2bapi.sead.world/api/v1',
    apiKey: 'your-api-key-here',
    userId: 'wallet-user-identifier'
});
Throws:
  • • Error if API key is missing or invalid format
  • • Error if user ID is not provided

Core Functions

async backup()

Creates a secure backup of a seed phrase using Sead's wallet backup technology.

async backup(options: BackupOptionsWithAPI): Promise<BackupResult>

Parameters

Property Type Required Default Description
seedPhrase string Yes - The seed phrase to backup (12-24 words)
n number No 3 Total number of shares to create (2-10)
m number No 2 Minimum shares needed to restore (2-n)
password string No undefined Optional encryption password
allowNonBIP39 boolean No false Allow non-BIP39 compliant phrases
extraQRPaymentProof object No* undefined Payment proof for extra QR codes
*Required when n > 3
onPaymentRequired function No undefined Payment handler callback

Example Usage

const result = await sead.backup({
    seedPhrase: 'your twelve word seed phrase here for wallet backup'
});
const result = await sead.backup({
    seedPhrase: 'your twelve word seed phrase here for wallet backup',
    n: 5,                    // Create 5 shares
    m: 3,                    // Need 3 to restore
    password: 'myPassword',  // Encrypt shares
    allowNonBIP39: true,     // Allow custom phrases
    extraQRPaymentProof: {   // For extra QRs (5-3=2)
        transactionId: 'tx_123',
        proof: 'proof_signature'
    },
    onPaymentRequired: async (amount, currency) => {
        // Handle payment if quota exhausted
        return {
            transactionId: 'tx_456',
            proof: 'payment_proof'
        };
    }
});

Return Value

interface BackupResult {
    success: boolean;         // Operation success status
    shares: Share[];          // Array of generated shares
    backupId: string;         // Unique backup identifier
    encryptionUsed: boolean;  // Whether encryption was applied
    quotaRemaining?: number;  // Remaining free backups
    error?: string;           // Error message if failed
}

interface Share {
    text: string;             // Full share text
    qrCode: string;           // Base64 encoded QR image
    qrContent: string;        // Compact QR data format
    shareNumber: number;      // Share index (1-based)
    metadata?: {
        timestamp: string;
        version: string;
        checksum: string;
    };
}

async restore()

Restores a seed phrase from backup shares.

async restore(options: RestoreOptionsWithAPI): Promise<RestoreResult>

Parameters

Property Type Required Default Description
shareTexts string[] Yes* - Array of share texts
qrCodes ArrayBuffer[] Yes* - Array of QR code images
password string No undefined Decryption password if encrypted
allowNonBIP39 boolean No false Allow non-BIP39 phrase restoration
onPaymentRequired function No undefined Payment handler (rarely needed)

*Note: Either shareTexts OR qrCodes must be provided

Example Usage

const result = await sead.restore({
    shareTexts: [
        '2024081509401712|share1data...',
        '2024081509401722|share2data...'
    ],
    password: 'myPassword'  // If encrypted
});
// Read QR images as ArrayBuffers
const qrBuffers = await Promise.all(
    qrFiles.map(file => file.arrayBuffer())
);

const result = await sead.restore({
    qrCodes: qrBuffers,
    password: 'myPassword'
});

Return Value

interface RestoreResult {
    success: boolean;           // Operation success status
    seedPhrase?: string;        // Recovered seed phrase
    sharesUsed: number;         // Number of shares used
    encryptionDetected: boolean; // Whether shares were encrypted
    error?: string;             // Error message if failed
}

Configuration Options

Payment Handler

The payment handler is called when quota is exhausted:

type PaymentHandler = (
    amount: number, 
    currency: string
) => Promise<PaymentProof>;

interface PaymentProof {
    transactionId: string;      // Blockchain transaction ID
    proof: string;              // Payment signature or proof
}

Implementation Example:

async function handlePaymentRequired(amount, currency) {
    // Show payment UI to user
    const userConfirmed = await showPaymentDialog(amount, currency);
    
    if (!userConfirmed) {
        throw new Error('Payment cancelled by user');
    }
    
    // Process payment (your implementation)
    const tx = await processPayment({
        to: SEAD_PAYMENT_ADDRESS,
        amount: amount,
        currency: currency
    });
    
    // Wait for confirmation
    await tx.wait();
    
    // Return proof for SDK
    return {
        transactionId: tx.hash,
        proof: tx.signature || tx.hash
    };
}

Extra QR Payment Proof

When creating more than 3 QR codes, payment is required:

Pricing:

  • • Free QR codes: 3
  • • Cost per extra QR: 0.1 SEAD
  • • Example: 5 QRs = 2 extra × 0.1 = 0.2 SEAD
interface ExtraQRPaymentProof {
    transactionId: string;      // Payment transaction ID
    proof: string;              // Payment proof/signature
}

Response Formats

Success Responses

Backup Success:

{
    "success": true,
    "shares": [
        {
            "text": "2024081509401712|a1b2c3...",
            "qrCode": "data:image/png;base64,iVBORw0...",
            "qrContent": "2024081509401712a SEAD SGVsbG8...",
            "shareNumber": 1,
            "metadata": {
                "timestamp": "20240815094017",
                "version": "1",
                "checksum": "a1b2"
            }
        }
    ],
    "backupId": "backup_xyz123",
    "encryptionUsed": false,
    "quotaRemaining": 24997
}

Restore Success:

{
    "success": true,
    "seedPhrase": "your twelve word seed phrase here for wallet backup",
    "sharesUsed": 2,
    "encryptionDetected": false
}

Error Responses

Backup Error:

{
    "success": false,
    "shares": [],
    "backupId": "",
    "encryptionUsed": false,
    "error": "Quota exhausted. Payment required."
}

Restore Error:

{
    "success": false,
    "sharesUsed": 0,
    "encryptionDetected": false,
    "error": "Invalid shares or incorrect password"
}

Backend API Endpoints

The SDK internally calls these endpoints. Understanding them helps with debugging.

POST /api/v1/users/register

Headers:

X-API-Key: your-api-key
Content-Type: application/json

Request Body:

{
    "userId": "wallet-user-id",
    "deviceFingerprint": "browser-fingerprint"
}

Response:

{
    "success": true,
    "userId": "db-user-id",
    "quotaStatus": {
        "freeBackupsRemaining": 3,
        "operationCount": 0
    }
}
POST /api/v1/quota/check

Request Body:

{
    "userId": "wallet-user-id",
    "operationType": "backup",
    "extraQRCodes": 0
}

Response:

{
    "success": true,
    "hasQuota": true,
    "quotaRemaining": 2,
    "requiresPayment": false,
    "freeBackupsRemaining": 2
}
POST /api/v1/payment/proof

Request Body:

{
    "anonymousUserId": "wallet-user-id",
    "operationType": "backup",
    "transactionId": "tx_blockchain_hash",
    "proofMessage": "signature_or_proof",
    "walletNote": "Payment for backup operation"
}

Response:

{
    "success": true,
    "proofId": "proof_xyz789",
    "status": "PENDING",
    "message": "Payment proof submitted"
}

API Response Headers:

All API responses include these headers:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1693900800
X-Request-Id: req_abc123xyz

Error Codes & Handling

Common Error Codes

Code Message Description Solution
INVALID_API_KEY API key is invalid or missing Authentication failed Check API key format
USER_ID_REQUIRED User ID is required Missing user identifier Provide consistent user ID
QUOTA_EXHAUSTED Quota exhausted. Payment required Free tier limit reached Implement payment handler
INVALID_SHARES Invalid or insufficient shares Restore failed Check share format/count
DECRYPTION_FAILED Incorrect password Wrong encryption password Request correct password
NETWORK_ERROR Cannot connect to API Network issue Check connection/CORS
RATE_LIMITED Too many requests Rate limit exceeded Implement backoff
INVALID_SEED Invalid seed phrase Non-BIP39 phrase Set allowNonBIP39: true

Error Handling Examples

Comprehensive Error Handling:

async function safeBackup(seedPhrase, userId) {
    try {
        const sead = new SeadSimpleWithAPI({
            apiUrl: API_URL,
            apiKey: API_KEY,
            userId: userId
        });
        
        const result = await sead.backup({
            seedPhrase: seedPhrase,
            onPaymentRequired: handlePayment
        });
        
        if (result.success) {
            return result;
        } else {
            // Handle specific errors
            if (result.error.includes('Quota exhausted')) {
                showPaymentRequired();
            } else if (result.error.includes('Invalid seed')) {
                showInvalidSeedError();
            } else {
                showGenericError(result.error);
            }
        }
        
    } catch (error) {
        // Handle SDK errors
        if (error.message.includes('API key')) {
            console.error('Configuration error:', error);
            showConfigError();
        } else if (error.message.includes('Network')) {
            console.error('Network error:', error);
            showNetworkError();
        } else {
            console.error('Unexpected error:', error);
            showUnexpectedError();
        }
    }
}

Retry with Exponential Backoff:

async function backupWithRetry(options, maxRetries = 3) {
    let lastError;
    
    for (let i = 0; i < maxRetries; i++) {
        try {
            return await sead.backup(options);
        } catch (error) {
            lastError = error;
            
            // Don't retry on certain errors
            if (error.message.includes('API key') ||
                error.message.includes('Invalid seed')) {
                throw error;
            }
            
            // Exponential backoff
            const delay = Math.pow(2, i) * 1000;
            await new Promise(resolve => setTimeout(resolve, delay));
        }
    }
    
    throw lastError;
}

Type Definitions

Complete TypeScript Definitions

// Configuration Types
interface ApiConfig {
    apiUrl: string;
    apiKey: string;
    userId: string;
}

// Backup Types
interface BackupOptionsWithAPI {
    seedPhrase: string;
    n?: number;                    // Default: 3
    m?: number;                    // Default: 2
    password?: string;
    allowNonBIP39?: boolean;       // Default: false
    extraQRPaymentProof?: {
        transactionId: string;
        proof: string;
    };
    onPaymentRequired?: PaymentHandler;
}

interface BackupResult {
    success: boolean;
    shares: Share[];
    backupId: string;
    encryptionUsed: boolean;
    quotaRemaining?: number;
    error?: string;
}

interface Share {
    text: string;
    qrCode: string;
    qrContent: string;
    shareNumber: number;
    index?: number;
    content?: string;
    metadata?: ShareMetadata;
}

interface ShareMetadata {
    timestamp: string;
    version: string;
    checksum: string;
    threshold?: number;
    total?: number;
}

// Restore Types
interface RestoreOptionsWithAPI {
    shareTexts?: string[];
    qrCodes?: ArrayBuffer[];
    password?: string;
    allowNonBIP39?: boolean;       // Default: false
    onPaymentRequired?: PaymentHandler;
}

interface RestoreResult {
    success: boolean;
    seedPhrase?: string;
    sharesUsed: number;
    encryptionDetected: boolean;
    error?: string;
}

// Payment Types
type PaymentHandler = (
    amount: number,
    currency: string
) => Promise<PaymentProof>;

interface PaymentProof {
    transactionId: string;
    proof: string;
}

// Quota Types
interface QuotaStatus {
    hasQuota: boolean;
    quotaRemaining: number;
    requiresPayment: boolean;
    freeBackupsRemaining: number;
    walletQuotaRemaining?: number;
    userQuotaRemaining?: number;
}

// Error Types
interface ApiError {
    success: false;
    error: string;
    code?: string;
    details?: any;
    requestId?: string;
}

Share Format Specification

Unencrypted Share Format:

[timestamp(17)][threshold(1)][index(1)][checksum(4)] SEAD [base64-data]

Example:
2024081509401712a SEAD SGVsbG8gV29ybGQh...
  • • timestamp: 17 chars (YYYYMMDDHHMMSSms)
  • • threshold: 1 hex char (2-F)
  • • index: 1 hex char (1-F)
  • • checksum: 4 hex chars
  • • separator: " SEAD "
  • • data: Base64 encoded

Encrypted Share Format:

[timestamp(17)][threshold(1)][index(1)][checksum(4)] [encrypted-base64]

Example:
2024081509401712a U2FsdGVkX1+...
  • • Same header format
  • • No "SEAD" separator
  • • Data starts with "U2FsdGVkX" (AES signature)

Complete Integration Example

class WalletBackupService {
    constructor(apiKey, apiUrl) {
        this.apiKey = apiKey;
        this.apiUrl = apiUrl;
        this.sdk = null;
    }
    
    // Initialize SDK for user
    initForUser(userId) {
        this.sdk = new SeadSimpleWithAPI({
            apiUrl: this.apiUrl,
            apiKey: this.apiKey,
            userId: userId
        });
    }
    
    // Backup with full error handling
    async createBackup(seedPhrase, options = {}) {
        if (!this.sdk) {
            throw new Error('SDK not initialized');
        }
        
        const defaultOptions = {
            n: 3,
            m: 2,
            allowNonBIP39: false,
            onPaymentRequired: this.handlePayment.bind(this)
        };
        
        const finalOptions = {
            ...defaultOptions,
            ...options,
            seedPhrase
        };
        
        try {
            const result = await this.sdk.backup(finalOptions);
            
            if (result.success) {
                // Store backup metadata
                await this.storeBackupMetadata({
                    backupId: result.backupId,
                    timestamp: Date.now(),
                    sharesCount: result.shares.length,
                    encrypted: result.encryptionUsed
                });
                
                return result;
            }
            
            throw new Error(result.error || 'Backup failed');
            
        } catch (error) {
            // Log error for monitoring
            console.error('Backup error:', error);
            
            // Translate to user-friendly message
            const userMessage = this.translateError(error.message);
            throw new Error(userMessage);
        }
    }
    
    // Restore with validation
    async restoreWallet(shares, password) {
        if (!this.sdk) {
            // For restore, we can use temporary user ID
            this.initForUser('restore_' + Date.now());
        }
        
        // Validate shares
        if (!shares || shares.length < 2) {
            throw new Error('At least 2 shares required');
        }
        
        try {
            const result = await this.sdk.restore({
                shareTexts: shares,
                password: password,
                allowNonBIP39: true  // Allow any previously backed up phrase
            });
            
            if (result.success) {
                return result.seedPhrase;
            }
            
            throw new Error(result.error || 'Restore failed');
            
        } catch (error) {
            console.error('Restore error:', error);
            
            if (error.message.includes('password')) {
                throw new Error('Incorrect password');
            }
            
            throw new Error('Invalid shares or corrupted data');
        }
    }
    
    // Payment handler
    async handlePayment(amount, currency) {
        // Implement your payment flow
        const tx = await this.processPayment(amount, currency);
        return {
            transactionId: tx.hash,
            proof: tx.signature
        };
    }
    
    // Error translation
    translateError(error) {
        const errorMap = {
            'Quota exhausted': 'You have used all free backups. Payment required.',
            'Invalid API key': 'Service configuration error. Please contact support.',
            'Network error': 'Cannot connect to backup service. Please try again.',
            'Invalid seed': 'The provided seed phrase is invalid.',
            'Rate limited': 'Too many attempts. Please wait and try again.'
        };
        
        for (const [key, message] of Object.entries(errorMap)) {
            if (error.includes(key)) {
                return message;
            }
        }
        
        return 'An unexpected error occurred. Please try again.';
    }
}

Performance Optimization

// 1. Lazy load the SDK
let sdkInstance = null;

async function getSDK(userId) {
    if (!sdkInstance || sdkInstance.userId !== userId) {
        // Load SDK only when needed
        if (!window.SeadSimpleWithAPI) {
            await loadScript('/js/sead-simple-api-bundle.js');
        }
        
        sdkInstance = new SeadSimpleWithAPI({
            apiUrl: API_URL,
            apiKey: API_KEY,
            userId: userId
        });
    }
    
    return sdkInstance;
}

// 2. Cache API responses
const quotaCache = new Map();

async function getCachedQuota(userId) {
    const cacheKey = `quota_${userId}`;
    const cached = quotaCache.get(cacheKey);
    
    if (cached && cached.expires > Date.now()) {
        return cached.data;
    }
    
    const quota = await checkQuota(userId);
    quotaCache.set(cacheKey, {
        data: quota,
        expires: Date.now() + 60000  // 1 minute cache
    });
    
    return quota;
}