vultisig-sdk

agent
Security Audit
Warn
Health Warn
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 5 GitHub stars
Code Pass
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
  • Permissions — No dangerous permissions requested
Purpose
This TypeScript SDK enables developers and AI agents to interact with self-custodial, multi-chain cryptocurrency wallets. It provides programmatic interfaces for executing cross-chain swaps, managing digital assets, and sending transactions across over 40 blockchains without requiring traditional seed phrases.

Security Assessment
Overall Risk: Medium. This tool manages highly sensitive cryptographic material and handles financial transactions, which inherently elevates its risk profile. It makes network requests to external services like Blockaid, CoinGecko, and various decentralized exchange routers (THORChain, 1inch) to facilitate swaps and price tracking. A light code audit of 12 files found no dangerous patterns, hardcoded secrets, or requests for dangerous system permissions. It does not appear to execute arbitrary shell commands. However, because the vault architecture relies on MPC (Multi-Party Computation) and requires exposing wallet functionality to automated AI agents, developers must thoroughly review the implementation to ensure local key fragments are stored and handled securely.

Quality Assessment
The project is actively maintained, with its most recent push occurring today. It uses the standard permissive MIT license and has a clear, detailed README with comprehensive documentation. However, it currently suffers from extremely low community visibility, boasting only 5 GitHub stars. Consequently, the codebase likely lacks the extensive peer review and real-world battle-testing typically expected for financial software.

Verdict
Use with caution: The code is clean, licensed, and active, but the combination of low community adoption and the high-stakes nature of handling automated cryptocurrency transactions mandates a strict, line-by-line security review before integrating it into any production environment.
SUMMARY

TypeScript SDK for self-custodial multi-chain wallets with MPC security, cross-chain swaps, and AI agent support. 40+ blockchains, no seed phrases.

README.md

Vultisig SDK

The self-custodial multi-chain wallet SDK for AI agents and developers.

  • Send & swap across 40+ blockchains with human-readable amounts (vault.send({ amount: "0.1" }))
  • MPC security — keys are split across parties, no seed phrases, no single point of failure
  • Built-in cross-chain swaps via THORChain, 1inch, KyberSwap, and LiFi — automatic routing
  • Portfolio tracking with real-time balances and fiat prices
  • Dry-run mode for sends and swaps — preview fees and output before signing
  • AI agent ready — JSON output, programmatic API, designed for autonomous operation

Overview

Vultisig SDK enables developers and AI agents to integrate multi-chain wallet functionality into their applications. The SDK supports two vault types:

  • Fast Vault: Server-assisted 2-of-2 MPC for quick setup and instant signing
  • Secure Vault: Multi-device N-of-M MPC for enhanced security with configurable thresholds

Both vault types provide comprehensive blockchain support including Bitcoin, Ethereum, Cosmos, Solana, and 40+ others.

Features

  • Fast Vault: Server-assisted MPC with VultiServer for instant signing (2-of-2 standard, 2-of-3 from seedphrase import)
  • Secure Vault: Multi-device N-of-M threshold signing with mobile device pairing
  • QR Code Pairing: Pair with Vultisig mobile apps for secure vault operations
  • Address Derivation: Generate blockchain addresses using WalletCore WASM
  • Vault Management: Create, import, export, and manage encrypted vaults
  • Cross-Chain Support: Bitcoin, Ethereum, Cosmos, Solana, and 40+ blockchains
  • Token Registry: Built-in known token database, fee coin lookup, and on-chain token discovery
  • Security Scanning: Transaction validation and simulation via Blockaid, site phishing detection
  • Price Feeds: Fetch token prices via CoinGecko
  • Fiat On-Ramp: Generate Banxa buy URLs for 23+ chains
  • Compound Wrappers: send(), swap(), signMessage(), portfolio(), allBalances() — single-call operations with human-readable amounts (send/swap support dryRun)
  • TypeScript: Full type safety and IntelliSense support

Which Interface Should I Use?

The Vultisig SDK ships two interfaces. Pick the right one for your use case:

