SDK

A TypeScript SDK for secure multi-party computation (MPC) and blockchain operations using the Vultisig protocol. Build secure, decentralized applications with threshold signature schemes and multi-chain support.

Features

  • 🔐 Multi-Party Computation (MPC) - Secure threshold signatures using DKLS and Schnorr protocols

  • 🏦 Fast Vault - Server-assisted 2-of-2 vault for quick setup and instant signing

  • 🛡️ Secure Vault - Multi-device N-of-M threshold signing with mobile device pairing

  • 📲 QR Code Pairing - Pair with Vultisig mobile apps (iOS/Android) for vault creation and signing

  • 🌐 Multi-Chain Support - Bitcoin, Ethereum, Solana, THORChain, and 40+ blockchains

  • 🔗 Address Derivation - Generate addresses across multiple blockchain networks

  • 📱 Cross-Platform - Works in browsers, Node.js, and Electron (React Native coming soon)

  • 🔒 Vault Management - Import, export, encrypt, and decrypt vault keyshares

  • 🔑 Seedphrase Import - Import existing BIP39 mnemonics with automatic chain discovery

  • 💰 VULT Discount Tiers - Automatic swap fee discounts based on VULT token holdings

  • 📋 Token Registry - Built-in known token database, fee coin lookup, and on-chain token discovery

  • 🛡️ Security Scanning - Transaction validation/simulation via Blockaid, site phishing detection

  • 💵 Price Feeds - Fetch token prices via CoinGecko

  • 🏪 Fiat On-Ramp - Generate Banxa buy URLs for 23+ supported chains

  • 🔔 Push Notifications - Real-time signing coordination via WebSocket or platform push (APNs, FCM, Web Push)

  • 🌍 WASM Integration - High-performance cryptographic operations via WebAssembly

Installation

Quick Start

1. Initialize the SDK

WARNING — Vault Persistence: Do not use MemoryStorage in production. It is non-persistent — all vault keyshares are lost when the process exits, resulting in permanent loss of funds. The SDK auto-configures persistent storage for your platform. Always back up vaults with vault.export().

2. Create a Fast Vault (Server-Assisted)

3. Derive Blockchain Addresses

4. Create a Secure Vault (Multi-Device)

5. Sign with Secure Vault

6. Import/Export Vaults

7. Create Vault from Seedphrase

Import an existing wallet from a BIP39 mnemonic. Supports all 10 BIP39 languages with automatic detection:

8. Token Registry & Prices

9. Security Scanning

10. Fiat On-Ramp (Banxa)

11. Push Notifications

Coordinate multi-party signing by notifying vault members when a signing session is initiated.

Consumer Responsibilities

The SDK handles server communication and state management. Your application is responsible for platform-specific push integration:

Responsibility
Owner
Details

Obtain push token

You

Use platform APIs (APNs, FCM, Web Push) to get a device token

Register token with server

SDK

sdk.notifications.registerDevice()

Send notification to vault members

SDK

sdk.notifications.notifyVaultMembers()

Wire platform push handler

You

iOS delegate, FCM onMessage, service worker, etc.

Parse incoming notification

SDK

sdk.notifications.handleIncomingPush(data)

Display notification to user

You

OS notification, in-app alert, etc.

Route user to signing flow

You

Use qrCodeData from the parsed notification

Persist registration state

SDK

Stored automatically in SDK storage

Platform Setup

iOS — Register for remote notifications, pass APNs device token:

Android — Use Firebase Cloud Messaging:

Browser / Extension — Use WebSocket for real-time delivery (no service worker needed):

Alternatively, use Web Push API with VAPID key:

Node.js / CLI — Use WebSocket delivery (connect()) or parseNotificationPayload() manually if you implement your own transport.

Supported Blockchains

The SDK supports address derivation and operations for 40+ blockchain networks:

Network
Chain ID
Description

Bitcoin

bitcoin

Bitcoin mainnet

Ethereum

ethereum

Ethereum mainnet

Solana

solana

Solana mainnet

THORChain

thorchain

THORChain mainnet

Polygon

polygon

Polygon (MATIC)

Avalanche

avalanche

Avalanche C-Chain

BSC

bsc

Binance Smart Chain

Arbitrum

arbitrum

Arbitrum One

Optimism

optimism

Optimism mainnet

Cosmos

cosmos

Cosmos Hub

Litecoin

litecoin

Litecoin mainnet

Dogecoin

dogecoin

Dogecoin mainnet

...

...

And many more

Vault Types

The SDK supports two vault types for different security and usability requirements:

Feature
Fast Vault
Secure Vault

Threshold

2-of-2

N-of-M (configurable)

