📘 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:
- •
Errorif API key is missing or invalid format - •
Errorif 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.
/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
}
}
/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
}
/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;
}