Programmatic SDK (@vultisig/sdk) CLI (@vultisig/cli)
Install npm install @vultisig/sdk npm install -g @vultisig/cli
Best for Apps, bots, monitoring scripts AI coding agents (Claude Code, Cursor), shell scripts
Language TypeScript — import and call methods Shell — run commands, parse JSON output
Vault creation sdk.createFastVault() + email verification vultisig create fast --two-step (non-interactive)
Agent mode Build your own logic with vault.send(), vault.swap() vultisig agent ask "check my ETH balance" (built-in AI agent)
Long-running Great — initialize WASM once, keep alive Not ideal — each command reloads WASM
Signing onPasswordRequired callback or vault.unlock() --password flag or VAULT_PASSWORD env var

AI coding agent? Start with the CLI — it has built-in agent ask for natural language, --two-step for non-interactive vault creation, and --json for machine-parseable output. See CLI Agent Integration.

Building a bot or app? Use the programmatic SDK — initialize once, call vault.send() / vault.swap() / vault.portfolio() directly with full TypeScript types.

Both? Create your vault with the CLI (vultisig create fast --two-step), then load it in the SDK (sdk.listVaults()) for long-running operations.

Installation

Programmatic SDK

npm install @vultisig/sdk
# or
yarn add @vultisig/sdk

CLI

npm install -g @vultisig/cli
# or run without installing
npx @vultisig/cli --help

Related packages

  • @vultisig/rujira — Rujira (FIN) swaps + secured asset deposit/withdraw helpers on THORChain

Quick Start

Fast Vault (Server-Assisted)

import { Vultisig, Chain } from '@vultisig/sdk'

// Initialize SDK (storage is auto-configured for your platform)
const sdk = new Vultisig()
await sdk.initialize()

// Create a fast vault (server-assisted 2-of-2)
const vaultId = await sdk.createFastVault({
  name: "My Wallet",
  email: "[email protected]",
  password: "secure-password",
});

// Verify with email code
const vault = await sdk.verifyVault(vaultId, "1234");

// Derive addresses
const btcAddress = await vault.address(Chain.Bitcoin);
const ethAddress = await vault.address(Chain.Ethereum);

// Send tokens (human-readable amounts)
const result = await vault.send({ chain: Chain.Ethereum, to: "0x...", amount: "0.1" });

// Sign messages (EIP-191 for EVM, SHA-256 for others)
const { signature } = await vault.signMessage("Login to MyDapp");

// Swap tokens
await vault.swap({ fromChain: Chain.Ethereum, fromSymbol: "ETH", toChain: Chain.Bitcoin, toSymbol: "BTC", amount: "0.5" });

// Portfolio overview
const portfolio = await vault.portfolio("usd");

Secure Vault (Multi-Device)

// Create a secure vault (2-of-3 threshold)
const { vault } = await sdk.createSecureVault({
  name: "Team Wallet",
  devices: 3,
  onQRCodeReady: (qrPayload) => {
    // Display QR code for other devices to scan
    displayQRCode(qrPayload);
  },
  onDeviceJoined: (deviceId, total, required) => {
    console.log(`Device joined: ${total}/${required}`);
  }
});

// Sign transactions (requires device coordination)
await vault.sign(payload, {
  onQRCodeReady: (qr) => displayQRCode(qr),
  onDeviceJoined: (id, total, required) => {
    console.log(`Signing: ${total}/${required} devices ready`);
  }
});

WARNING — Storage & Vault Backups: The SDK auto-configures persistent storage for your platform (FileStorage on Node.js, BrowserStorage in browsers). Do not use MemoryStorage in production — it is non-persistent and all vault keyshares are lost when the process exits. Loss of keyshares means permanent loss of funds. Always back up your vaults using vault.export().

Documentation

Type Reference

All compound methods live on VaultBase (inherited by FastVault and SecureVault).

Balance

type Balance = {
  amount: string           // Raw amount in base units (as string)
  formattedAmount: string  // Human-readable (e.g., "1.5")
  decimals: number         // Token decimal places
  symbol: string           // Token symbol (e.g., "ETH", "BTC")
  chainId: string          // Chain identifier
  tokenId?: string         // Token contract address (if not native coin)
  value?: number           // Price per unit in fiat (populated by portfolio)
  fiatValue?: number       // Total fiat value (populated by portfolio)
  fiatCurrency?: string    // Fiat currency code (e.g., "USD")
}

Portfolio

await vault.portfolio("usd")