Setup

Server-assisted, instant

Multi-device, requires pairing

Signing

Instant via VultiServer

Requires device coordination

Use Cases

Personal wallets, quick setup

Team wallets, high security, custody

Device Pairing

None required

QR code with Vultisig mobile app

Password

Required

Optional

When to Use Each Type

Fast Vault - Best for:

  • Individual users wanting quick setup

  • Development and testing

  • Situations where server-assisted signing is acceptable

Secure Vault - Best for:

  • Team or organizational wallets

  • High-value assets requiring multi-party approval

  • Scenarios requiring configurable thresholds (2-of-3, 3-of-5, etc.)

  • Maximum security without server dependency during signing

Framework Integration Example

The SDK works with any JavaScript framework. Here's a React example:

React Component Example

Configuration

SDK Configuration

WASM Files

The SDK requires three WASM files to be available in your application's public directory:

  • wallet-core.wasm - Trust Wallet Core for address derivation

  • dkls.wasm - ECDSA threshold signatures (DKLS protocol)

  • schnorr.wasm - EdDSA threshold signatures (Schnorr protocol)

For bundled applications (Vite, webpack, etc.), place these files in the public/ directory.

API Reference

Core Methods

initialize(): Promise<void>

Initialize the SDK and load all WASM modules.

createFastVault(options): Promise<string>

Create a new vault using VultiServer assistance. Returns the vaultId.

Parameters:

  • options.name: string - Vault name

  • options.email: string - Email for verification

  • options.password: string - Vault encryption password

verifyVault(vaultId, code): Promise<FastVault>

Verify vault creation with email verification code. Returns the verified vault.

createSecureVault(options): Promise<{ vault, vaultId, sessionId }>

Create a multi-device secure vault with N-of-M threshold signing.

Parameters:

  • options.name: string - Vault name

  • options.devices: number - Number of devices participating (minimum 2)

  • options.threshold?: number - Signing threshold (defaults to ceil((devices+1)/2))

  • options.password?: string - Optional vault encryption password

  • options.onQRCodeReady?: (qrPayload: string) => void - Called when QR code is ready for device pairing

  • options.onDeviceJoined?: (deviceId: string, total: number, required: number) => void - Called when a device joins

  • options.onProgress?: (step: VaultCreationStep) => void - Called with creation progress updates

Returns:

  • vault: SecureVault - The created vault instance

  • vaultId: string - Unique vault identifier

  • sessionId: string - Session ID used for creation

validateSeedphrase(mnemonic): Promise<SeedphraseValidation>

Validate a BIP39 mnemonic phrase.

Returns:

  • valid: boolean - Whether the mnemonic is valid

  • wordCount: number - Number of words (12 or 24)

  • invalidWords?: string[] - Words not in BIP39 wordlist

  • error?: string - Error message if invalid

discoverChainsFromSeedphrase(mnemonic, chains?, onProgress?): Promise<ChainDiscoveryResult[]>

Discover chains with balances for a seedphrase.

Parameters:

  • mnemonic: string - BIP39 mnemonic phrase

  • chains?: Chain[] - Chains to scan (defaults to common chains)

  • onProgress?: (progress: ChainDiscoveryProgress) => void - Progress callback

createFastVaultFromSeedphrase(options): Promise<string>

Create a FastVault from a BIP39 seedphrase. Returns vaultId for email verification.

Parameters:

  • options.mnemonic: string - BIP39 mnemonic (12 or 24 words)

  • options.name: string - Vault name

  • options.email: string - Email for verification

  • options.password: string - Vault encryption password

  • options.discoverChains?: boolean - Auto-enable chains with balances

  • options.onProgress?: (step: VaultCreationStep) => void - Progress callback

  • options.onChainDiscovery?: (progress: ChainDiscoveryProgress) => void - Discovery callback

createSecureVaultFromSeedphrase(options): Promise<{ vault, vaultId, sessionId }>

Create a SecureVault from a BIP39 seedphrase with multi-device MPC.

Parameters:

  • options.mnemonic: string - BIP39 mnemonic (12 or 24 words)

  • options.name: string - Vault name

  • options.devices: number - Number of participating devices

  • options.threshold?: number - Signing threshold

  • options.password?: string - Optional encryption password

  • options.onQRCodeReady?: (qrPayload: string) => void - QR callback

  • options.onDeviceJoined?: (deviceId, total, required) => void - Device join callback

joinSecureVault(qrPayload, options): Promise<{ vault, vaultId }>

Join an existing SecureVault creation session. Auto-detects keygen vs seedphrase mode.