type Portfolio = {
  balances: Balance[]   // Balances with fiat values populated
  totalValue: string    // Total portfolio value (human-readable, e.g., "1234.56")
  currency: string      // Fiat currency used (e.g., "usd")
}

Send

// Execute
const result = await vault.send({ chain: Chain.Ethereum, to: "0x...", amount: "0.1" })
// result.txHash -> "0xabc..."

// Dry run (estimate fees without signing)
const preview = await vault.send({ chain: Chain.Ethereum, to: "0x...", amount: "0.1", dryRun: true })
// preview.fee -> "0.00042"
// preview.total -> "0.10042"

type SendResult =
  | { dryRun: false; txHash: string; chain: Chain }
  | { dryRun: true; fee: string; total: string; keysignPayload: KeysignPayload }

Full send params: { chain, to, amount, symbol?, memo?, dryRun? }

  • Omit symbol for native token (ETH, BTC). Set it for ERC-20s (e.g., "USDC").

Swap

// Dry run (get quote)
const quote = await vault.swap({
  fromChain: Chain.Ethereum, fromSymbol: "ETH",
  toChain: Chain.Ethereum, toSymbol: "USDC",
  amount: "0.5", dryRun: true
})
// quote.quote.provider -> "1inch"
// quote.quote.estimatedOutput -> bigint (base units)
// quote.quote.fees -> fee breakdown

// Execute
const result = await vault.swap({
  fromChain: Chain.Ethereum, fromSymbol: "ETH",
  toChain: Chain.Bitcoin, toSymbol: "BTC",
  amount: "0.5"
})
// result.txHash -> "0xabc..."

type CompoundSwapResult =
  | { dryRun: false; txHash: string; chain: Chain; quote: SwapQuoteResult }
  | { dryRun: true; quote: SwapQuoteResult }

type SwapQuoteResult = {
  quote: SwapQuote               // Raw quote from provider
  estimatedOutput: bigint        // Output amount in base units
  estimatedOutputFiat?: number   // Output in fiat
  provider: string               // "thorchain", "1inch", "kyber", "li.fi", "maya"
  expiresAt: number              // Quote expiry (ms)
  requiresApproval: boolean      // ERC-20 approval needed?
  approvalInfo?: SwapApprovalInfo // Approval details (when required)
  fees: SwapFees                 // Fee breakdown (base units)
  feesFiat?: SwapFeesFiat        // Fee breakdown in fiat
  warnings: string[]             // Provider warnings
  fromCoin: ResolvedCoinInfo     // Source coin details
  toCoin: ResolvedCoinInfo       // Destination coin details
  balance: bigint                // Source balance (base units)
  maxSwapable: bigint            // Max swappable (base units)
}

Sign Message

const { signature, chain, algorithm } = await vault.signMessage("Hello World")

type MessageSignature = {
  signature: string        // Hex-encoded (e.g., "0x..." for EVM)
  chain: Chain             // Chain used for signing
  algorithm: 'ECDSA' | 'EdDSA'
}

Vault Loading

// List all vaults
const vaults: VaultBase[] = await sdk.listVaults()

// Find by name (listVaults + filter)
const vault = vaults.find(v => v.name === 'MyVault')

// By ID
const vault: VaultBase | null = await sdk.getVaultById("vault-id")

// Active vault
const vault: VaultBase | null = await sdk.getActiveVault()

Which Balance Method to Use

Need Method Returns
One chain, native coin vault.balance(chain) Balance
One chain, specific token vault.balance(chain, tokenId) Balance
Multiple specific chains vault.balances(chains, includeTokens?) Record<string, Balance>
All configured chains vault.allBalances(includeTokens?) Balance[]
Full portfolio with fiat vault.portfolio("usd") Portfolio

Security

  • No Private Keys: Private keys never exist in complete form
  • MPC Security: Keys are split across multiple parties using threshold signatures
  • Configurable Thresholds: Secure vaults support N-of-M signing (e.g., 2-of-3, 3-of-5)
  • Encryption: All vault data is encrypted with user passwords
  • WASM Isolation: Cryptographic operations run in WebAssembly sandbox

Contributing

See CONTRIBUTING.md for development setup, project structure, and contribution guidelines.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support


Built with ❤️ by the Vultisig Team

Reviews (0)

No results found