Parameters:

  • qrPayload: string - QR code content from initiator (vultisig://...)

  • options.mnemonic?: string - Required for seedphrase-based sessions, ignored for keygen

  • options.devices: number - Number of participating devices (required)

  • options.password?: string - Optional encryption password

  • options.onProgress?: (step: VaultCreationStep) => void - Progress callback

  • options.onDeviceJoined?: (deviceId, total, required) => void - Device join callback

vault.address(chain): Promise<string>

Derive a blockchain address for the given chain (called on Vault instance).

addVault(file, password?): Promise<Vault>

Import a vault from a backup file.

vault.export(password?): Promise<Blob>

Export a vault to encrypted backup format as a Blob (called on Vault instance).

vault.exportAsBase64(password?): Promise<string>

Export a vault to encrypted backup format as a base64 string (called on Vault instance).

secureVault.sign(payload, options?): Promise<SigningResult>

Sign a transaction with a SecureVault (requires device coordination).

Parameters:

  • payload: SigningPayload - Transaction data to sign

  • options.signal?: AbortSignal - Optional signal to cancel the signing operation

  • options.onQRCodeReady?: (qrPayload: string) => void - Called when QR code is ready for device pairing

  • options.onDeviceJoined?: (deviceId: string, total: number, required: number) => void - Called when a device joins

  • options.onProgress?: (step: SigningStep) => void - Called with signing progress updates

secureVault.signBytes(options, signingOptions?): Promise<SigningResult>

Sign arbitrary bytes with a SecureVault.

Parameters:

  • options.chain: string - Chain for signature algorithm selection

  • options.messages: (Uint8Array | Buffer | string)[] - Messages to sign (hex strings or bytes)

  • signingOptions.signal?: AbortSignal - Optional signal to cancel the operation

Static Methods (No Vault Needed)

Vultisig.getKnownTokens(chain): TokenInfo[]

Get all known tokens for a chain from the built-in registry.

Vultisig.getKnownToken(chain, contractAddress): TokenInfo | null

Look up a specific token by contract address (case-insensitive). Returns null if not found.

Vultisig.getFeeCoin(chain): FeeCoinInfo

Get the native fee coin info for a chain (e.g., ETH for Ethereum, BTC for Bitcoin).

Vultisig.getCoinPrices(params): Promise<Record<string, number>>

Fetch current token prices by CoinGecko IDs.

Parameters:

  • params.ids: string[] - CoinGecko price provider IDs

  • params.fiatCurrency?: string - Fiat currency code (default: 'usd')

Vultisig.getBanxaSupportedChains(): Chain[]

Get the list of chains supported by the Banxa fiat on-ramp.

Vultisig.scanSite(url): Promise<SiteScanResult>

Scan a website URL for malicious content via Blockaid.

Returns:

  • isMalicious: boolean - Whether the site is flagged as malicious

  • url: string - The scanned URL

Vault Methods (Token Discovery & Security)

vault.discoverTokens(chain): Promise<DiscoveredToken[]>

Discover tokens with non-zero balances at this vault's address. Supported: EVM (via 1inch), Solana (via Jupiter), Cosmos (via RPC).

vault.resolveToken(chain, contractAddress): Promise<TokenInfo>

Resolve token metadata by contract address. Checks known tokens registry first, then resolves from chain APIs.

vault.getBuyUrl(chain, ticker?): Promise<string | null>

Generate a Banxa fiat on-ramp URL for buying crypto to this vault's address. Returns null if chain is not supported by Banxa.

vault.validateTransaction(keysignPayload): Promise<TransactionValidationResult | null>

Validate a transaction for security risks before signing using Blockaid. Supported: EVM chains, Solana, Sui, Bitcoin. Returns null for unsupported chains.

vault.simulateTransaction(keysignPayload): Promise<TransactionSimulationResult | null>

Simulate a transaction to preview asset changes before signing. Supported: EVM chains, Solana. Returns null for unsupported chains.

Transaction Status

vault.getTxStatus(params): Promise<TxStatusResult>

Check the on-chain status of a previously broadcast transaction. Supports all chain types.

Parameters:

  • params.chain: Chain - The blockchain the transaction was broadcast on

  • params.txHash: string - The transaction hash to check

Returns:

  • status: 'pending' | 'success' | 'error' - Current transaction status

  • receipt?: TxReceiptInfo - Fee details if available (feeAmount, feeDecimals, feeTicker)

Example:

Emits transactionConfirmed or transactionFailed events for terminal states.

Push Notification Methods

Accessed via sdk.notifications:

notifications.registerDevice(options): Promise<void>

Register a device to receive push notifications for a vault.

Parameters:

  • options.vaultId: string - Vault ID (publicKeys.ecdsa)

  • options.partyName: string - Local party ID of the device

  • options.token: string - Push token from APNs, FCM, or Web Push

  • options.deviceType: 'ios' | 'android' | 'web' - Platform type

notifications.unregisterVault(vaultId): Promise<void>

Remove local push registration for a vault.

notifications.notifyVaultMembers(options): Promise<void>

Send a push notification to all other registered devices for a vault.

Parameters:

  • options.vaultId: string - Vault ID

  • options.vaultName: string - Vault display name

  • options.localPartyId: string - Sender's party ID (excluded from recipients)

  • options.qrCodeData: string - Keysign session data for joining

notifications.onSigningRequest(handler): () => void

Register a callback for incoming signing notifications. Returns an unsubscribe function.

notifications.handleIncomingPush(data): void

Process raw push notification data from a platform handler. Parses and invokes registered callbacks.

notifications.parseNotificationPayload(data): SigningNotification | null

Parse raw push data into a typed SigningNotification. Returns null if data doesn't match expected format.

notifications.fetchVapidPublicKey(): Promise<string>

Fetch the VAPID public key for Web Push subscriptions. Only needed for deviceType: 'web'.

notifications.isVaultRegistered(vaultId): Promise<boolean>

Check if a vault is registered locally for push notifications.

notifications.hasRemoteRegistrations(vaultId): Promise<boolean>

Check if any devices are registered for a vault on the server.

notifications.connect(options): void

Open a WebSocket connection for real-time notification delivery. Messages are dispatched through onSigningRequest() callbacks. Auto-reconnects with exponential backoff (1s → 30s cap). Requires prior registerDevice() call.

Parameters:

  • options.vaultId: string - Vault ID (publicKeys.ecdsa)

  • options.partyName: string - Local party ID of the device

  • options.token: string - Same token used for registerDevice()

notifications.disconnect(): void

Close the WebSocket connection and stop auto-reconnect. Also called automatically by sdk.dispose().

notifications.connectionState: WSConnectionState

Current WebSocket state: 'disconnected' | 'connecting' | 'connected' | 'reconnecting'

notifications.onConnectionStateChange(handler): () => void

Register a callback for WebSocket connection state changes. Returns an unsubscribe function.

notifications.ping(): Promise<boolean>

Check if the notification server is reachable.

Utility Methods

isVaultFileEncrypted(file): Promise<boolean>

Check if a vault backup file is encrypted.

validateVault(vault): VaultValidationResult

Validate vault structure and integrity.

getVaultDetails(vault): VaultDetails

Get vault metadata and information.

Error Handling

The SDK throws descriptive errors that you can catch and handle:

Examples

See the /examples directory for complete sample applications:

  • Browser Example - Complete web application with vault creation, import, and address derivation

  • Node.js Example - Server-side vault operations and blockchain interactions

Requirements

  • Node.js 20+

  • Modern browser with WebAssembly support

  • Electron 20+ (for desktop applications)

  • Network access for VultiServer communication (for Fast Vault features)

Security Considerations

  • Private Keys: The SDK uses threshold signatures - private keys are never stored in a single location

  • Encryption: Vault keyshares are encrypted using AES-GCM with user-provided passwords

  • Server Trust: Fast Vaults use VultiServer as one party in the MPC protocol

  • Secure Vault Independence: Secure Vaults only use the relay server for coordination, not signing

  • Configurable Thresholds: Secure Vaults support custom M-of-N thresholds for multi-party approval

  • WASM Integrity: Ensure WASM files are served from trusted sources

Development

Prerequisites

  • Node.js 20+

  • Yarn 4.x

Setup

This SDK is part of a monorepo. Always install dependencies from the root directory:

Building

The SDK bundles functionality from workspace packages (packages/core/ and packages/lib/) into a single distributable package.

This creates the distributable package in packages/sdk/dist/ with all dependencies bundled.

Testing

Development Workflow

  1. Make changes to SDK code in packages/sdk/src/ or workspace packages in packages/core//packages/lib/

  2. Build: yarn workspace @vultisig/sdk build

  3. Test: yarn workspace @vultisig/sdk test

  4. Lint: yarn lint (from root)

Project Structure

Contributing

  1. Fork the repository

  2. Install dependencies from root: yarn install

  3. Make your changes in packages/sdk/src/ or workspace packages

  4. Run tests: yarn workspace @vultisig/sdk test

  5. Build: yarn workspace @vultisig/sdk build

  6. Submit a pull request

License

MIT License - see LICENSEarrow-up-right file for details.

Support


Built with ❤️ by the Vultisig team

Last updated

Was this helpful?