# Overview

Crypto security reimagined for the AI Agent era: Self-custodial automation, multi-chain, multi-factor, and the end of seed phrases. Your ultimate wallet.

## Vultisig Project

Vultisig is an open-source cryptocurrency vault that takes a novel approach: seedless, multi-factor, multi-chain security based on MPC (Multi-Party Computation) technology.

Available on iOS, Android, macOS, Windows, Linux, and as a browser extension—Vultisig delivers multi-sig level security without the traditional multi-sig complexity.

***

## What is Vultisig?

Vultisig is a multi-chain, multi-factor, multi-platform Threshold Signature Scheme (TSS) vault. No specialized hardware required.

Supporting UTXO, EVM, BFT, and EdDSA chains (Bitcoin, Ethereum, Cosmos, Solana, and 30+ more), Vultisig generates both ECDSA and EdDSA signature keys for every vault. Hold and sign for BTC, ETH, SOL, and more from a single vault setup.

Powered by [DKLS23](https://github.com/silence-laboratories/dkls23), a state-of-the-art TSS protocol developed by Silence Laboratories.

Built by the founders of [THORChain](https://thorchain.org)—creators of the largest and longest-running multi-chain DEX powered by Threshold Signature Schemes.

### Key Features

* **No seed phrases**: Vault shares replace vulnerable 12/24 word seeds
* **Multi-chain**: 30+ blockchains from one vault (Bitcoin, Ethereum, Solana, Cosmos, and more)
* **Multi-factor**: Multiple devices required to sign transactions
* **Multi-platform**: iOS, Android, macOS, Windows, Linux, Browser Extension
* **Open source**: Fully auditable code on [GitHub](https://github.com/vultisig)

***

## How It Works

Vultisig works like a traditional multisig wallet but with flexible setup options and modern convenience.

**Fast Vault** — Single device + Vultisig server. Quick setup, instant signing.

**Secure Vault** — Multiple devices you control:

* 2-of-2: Fastest setup, no fallback
* 2-of-3: Recommended, with fallback device
* 3-of-4: Maximum security, with fallback device

{% hint style="info" %}
These are the most common configurations, but Vultisig supports a wide range of threshold setups for advanced users.
{% endhint %}

***

## Why Vultisig?

**Better security model:**

* Vault shares don't store funds—no funds at risk if you lose a share
* No on-chain registration of signing keys
* Compatible with all chains and fully DeFi compatible (multi-sigs often aren't)

**Uses devices you already own:**

* Phones, tablets, laptops with familiar interfaces
* Secure Enclaves protect vault shares
* Biometric authentication built-in
* Doesn't look like a hardware wallet (better operational security)

**Open source and audited:**

* Fully transparent codebase on [GitHub](https://github.com/vultisig)
* Security audits completed ([view reports](/help-and-legal/security))

{% hint style="info" %}
**No registration required.** Vultisig never permanently stores your email or personal info. Fast Vaults briefly require email to send backup files—used once and not retained.
{% endhint %}

***

## Quick Navigation

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Getting Started</strong></td><td>New to Vultisig? Download, create your first vault, and make your first transaction.</td><td><a href="/pages/04wGvJcpxv5Z8Y4LZhH0">/pages/04wGvJcpxv5Z8Y4LZhH0</a></td></tr><tr><td><strong>App Guide</strong></td><td>Complete guides for Wallet, DeFi, and Vault Management features.</td><td><a href="/pages/cmNx2uC6LhdQ4hE0fSxn">/pages/cmNx2uC6LhdQ4hE0fSxn</a></td></tr><tr><td><strong>Security &#x26; Technology</strong></td><td>How threshold signatures work, protocol deep-dives, and security architecture.</td><td><a href="/pages/eMasSa2nLw3it9zEVBHb">/pages/eMasSa2nLw3it9zEVBHb</a></td></tr><tr><td><strong>Developer Docs</strong></td><td>Build on Vultisig: SDK, Extension integration, Marketplace development.</td><td><a href="/pages/Ddr8dZAJr8vwRuzC4kQo">/pages/Ddr8dZAJr8vwRuzC4kQo</a></td></tr></tbody></table>

***

## Vultisig Ecosystem

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Vultisig Wallet</strong></td><td>Core vault application for iOS, Android, macOS, Windows, Linux</td><td><a href="/pages/rSqoRXgYkTkDn2tygPON">/pages/rSqoRXgYkTkDn2tygPON</a></td></tr><tr><td><strong>Vultisig Extension</strong></td><td>Browser extension for Web3 dApp connections</td><td><a href="/pages/rtDxPoxH2hhQYPIIVlsN">/pages/rtDxPoxH2hhQYPIIVlsN</a></td></tr><tr><td><strong>Web App</strong></td><td>View-only vault access and airdrop tracking</td><td><a href="/pages/e0zqaPEtyLVEHvFapzlu">/pages/e0zqaPEtyLVEHvFapzlu</a></td></tr><tr><td><strong>Marketplace</strong></td><td>Self-custodial automation marketplace</td><td><a href="/pages/Qsck8PSpzHLPwJmwnU4P">/pages/Qsck8PSpzHLPwJmwnU4P</a></td></tr></tbody></table>

***

## Download

<table data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>iOS</strong></td><td><a href="https://apps.apple.com/us/app/vultisig/id6503023896">https://apps.apple.com/us/app/vultisig/id6503023896</a></td></tr><tr><td><strong>Android</strong></td><td><a href="https://play.google.com/store/apps/details?id=com.vultisig.wallet">https://play.google.com/store/apps/details?id=com.vultisig.wallet</a></td></tr><tr><td><strong>macOS</strong></td><td><a href="https://github.com/vultisig/vultisig-ios">https://github.com/vultisig/vultisig-ios</a></td></tr><tr><td><strong>Windows/Linux</strong></td><td><a href="https://github.com/vultisig/vultisig-windows/releases">https://github.com/vultisig/vultisig-windows/releases</a></td></tr><tr><td><strong>Browser Extension</strong></td><td><a href="https://chromewebstore.google.com/detail/vulticonnect/ggafhcdaplkhmmnlbfjpnnkepdfjaelb">https://chromewebstore.google.com/detail/vulticonnect/ggafhcdaplkhmmnlbfjpnnkepdfjaelb</a></td></tr></tbody></table>

***

## Community

* **Discord**: [discord.gg/Cugw9T2NrP](https://discord.gg/Cugw9T2NrP)
* **Twitter/X**: [@vultisig](https://x.com/vultisig)
* **GitHub**: [github.com/vultisig](https://github.com/vultisig)


# For AI Agents

Structured index of Vultisig documentation for AI agents and language models. SDK and CLI focus.

> Vultisig: Seedless, multi-chain, self-custody wallet using TSS/MPC. TypeScript SDK and CLI for building AI agents, automated plugins, and crypto applications across 40+ blockchains.

## SDK (`@vultisig/sdk`)

TypeScript SDK for MPC vault creation, signing, balance checks, swaps, and transaction management.

**Install:** `npm install @vultisig/sdk`

**Core flow:** Initialize → Create vault → Verify → Use

```typescript
import { Vultisig, MemoryStorage } from '@vultisig/sdk'

const sdk = new Vultisig({ storage: new MemoryStorage() })
await sdk.initialize()

const vaultId = await sdk.createFastVault({ name: 'Agent Wallet', email: 'agent@example.com', password: 'pass' })
const vault = await sdk.verifyVault(vaultId, code)

const address = await vault.address('Ethereum')
const balance = await vault.balance('Ethereum')
```

**Key methods:**

| Method                                  | What it does                                           |
| --------------------------------------- | ------------------------------------------------------ |
| `sdk.createFastVault(opts)`             | Create 2-of-2 vault with VultiServer (instant signing) |
| `sdk.createSecureVault(opts)`           | Create N-of-M multi-device vault (human co-signing)    |
| `sdk.verifyVault(vaultId, code)`        | Verify vault via email code, returns vault             |
| `vault.address(chain)`                  | Derive address for a chain                             |
| `vault.balance(chain)`                  | Get native balance                                     |
| `vault.balances(chains, includeTokens)` | Get balances across chains                             |
| `vault.prepareSendTx(params)`           | Prepare a send transaction                             |
| `vault.sign(payload)`                   | Sign a transaction (MPC)                               |
| `vault.broadcastTx(params)`             | Broadcast signed transaction                           |
| `vault.gas(chain)`                      | Get gas/fee estimate                                   |
| `vault.getSwapQuote(params)`            | Get swap quote (THORChain, 1inch, LiFi)                |
| `vault.prepareSwapTx(params)`           | Prepare swap transaction (handles approval)            |
| `vault.signBytes(opts)`                 | Sign arbitrary pre-hashed bytes                        |
| `vault.broadcastRawTx(params)`          | Broadcast pre-signed raw transaction                   |
| `sdk.importVault(content, password)`    | Import vault from `.vult` file                         |
| `vault.export(password)`                | Export vault to backup                                 |

**Vault types:**

|                    | Fast Vault                | Secure Vault                        |
| ------------------ | ------------------------- | ----------------------------------- |
| **Threshold**      | 2-of-2 (with VultiServer) | N-of-M (configurable)               |
| **Signing**        | Instant, no human needed  | Requires device coordination via QR |
| **Agent use case** | Full autonomy             | Human oversight on every tx         |

**Supported chains (36+):** Bitcoin, Ethereum, Solana, THORChain, Polygon, Arbitrum, Optimism, Base, BSC, Avalanche, Cosmos, Litecoin, Dogecoin, Sui, TON, Ripple, Tron, Polkadot, Cardano, and more.

**Full docs:**

* [SDK README](/developer-docs/vultisig-sdk): Installation, quick start, API reference, vault types, error handling
* [SDK Implementation Guide](/developer-docs/vultisig-sdk/sdk-users-guide): Complete usage guide — password management, vault lifecycle, transactions, swaps, events, caching, platform notes

***

## CLI (`@vultisig/cli`)

Command-line wallet for scripting, automation, and agent pipelines. Mirrors the SDK's full capabilities.

**Install:** `npm install -g @vultisig/cli`

**Key commands:**

```bash
# Vault management
vultisig create fast --name "Wallet" --email user@example.com --password pass
vultisig create secure --name "Team Wallet" --shares 3
vultisig import /path/to/vault.vult
vultisig vaults
vultisig export

# Balances & addresses
vultisig balance                      # All chains
vultisig balance ethereum --tokens    # Specific chain + tokens
vultisig addresses
vultisig portfolio

# Transactions
vultisig send ethereum 0xRecipient 0.1
vultisig send ethereum 0xRecipient 100 --token 0xTokenAddress

# Swaps
vultisig swap-quote ethereum bitcoin 0.1
vultisig swap ethereum bitcoin 0.1

# Natural-language, one-shot — built for AI agent integration
vultisig agent ask "What is my ETH balance?" --password "$VAULT_PASSWORD" --json
vultisig agent ask "Send 0.01 ETH to 0x742d..." --session abc123 --password "$VAULT_PASSWORD"

# Advanced: sign arbitrary bytes, broadcast raw tx
vultisig sign --chain ethereum --bytes "base64hash" -o json
vultisig broadcast --chain ethereum --raw-tx "0x02f8..."

# Seedphrase import
vultisig create-from-seedphrase fast --name "Imported" --email user@example.com --discover-chains
```

**Agent-friendly features:**

* `agent ask "<message>"` — one-shot natural-language mode for AI-to-AI use; returns structured JSON with `--json` and stable error codes
* Non-interactive (non-TTY) auto-detection — skips prompts that would hang an agent; vault creation falls back to two-step mode automatically
* `--ci` — full automation mode (`--output json --non-interactive --quiet`)
* `--output json` (or `-o json`) — structured JSON for all commands
* `--silent` — suppress spinners and progress messages
* `--password` flag — avoid interactive prompts
* `VAULT_PASSWORD` env var — for automation pipelines
* `VULTISIG_VAULT` env var — pre-select vault by name or ID
* Exit codes: 0 success, 1-7 for specific error types
* `vsig` shorthand alias for `vultisig`

**Full docs:** [CLI Documentation](/developer-docs/vultisig-sdk/cli): All commands, options, environment variables, JSON output examples, exit codes, interactive shell

***

## Agent Resources

Files on [vultisig.com](https://vultisig.com) for agent discovery and integration:

| File                                                      | What it is                                                                                          |
| --------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| [SKILL.md](https://vultisig.com/SKILL.md)                 | Full operating procedure — 14 steps covering vault creation, sends, swaps, balances, gas estimation |
| [llms.txt](https://vultisig.com/llms.txt)                 | Spec-compliant link index (llmstxt.org format)                                                      |
| [llms-full.txt](https://vultisig.com/llms-full.txt)       | Full SDK context with verified code examples and source references                                  |
| [agent.json](https://vultisig.com/.well-known/agent.json) | Structured capabilities manifest — chains, operations, SDK info                                     |

***

## Documentation Index

### Getting Started

* [Overview](/): What Vultisig is, key features
* [Download & Install](/getting-started/download-install): iOS, Android, macOS, Windows, Linux, browser extension
* [Create a Vault](/getting-started/create-vault): Fast Vault and Secure Vault creation
* [Backup & Recovery](/getting-started/backup-recovery): Vault backup and restore
* [Your First Transaction](/getting-started/first-transaction): Send your first transaction

### App Guide

* [Vault Creation](/app-guide/creating-a-vault): Vault types and flows
  * [Fast Vault](/app-guide/creating-a-vault/fast-vault): 2-of-2 with VultiServer
  * [Secure Vault](/app-guide/creating-a-vault/secure-vault): Multi-device with QR pairing
* [Sending](/app-guide/wallet/sending): How to send tokens
* [Swapping](/app-guide/wallet/swapping): Cross-chain and same-chain swaps
* [DeFi](/app-guide/defi): Circle Protocol, THORChain, MayaChain, staking
* [Vault Management](/app-guide/vault-management): Details, backups, reshare, rename, upgrade

### Security & Technology

* [Overview](/security-and-technology/overview): Security architecture
* [Keysign](/security-and-technology/keysign): Transaction signing
* [TSS Actions](/security-and-technology/tss-actions): Threshold signature operations
* [How GG20 Works](/security-and-technology/how-gg20-works): GG20 protocol
* [How DKLS23 Works](/security-and-technology/how-dkls23-works): DKLS23 protocol
* [Difference to Multi-Signatures](/security-and-technology/difference-to-multi-sig): TSS vs multisig
* [Emergency Recovery](/security-and-technology/emergency-recovery): Recovery procedures

### Ecosystem

* [Vultisig Extension](/ecosystem/vultisig-extension): Browser extension for dApps
* [Plugin Marketplace](/ecosystem/marketplace): Self-custodial automation — plugins and AI agents
* [Web App](/ecosystem/web-app): Browser-based vault access
* [Vultisig SDK](/ecosystem/vultisig-sdk): SDK overview with agent section
* [Community Tools](/ecosystem/community-tools): Third-party tools

### VULT Token

* [The $VULT Token](/vult-token/vult): Tokenomics and utility
* [In-App Utility](/vult-token/vult/in-app-utility): Fee discounts, staking tiers
* [Marketplace Utility](/vult-token/vult/marketplace-utility): Revenue distribution
* [Governance](/vult-token/vult/governance-utility): Voting rights

### Infrastructure

* [Overview](/infrastructure/overview): Architecture
* [Vultiserver](/infrastructure/what-is-vultisigner): Co-signing server for Fast Vaults
* [Transaction Policies](/infrastructure/what-is-vultisigner/what-can-be-configured): Spending limits, whitelists, time delays
* [Relay Server](/infrastructure/relay-server): Device session coordination

### Developer Docs

* [Developer Home](/developer-docs/developer-docs): Entry point
* [Marketplace Plugins](/developer-docs/marketplace): Build and publish plugins
  * [What is a Plugin](/developer-docs/marketplace/plugins): Architecture and scope
  * [Services Architecture](/developer-docs/marketplace/services): Service components
  * [Policy Rules](/developer-docs/marketplace/metarules): Transaction validation rules
  * [Infrastructure](/developer-docs/marketplace/infrastructure): Plugin infrastructure
  * [Quick Start](/developer-docs/marketplace/basics-quick-start): Scaffold your first plugin
  * [Build Your Plugin](/developer-docs/marketplace/build-your-plugin): Full development guide
  * [Submission & Revenue](/developer-docs/marketplace/submission-process): Review process, 70/30 split
* [Extension Integration](/developer-docs/vultisig-extension-integration-guide): window\.vultisig API, code examples
* [SDK](/developer-docs/vultisig-sdk): Full SDK docs
  * [SDK Implementation Guide](/developer-docs/vultisig-sdk/sdk-users-guide): Detailed usage guide
  * [SDK CLI](/developer-docs/vultisig-sdk/cli): CLI reference

### Help & Legal

* [FAQ](/help-and-legal/faq): Common questions
* [Security](/help-and-legal/security): Security policy
* [Privacy](/help-and-legal/privacy): Privacy policy
* [Terms of Use](/help-and-legal/terms): Terms


# Overview

Get started with Vultisig in minutes. Download, create your first vault, and send your first transaction - no seed phrases required.

Welcome to Vultisig! This guide will get you up and running with the most secure self-custodial wallet in crypto.

{% hint style="danger" %}
**Critical: Backup Your Vault**

Your vault backup is the ONLY way to recover access if you lose a device. Read the [Backup & Recovery](/getting-started/backup-recovery) guide before storing any significant funds.
{% endhint %}

***

## Quick Start Path

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>1. Download &#x26; Install</strong></td><td>Get Vultisig on your devices</td><td><a href="/pages/rSqoRXgYkTkDn2tygPON">/pages/rSqoRXgYkTkDn2tygPON</a></td></tr><tr><td><strong>2. Create Your Vault</strong></td><td>Set up your first vault in minutes</td><td><a href="/pages/GKEHQk0ZFzZBwMsBKXYn">/pages/GKEHQk0ZFzZBwMsBKXYn</a></td></tr><tr><td><strong>3. Backup Your Vault</strong></td><td>Essential - protect your assets</td><td><a href="/pages/Khl5UkSsWOHjrDdmqu49">/pages/Khl5UkSsWOHjrDdmqu49</a></td></tr><tr><td><strong>4. First Transaction</strong></td><td>Send or receive your first crypto</td><td><a href="/pages/BDFJXCBNk7ajvLcCcovf">/pages/BDFJXCBNk7ajvLcCcovf</a></td></tr></tbody></table>

***

## What Makes Vultisig Different?

| Traditional Wallets                   | Vultisig                                    |
| ------------------------------------- | ------------------------------------------- |
| Seed phrase (single point of failure) | No seed phrases - distributed vault shares  |
| One device controls everything        | Multi-device security by design             |
| Hardware wallet required for security | Your existing devices become secure signers |
| Single-chain or limited chains        | 30+ blockchains from one vault              |

***

## Choose Your Path

**Using the Vultisig app?**

* [Fast Vault](/app-guide/creating-a-vault/fast-vault) - single device, quick setup
* [Secure Vault](/app-guide/creating-a-vault/secure-vault) - multi-device, maximum security

**Building with the SDK or CLI?**

* [SDK Developer Docs](/developer-docs/vultisig-sdk) - TypeScript SDK for web apps, backends, and AI agents
* [CLI Documentation](/developer-docs/vultisig-sdk/cli) - Command-line wallet for scripts and automation

***

## Need Help?

* [FAQ](/help-and-legal/faq) - Common questions answered
* [Discord Community](https://discord.com/invite/9wrAfNSRpS) - Get help from the team and community


# Download & Install

Download Vultisig for iOS, Android, Windows, Linux, or Chrome. Available on all major platforms for secure multi-device crypto management.

Vultisig is available on all major platforms. Download on at least two devices to create a Secure Vault, or use a single device with a Fast Vault.

***

## Mobile

| Platform           | Link                                                                             | Notes           |
| ------------------ | -------------------------------------------------------------------------------- | --------------- |
| **iOS**            | [App Store](https://apps.apple.com/us/app/vultisig/id6503023896)                 | iPhone and iPad |
| **iOS TestFlight** | [TestFlight](https://testflight.apple.com/join/dxKWaCNK)                         | Beta features   |
| **Android**        | [Google Play](https://play.google.com/store/apps/details?id=com.vultisig.wallet) | Android 8.0+    |

***

## Desktop

| Platform    | Link                                                                     | Notes              |
| ----------- | ------------------------------------------------------------------------ | ------------------ |
| **macOS**   | [GitHub Releases](https://github.com/vultisig/vultisig-ios)              | Build from source  |
| **Windows** | [GitHub Releases](https://github.com/vultisig/vultisig-windows/releases) | Windows 10/11      |
| **Linux**   | [GitHub Releases](https://github.com/vultisig/vultisig-windows/releases) | AppImage available |

***

## Browser Extension

| Browser    | Link                                                                                                       | Notes            |
| ---------- | ---------------------------------------------------------------------------------------------------------- | ---------------- |
| **Chrome** | [Chrome Web Store](https://chromewebstore.google.com/detail/vulticonnect/ggafhcdaplkhmmnlbfjpnnkepdfjaelb) | Connect to dApps |

{% hint style="info" %}
The browser extension requires the Vultisig mobile or desktop app to sign transactions. It's a companion tool, not a standalone wallet.
{% endhint %}

***

## Source Code

Vultisig is fully open-source:

* [iOS/macOS Source](https://github.com/vultisig/vultisig-ios)
* [Android Source](https://github.com/vultisig/vultisig-android)
* [Windows/Linux Source](https://github.com/vultisig/vultisig-windows)

***

## System Requirements

**Mobile:**

* iOS 15.0 or later
* Android 8.0 or later

**Desktop:**

* Windows 10/11 (64-bit)
* macOS 12.0 or later
* Linux (most modern distributions)

***

## Next Step

Once installed, proceed to [Create Your Vault](/getting-started/create-vault).


# Create a Vault

Create your first Vultisig vault. Choose between Fast Vault for quick setup or Secure Vault for multi-device security.

A vault is your secure container for crypto assets. Vultisig uses Threshold Signature Scheme (TSS) technology - your private key is never stored in one place.

***

## Choose Your Vault Type

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Fast Vault</strong></td><td>Single device + Vultisig server</td><td>Best for: Getting started, smaller amounts, convenience</td><td><a href="/pages/FEL7F7Jt93789e56MRtb">/pages/FEL7F7Jt93789e56MRtb</a></td></tr><tr><td><strong>Secure Vault</strong></td><td>2+ devices you control</td><td>Best for: Maximum security, larger amounts, no trusted third party</td><td><a href="/pages/uxqdntNl3mTHlg1Ja3al">/pages/uxqdntNl3mTHlg1Ja3al</a></td></tr></tbody></table>

***

## Quick Comparison

| Feature                  | Fast Vault         | Secure Vault      |
| ------------------------ | ------------------ | ----------------- |
| Setup time               | \~1 minute         | \~3 minutes       |
| Devices needed           | 1                  | 2 or more         |
| Vultisig server involved | Yes (as co-signer) | No                |
| Self-custody level       | Partial            | Full              |
| Best for                 | Daily transactions | Long-term storage |

***

## Recommended Configurations

**For beginners:**

* Start with a **Fast Vault** to learn the app
* Upgrade to Secure Vault later for larger amounts

**For security-conscious users:**

* **2-of-2**: Two devices, both required to sign (no backup device)
* **2-of-3**: Three devices, any two can sign (recommended - has backup)
* **3-of-4**: Four devices, any three can sign (maximum security)

{% hint style="success" %}
**2-of-3 is the sweet spot** - secure enough for most users, with a backup device in case one is lost.
{% endhint %}

***

## Video Guides

**Creating a Fast Vault:**

[![Fast Vault Setup](/files/T8ARtfgVx4nJ6n5vYjUz)](https://x.com/iceman00008/status/1955828412876312653/video/1)

**Creating a 2-of-2 Secure Vault:**

[![2-of-2 Setup](/files/T8ARtfgVx4nJ6n5vYjUz)](https://x.com/iceman00008/status/1955865336341041197/video/1)

**Creating a 3-of-4 Secure Vault:**

[![3-of-4 Setup](/files/T8ARtfgVx4nJ6n5vYjUz)](https://x.com/iceman00008/status/1958428338915287477/video/1)

***

## After Creating Your Vault

{% hint style="danger" %}
**Immediately backup your vault!**

This is the most important step. Without a backup, you could lose access to your funds if a device is lost or damaged.

[Backup & Recovery Guide →](/getting-started/backup-recovery)
{% endhint %}

***

## Detailed Guides

For step-by-step instructions with screenshots:

* [Fast Vault Setup Guide](/app-guide/creating-a-vault/fast-vault)
* [Secure Vault Setup Guide](/app-guide/creating-a-vault/secure-vault)


# Backup & Recovery

Critical guide to backing up your Vultisig vault. Protect your assets with proper vault share storage. No seed phrases - just secure backups.

{% hint style="danger" %}
**This is the most important page in the documentation.**

Without proper backups, you WILL lose access to your funds if a device is lost, stolen, or damaged. Read this entire page before storing any significant value.
{% endhint %}

***

## How Vultisig Backups Work

Vultisig doesn't use seed phrases. Instead, each device in your vault has a unique **Vault Share** - a file that allows that device to participate in signing.

**Key concepts:**

* Each device has its **own unique** vault share
* Each device needs its **own backup**
* A single vault share alone cannot access your funds
* You need your signing threshold of shares to recover (e.g., 2 shares for a 2-of-3 vault)

***

## Video Overview

[![Backup Overview](/files/qNeTqNAxbFVp6BuZpeik)](https://x.com/vultisig/status/1981438381184958698)

***

## How to Backup

### Step-by-Step

1. Open Vultisig app
2. Go to **Settings** → **Vault Settings**
3. Select **Backup**
4. (Optional) Set an encryption password for extra security
5. Save the `.vult` file to a secure location
6. **Repeat for every device** in your vault

### Video Guide

[![Backup Tutorial](/files/T8ARtfgVx4nJ6n5vYjUz)](https://twitter.com/iceman00008/status/1824686908368412732/video/1)

***

## Understanding Vault Share Files

Vault shares use the `.vult` extension and are named:

```
vaultname-ID-share(t)of(n).vult
```

Example: `savings-ef8b-share1of2.vult`

* `savings` = vault name
* `ef8b` = vault ID
* `share1of2` = this is share 1 of a 2-share vault

{% hint style="info" %}
**DKLS vaults** use "share" in the filename. **GG20 vaults** use "part" in the filename.
{% endhint %}

***

## Where to Store Backups

{% hint style="danger" %}
**NEVER store multiple vault shares in the same location!**

If someone gains access to enough shares, they can reconstruct your vault and steal your funds.
{% endhint %}

### Recommended Storage Strategy

| Share   | Storage Location |
| ------- | ---------------- |
| Share 1 | Google Drive     |
| Share 2 | iCloud           |
| Share 3 | Dropbox          |

### Good Practices

* Use different cloud providers for different shares
* Consider password managers (1Password, Bitwarden) for individual shares
* Use offline storage (USB drive, external hard drive) for maximum security
* Encrypt your backups with a strong password

### Bad Practices

* Storing all shares on one device
* Storing all shares in one cloud account
* Emailing shares to yourself (all in one inbox)
* Storing shares unencrypted on shared computers

***

## Estate Planning (Gold Standard)

For inheritance and emergency access:

1. **Share 1**: Keep in your personal secure storage
2. **Share 2**: Give to spouse or trusted family member
3. **Share 3**: Give to family lawyer or accountant

{% hint style="info" %}
Ensure the people holding shares cannot easily collaborate without your knowledge.
{% endhint %}

***

## Recovering a Lost Device

If you lose a device, you have two options:

### Option 1: Import Backup

Import your backed-up vault share into a new device:

1. Install Vultisig on the new device
2. Open the `.vult` file (or import via app)
3. Enter the encryption password (if set)
4. Your vault is restored on the new device

{% hint style="success" %}
Vault shares are cross-platform. An iOS backup can be imported on Android, Windows, etc.
{% endhint %}

### Option 2: Reshare (2-of-3+ vaults only)

If you have a 2-of-3 or larger vault:

1. Use your remaining devices to [reshare](/app-guide/vault-management/vault-reshare) the vault
2. This creates new shares including one for your new device
3. **Important**: Old backups become invalid after resharing

***

## Critical Warnings

{% hint style="danger" %}
**Backups are reshare-sensitive**

After using the [reshare feature](/app-guide/vault-management/vault-reshare), all old backups become invalid. You must create new backups after every reshare.
{% endhint %}

{% hint style="danger" %}
**Fast Vaults still need backups**

Even though Vultisig's server is a co-signer, you still need to backup your device's share. The server cannot recover your vault alone.
{% endhint %}

{% hint style="success" %}
**Fast Vault Priority: Device Share First**

For Fast Vaults, the device backup is the most important. If you have your device share and remember the password you set during creation, you can always request the server share again via email. Prioritize securing your device share backup.
{% endhint %}

***

## Backup Checklist

Before storing significant funds, confirm:

* [ ] I have backed up **every device** in my vault
* [ ] Each backup is stored in a **different location**
* [ ] I understand that I need **\[threshold] shares** to recover
* [ ] I have tested importing a backup on a spare device (optional but recommended)
* [ ] I have set encryption passwords on my backups (optional but recommended)

***

## Next Step

Once backed up, you're ready for your [First Transaction](/getting-started/first-transaction).


# Your First Transaction

Send or receive your first crypto with Vultisig. Quick guide to making your first transaction with multi-device security.

Your vault is created and backed up. Now let's move some crypto!

***

## Receiving Crypto

### Get Your Address

1. Open your vault in Vultisig
2. Tap on the asset you want to receive (e.g., Bitcoin, Ethereum)
3. Tap **Receive** or the QR code icon
4. Copy the address or share the QR code

{% hint style="info" %}
Each blockchain has its own address. Your Bitcoin address is different from your Ethereum address.
{% endhint %}

### Deposit From

* Another wallet you own
* An exchange (Coinbase, Binance, Kraken, etc.)
* A friend sending you crypto

***

## Sending Crypto

### Step-by-Step

1. **Select the asset** you want to send from your vault
2. **Tap "Send"**
3. **Enter the recipient address** - paste or scan QR code
4. **Enter the amount** - or tap "Max" for everything
5. **Review the transaction** - check address, amount, and fee
6. **Sign with your devices** - bring your threshold of devices together
7. **Done!** - transaction broadcasts automatically

### Tips

* **Double-check the address** - crypto transactions are irreversible
* **Start small** - send a test transaction first for large amounts
* **Have enough for fees** - keep some native token (ETH, BTC, SOL) for gas

***

## The Signing Process

This is where Vultisig's security shines:

1. **Initiate** - Start the transaction on one device
2. **Pair** - Other device(s) scan the QR code or connect via relay
3. **Review** - All devices show the same transaction details
4. **Approve** - Each device approves independently
5. **Sign** - Threshold signatures combine to create a valid transaction
6. **Broadcast** - Transaction is sent to the blockchain

{% hint style="success" %}
**No single device ever has the full private key.** Even if one device is compromised, your funds remain safe.
{% endhint %}

For detailed information on the signing process, see [How Keysigning Works](/security-and-technology/keysign).

***

## Supported Actions

Once you're comfortable with basic transactions, explore:

| Action   | Description                     | Guide                                        |
| -------- | ------------------------------- | -------------------------------------------- |
| **Send** | Transfer crypto to any address  | [Sending Guide](/app-guide/wallet/sending)   |
| **Swap** | Exchange one crypto for another | [Swapping Guide](/app-guide/wallet/swapping) |
| **DeFi** | Stake, bond, provide liquidity  | [DeFi Guide](/app-guide/defi)                |

***

## Troubleshooting

**Transaction stuck?**

* Check the blockchain explorer for your transaction
* Network congestion can cause delays
* Ensure you paid sufficient gas fees

**Signing failed?**

* Ensure all devices are on the same network
* Try the relay server if QR scanning fails
* Restart the app and try again

**Need help?**

* [FAQ](/help-and-legal/faq)
* [Discord Community](https://discord.com/invite/9wrAfNSRpS)

***

## What's Next?

Explore the full [App Guide](/app-guide/overview) to learn about:

* [Wallet features](/app-guide/wallet) - Send, swap, manage assets
* [DeFi](/app-guide/defi) - Stake, bond, earn yield
* [Vault Management](/app-guide/vault-management) - Rename, reshare, upgrade


# Overview

Complete guide to the Vultisig app. Navigate the Wallet and DeFi tabs, manage vaults, and access all features across iOS, Android, and desktop.

The Vultisig app is organized into two main sections, accessible via the bottom navigation bar: **Wallet** and **DeFi**. This guide covers all app functionality in the same structure as the app itself.

***

## App Structure

| Tab        | Purpose                           | Key Features                               |
| ---------- | --------------------------------- | ------------------------------------------ |
| **Wallet** | Asset management and transactions | Send, receive, swap across 30+ chains      |
| **DeFi**   | Decentralized finance operations  | Stake, bond, provide liquidity, earn yield |

Additional functionality is available through **Vault Management** in the settings menu.

***

## Sections

### Creating a Vault

Set up your first vault with either Fast Vault (single device) or Secure Vault (multi-device).

{% content-ref url="/pages/1WqRqgJy29abLy1chbxc" %}
[Creating a Vault](/app-guide/creating-a-vault)
{% endcontent-ref %}

### Wallet

The Wallet tab provides asset management capabilities: viewing balances, sending crypto, receiving funds, and swapping between assets.

{% content-ref url="/pages/6wEurqpv0oLkEkW7HfD6" %}
[Wallet](/app-guide/wallet)
{% endcontent-ref %}

### DeFi

The DeFi tab offers direct access to decentralized finance protocols. Users can stake tokens, bond to nodes, provide liquidity, and earn yield—all without connecting to external dApps.

{% content-ref url="/pages/Lv7btHV1k0Mc6LxpyWmB" %}
[DeFi](/app-guide/defi)
{% endcontent-ref %}

### Vault Management

Vault settings and maintenance: backups, renaming, resharing keys, and security upgrades.

{% content-ref url="/pages/3XUNsEV9jsPcRpz0hodr" %}
[Vault Management](/app-guide/vault-management)
{% endcontent-ref %}

***

## Platform Availability

The Vultisig app is available on:

* iOS (iPhone, iPad)
* Android
* macOS
* Windows
* Linux

All platforms share the same core functionality. The interface adapts to each platform while maintaining consistent features.

***

## Related

* [Getting Started](/getting-started/overview) - New user onboarding
* [Security & Technology](/security-and-technology/overview) - How Vultisig works under the hood
* [Vultisig Extension](/ecosystem/vultisig-extension) - Browser extension for dApp connections


# Creating a Vault

Create a Vultisig vault in minutes. Choose Fast Vault for quick setup or Secure Vault for multi-device security. No seed phrases required.

Vultisig vaults are multi-factor by nature, requiring coordination between multiple signing parties. There are two vault types designed to meet different user needs: from a convenient "hot wallet" option to a highly secure "cold wallet" configuration.

Creating a vault is also called a Key Generation (KeyGen) event. See [TSS Actions](/security-and-technology/tss-actions) for technical details.

***

## Vault Types

{% hint style="success" %}
iOS, macOS, Android, Windows, Chrome browser, and Linux are supported. Check the [website](https://vultisig.com/) for the latest platform availability.
{% endhint %}

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Fast Vault</strong></td><td>Single device + Vultisig server. Quick setup, ideal for daily transactions.</td><td><a href="/pages/FEL7F7Jt93789e56MRtb">/pages/FEL7F7Jt93789e56MRtb</a></td></tr><tr><td><strong>Secure Vault</strong></td><td>Multiple user devices. Maximum security, ideal for long-term storage.</td><td><a href="/pages/uxqdntNl3mTHlg1Ja3al">/pages/uxqdntNl3mTHlg1Ja3al</a></td></tr></tbody></table>

<figure><img src="/files/Shs9f3PzfeOrT1pxzP6R" alt="" width="375"><figcaption></figcaption></figure>

***

## Video Guides

**Creating a Fast Vault:**

[![Fast Vault](/files/T8ARtfgVx4nJ6n5vYjUz)](https://x.com/iceman00008/status/1955828412876312653/video/1)

**Creating a 2-of-2 Secure Vault:**

[![2-of-2 Vault](/files/T8ARtfgVx4nJ6n5vYjUz)](https://x.com/iceman00008/status/1955865336341041197/video/1)

**Creating a 3-of-4 Secure Vault:**

[![3-of-4 Vault](/files/T8ARtfgVx4nJ6n5vYjUz)](https://x.com/iceman00008/status/1958428338915287477/video/1)

***

## After Creation

{% hint style="danger" %}
**Always backup your vault immediately after creation.**

Without proper backups, device loss means permanent loss of access to funds. See [Backup & Recovery](/getting-started/backup-recovery).
{% endhint %}


# Fast Vault

Create a Fast Vault in seconds—single-device hot wallet powered by Vultisigner. Perfect for daily transactions with seedless MPC security.

## Overview

Fast Vault is the "hot wallet" equivalent in Vultisig. It allows vault creation with a single device, without requiring multiple devices from the user.

Fast Vaults are configured as two-factor vaults: one factor is the user's device, the other is the Vultiserver, which automatically co-signs user requests. This creates a single-signature experience while maintaining threshold security.

Learn more about Vultiserver in the [Infrastructure documentation](/infrastructure/what-is-vultisigner).

<figure><img src="/files/RUo6zZq9BGbsDxyDfaMm" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Fast Vaults are recommended for daily transactions and smaller amounts. For larger holdings, use a [Secure Vault](/app-guide/creating-a-vault/secure-vault).
{% endhint %}

***

## Creation Steps

<figure><img src="/files/yquJJ4gKLJuxh6QMItwV" alt="" width="375"><figcaption></figcaption></figure>

1. Download Vultisig and open the app
2. Select **Fast Vault** option

<figure><img src="/files/cNyVg3FBNeT4FmSuGxOR" alt="" width="375"><figcaption></figcaption></figure>

3. Choose a vault name
4. Enter your email to receive the server vault share
5. Set a password for the server share

{% hint style="warning" %}
Remember this password. It encrypts your backup and is the only way to access it. Vultisig cannot help with password recovery.
{% endhint %}

6. Set an optional hint for the password
7. Start keygen and wait for completion
8. Enter the 4-digit verification code received via email
9. Backup your device share

{% hint style="danger" %}
Do not store the device backup on the device itself. Use separate cloud storage or offline media.
{% endhint %}

10. Start using your Fast Vault

***

## Backups

Fast Vaults have **two backup shares** despite using one user device for signing:

* **Device share**: Your device's vault share
* **Server share**: Sent to your email during creation

{% hint style="info" %}
Both shares must be backed up in separate locations. See [Backup & Recovery](/getting-started/backup-recovery) for storage recommendations.
{% endhint %}

***

## Troubleshooting

**Unable to connect to the server** The server may be temporarily unavailable. Try again later.

**Unstable Network** Keygen may fail with unstable connections. Quit the app, change networks, and restart.

**Unable to sign with Fast Vault**

1. *Server not available*: Try again later
2. *QR code appears instead of password prompt*: You imported the server share instead of the device share. Import the correct device share.


# Secure Vault

Create a Secure Vault with multiple devices for cold storage security. Flexible threshold signing (2-of-2 up to m-of-n). Ideal for holdings and DAOs.

## Overview

Secure Vault offers the highest level of security—the "cold wallet" equivalent in Vultisig. These vaults consist solely of user-controlled devices with no third-party involvement.

A minimum of two devices is required; three or more is recommended for redundancy. Additional devices increase the signing threshold and enhance security.

<figure><img src="/files/43aYnr9Htkyaz9e6N19A" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Secure Vaults are ideal for shared wallets among multiple users and DAOs.
{% endhint %}

***

## Threshold Configurations

Secure Vaults use an `m`-of-`n` threshold where `m` is at least 67% of `n`. Common configurations:

| Setup      | Devices | Signing | Redundancy     | Recommendation   |
| ---------- | ------- | ------- | -------------- | ---------------- |
| **2-of-3** | 3       | 2       | Yes (1 device) | **Recommended**  |
| **3-of-4** | 4       | 3       | Yes (1 device) | Maximum security |
| **2-of-2** | 2       | 2       | No             | Not recommended  |

{% hint style="info" %}
**Best practice for maximum redundancy:**

1. Use 3 different platforms (Mac, iOS, Android)
2. Encrypt vault shares with 3 different passwords
3. Store shares in 3 different cloud providers (Google, iCloud, Dropbox)
4. Use unique email addresses with 2FA for each cloud account

This setup allows recovery from anywhere in the world with just email access and passwords—no hardware wallets or seed phrases required.
{% endhint %}

***

## Creation Steps

**Requirements:**

* One initiating device
* One or more pairing devices

<figure><img src="/files/yquJJ4gKLJuxh6QMItwV" alt="" width="375"><figcaption></figcaption></figure>

### On the Initiating Device

1. Select **Secure Vault** option

<figure><img src="/files/r71T7U6owhSmEK9Tw4ug" alt="" width="375"><figcaption></figcaption></figure>

2. Choose a vault name
3. A QR code will appear for pairing devices

<figure><img src="/files/5Pqi8bH1Bkk5CWisVSAO" alt=""><figcaption></figcaption></figure>

### On Pairing Devices

4. Select **Scan QR code** and scan the initiating device's QR

<figure><img src="/files/oliQ0naX5ynLfZiItcAB" alt=""><figcaption></figcaption></figure>

### Complete Setup

5. When all devices are connected, tap **Next** on the initiating device
6. Wait for keygen to complete on all devices

<figure><img src="/files/Mw4wiC3lZsw6rhXvGdKZ" alt=""><figcaption></figcaption></figure>

***

## Network Options

| Mode         | Description                | Use Case                               |
| ------------ | -------------------------- | -------------------------------------- |
| **Internet** | Uses Vultisig relay server | Devices on different networks          |
| **Local**    | Uses local WiFi (mDNS)     | Same network, may not work on all WiFi |

<figure><img src="/files/uA9rSGJwYyPEmZ92fHf2" alt="" width="281"><figcaption></figcaption></figure>

***

## After Creation

{% hint style="warning" %}
**Immediately backup every device** after vault creation. Without backups, device loss can mean permanent fund loss.

See [Backup & Recovery](/getting-started/backup-recovery) for detailed instructions.
{% endhint %}


# Wallet

Vultisig Wallet tab: send, receive, and swap crypto across 30+ blockchains. Multi-chain asset management with threshold signature security.

The Wallet tab is the primary interface for managing crypto assets. It displays all holdings across supported blockchains and provides access to core transaction functions.

***

## Features

| Function            | Description                                                             |
| ------------------- | ----------------------------------------------------------------------- |
| **View Assets**     | See balances across all chains in one view                              |
| **Receive**         | Generate addresses and QR codes for deposits                            |
| **Send**            | Transfer assets to any address                                          |
| **Swap**            | Exchange assets within or across chains                                 |
| **Chain Functions** | Chain-specific actions via the **Functions** button on supported chains |

***

## Chain Functions

Some chains expose extra actions beyond send/receive/swap. Tap a chain in the Wallet tab, then tap **Functions** to access them.

| Chain                                                   | Functions                                               |
| ------------------------------------------------------- | ------------------------------------------------------- |
| [Cosmos Hub / Kujira / Osmosis](/app-guide/defi/cosmos) | IBC Transfer, Switch (→ THORChain), Custom transactions |
| [TON](/app-guide/defi/ton)                              | Stake, Unstake                                          |
| [dYdX](/app-guide/defi/dydx)                            | Vote on governance proposals                            |

***

## Supported Chains

Vultisig supports 30+ blockchains including:

* **UTXO**: Bitcoin, Litecoin, Dogecoin, Bitcoin Cash, Dash
* **EVM**: Ethereum, Arbitrum, Optimism, Base, Polygon, BSC, Avalanche
* **Cosmos**: Cosmos Hub, Osmosis, Kujira, Dydx, THORChain, Maya
* **Other**: Solana, Polkadot, Sui, TON, Ripple

All chains are accessible from a single vault. Each vault generates addresses for all supported chains automatically.

***

## Transaction Security

All transactions from the Wallet tab require threshold signatures:

1. Transaction is initiated on one device
2. Other devices join the signing session
3. Each device independently verifies and approves
4. Threshold signatures combine to create a valid transaction
5. Transaction broadcasts to the blockchain

No single device ever holds the complete private key. See [How Keysigning Works](/security-and-technology/keysign) for technical details.

***

## Guides

{% content-ref url="/pages/7WNNsGgy1Si3VnSmwqnG" %}
[Sending](/app-guide/wallet/sending)
{% endcontent-ref %}

{% content-ref url="/pages/VCKsnk7Hzw0o6YQaw0qJ" %}
[Swapping](/app-guide/wallet/swapping)
{% endcontent-ref %}


# Sending

Send crypto across 30+ blockchains with Vultisig. Step-by-step guide for secure, seedless transactions using threshold signatures.

Vultisig supports sending assets on all integrated blockchains. Transactions are secured using threshold signatures—no single device ever holds the complete private key.

***

## How to Send

1. **Select the asset** from your vault's asset list
2. **Tap "Send"** to enter the send flow
3. **Enter the recipient address** — paste or scan a QR code
4. **Enter the amount** — tap "Max" to send the full balance
5. **Review the transaction** including network fee
6. **Sign with your devices** — bring your threshold of devices together
7. **Transaction broadcasts** automatically after successful signing

<figure><img src="/files/3BYE6v9A5HLs7xOydYMN" alt=""><figcaption><p>Send Flow</p></figcaption></figure>

***

## Supported Chains

Sending is supported on all integrated blockchains, including Bitcoin, Ethereum, Solana, THORChain, and 30+ others.

***

## Tips

* **Double-check the recipient address** — blockchain transactions are irreversible
* **Ensure sufficient balance** for network fees (gas)
* **Use QR scanning** when possible to avoid address typos
* **For large amounts**, send a small test transaction first

***

## Related

* [Keysign](/security-and-technology/keysign) — How transaction signing works
* [Swapping](/app-guide/wallet/swapping)


# Swapping

Swap crypto across chains with Vultisig. Integrated with THORChain, Maya, 1inch, Li.Fi, and Kyberswap for secure cross-chain exchanges.

Vultisig supports swapping assets both within the same chain and across different blockchains. All swaps are secured by threshold signatures.

***

## How to Swap

1. **Tap "Swap"** from your vault view
2. **Select the asset to swap from** (source)
3. **Select the asset to receive** (destination)
4. **Enter the amount** to swap
5. **Review the quote** — rate, fees, and estimated output
6. **Sign with your devices**
7. **Monitor the swap** — cross-chain swaps depend on blockchain finality

<figure><img src="/files/YDx0cDauQGno1dlFQqZU" alt=""><figcaption><p>Swap Flow</p></figcaption></figure>

***

## Swap Providers

Vultisig automatically selects the best route using integrated providers:

| Provider                                       | Type              | Speciality                                |
| ---------------------------------------------- | ----------------- | ----------------------------------------- |
| [THORChain](https://thorchain.org/)            | Cross-chain DEX   | Native cross-chain swaps (BTC, ETH, etc.) |
| [MAYA Protocol](https://www.mayaprotocol.com/) | Cross-chain DEX   | Extended asset support                    |
| [1inch](https://1inch.io/)                     | DEX Aggregator    | Best rates across EVM DEXs                |
| [Li.Fi](https://li.fi/)                        | Bridge Aggregator | Cross-chain bridging                      |
| [Kyberswap](https://kyberswap.com)             | DEX Aggregator    | EVM chain swaps                           |

***

## Cross-Chain vs Same-Chain

| Type            | Example                | Speed                          |
| --------------- | ---------------------- | ------------------------------ |
| **Same-chain**  | ETH → USDC on Ethereum | Fast, single transaction       |
| **Cross-chain** | BTC → ETH              | Depends on blockchain finality |

Cross-chain swaps use THORChain or Maya Protocol. Large swaps are automatically streamed for better rates.

***

## Tips

* **Compare quotes** — Vultisig shows the best available rate
* **Check slippage** — larger swaps may have higher slippage
* **Streaming swaps** — large amounts are split for better execution
* **Transaction fees** are shown before confirmation

***

## Related

* [Keysign](/security-and-technology/keysign) — How transaction signing works
* [Sending](/app-guide/wallet/sending)
* [DeFi](/app-guide/defi)


# DeFi

Vultisig DeFi tab: stake, bond, and provide liquidity across THORChain, Maya, and more. Access DeFi directly from your vault without external dApps.

The DeFi tab provides direct access to decentralized finance protocols. Users can stake tokens, bond to nodes, provide liquidity, and earn yield—all without connecting to external dApps or leaving the secure Vultisig environment.

***

## Overview

The DeFi tab displays a portfolio view of all DeFi positions across supported chains, including:

* Total DeFi balance (aggregated across all positions)
* Active positions by chain
* Available actions for each protocol

***

## In the DeFi Tab

| Protocol                                  | Features                                       |
| ----------------------------------------- | ---------------------------------------------- |
| [Circle Protocol](/app-guide/defi/circle) | USDC yield accounts                            |
| [THORChain](/app-guide/defi/thorchain)    | Bond, stake (RUNE, TCY, RUJI), liquidity pools |
| [MayaChain](/app-guide/defi/maya)         | Bond, stake (CACAO), liquidity pools           |
| [TRON](/app-guide/defi/tron)              | Freeze / Unfreeze (bandwidth & energy)         |

***

## Via Wallet → Functions

Some chain-specific actions are accessed through the **Functions** button on the respective chain in the **Wallet tab**, not the DeFi tab.

| Chain                                  | Features                                                |
| -------------------------------------- | ------------------------------------------------------- |
| [Cosmos (IBC)](/app-guide/defi/cosmos) | IBC Transfer, Switch (→ THORChain), Custom transactions |
| [TON](/app-guide/defi/ton)             | Stake / Unstake                                         |
| [dYdX](/app-guide/defi/dydx)           | Governance voting                                       |

{% hint style="info" %}
**More DeFi integrations coming.** Vultisig is continuously expanding DeFi support. Additional chains and protocols will be added in future updates.
{% endhint %}

***

## Position Types

The DeFi tab organizes positions into three categories:

### Bond

Bonding assets to network nodes. Available on THORChain and MayaChain. Bonded assets contribute to network security and earn rewards.

### Stake

Staking tokens to earn passive income from protocol fees. Different assets are available depending on the chain.

### Liquidity Pools

Providing liquidity to trading pairs. Liquidity providers earn fees from swaps that use their pools.

***

## Navigation

1. **Open the DeFi tab** from the bottom navigation bar
2. **View portfolio overview** — total balance and positions
3. **Select a chain** to see available actions
4. **Choose position type** — Bond, Stake, or LPs
5. **Execute transactions** using standard Vultisig signing

***

## Customization

Users can customize which chains and position types appear in the DeFi tab:

* **Chain visibility**: Show/hide specific chains
* **Position filters**: Focus on Bond, Stake, or LP positions
* **Search**: Find specific chains or assets

***

## Security

All DeFi transactions use the same threshold signature security as standard Vultisig transactions. No external wallet connections or seed phrase exposure is required.

***

## Chain Guides

{% content-ref url="/pages/iEkWA6QWeVKiJ2bt30pf" %}
[Circle Protocol](/app-guide/defi/circle)
{% endcontent-ref %}

{% content-ref url="/pages/1e9jc5sLgKHFTkW8x4lM" %}
[THORChain](/app-guide/defi/thorchain)
{% endcontent-ref %}

{% content-ref url="/pages/kFSCSVx59DvTCHFP5qdH" %}
[MayaChain](/app-guide/defi/maya)
{% endcontent-ref %}

{% content-ref url="/pages/Xim3o0pZf7ERhlZuXFUF" %}
[TRON](/app-guide/defi/tron)
{% endcontent-ref %}

{% content-ref url="/pages/Cp6iHiIIlz97hO1lO3xx" %}
[Cosmos (IBC)](/app-guide/defi/cosmos)
{% endcontent-ref %}

{% content-ref url="/pages/Js66VSMW06EDpJ3eicfz" %}
[TON](/app-guide/defi/ton)
{% endcontent-ref %}

{% content-ref url="/pages/RqNWkFq2cj4odvrP67Pv" %}
[dYdX](/app-guide/defi/dydx)
{% endcontent-ref %}


# Circle Protocol

Circle Protocol in Vultisig: USDC yield accounts with institutional-grade returns. Deposit and withdraw directly from the DeFi tab.

Circle Protocol integration allows users to earn yield on USDC holdings directly from the Vultisig DeFi tab.

***

## Overview

Circle Protocol provides stablecoin yield through a USDC yield account. Users can deposit USDC and earn passive returns while maintaining self-custody through Vultisig's threshold signature security.

***

## Features

| Action        | Description                           |
| ------------- | ------------------------------------- |
| **Deposit**   | Add USDC to the yield account         |
| **Withdraw**  | Remove USDC from the yield account    |
| **Dashboard** | View current balance and earned yield |

***

## How to Deposit

1. Open the **DeFi tab**
2. Select **Circle Protocol**
3. If first time: **Create an account** by following the on-screen prompts
4. Tap **Deposit**
5. Enter the amount of USDC
6. Review the transaction details
7. Sign with your threshold of devices
8. Deposit confirms after transaction finality

***

## How to Withdraw

1. Open the **DeFi tab**
2. Select **Circle Protocol**
3. Tap **Withdraw**
4. Enter the amount to withdraw
5. Review the transaction details
6. Sign with your threshold of devices
7. USDC returns to your vault

***

## Notes

{% hint style="info" %}
Circle Protocol yield rates are determined by market conditions. Check the dashboard for current rates.
{% endhint %}

***

## Related

* [DeFi Overview](/app-guide/defi)
* [THORChain](/app-guide/defi/thorchain)


# THORChain

THORChain DeFi in Vultisig: bond to nodes, stake RUNE/TCY/RUJI, and provide liquidity. Access all THORChain features directly from your vault.

THORChain is a decentralized cross-chain liquidity protocol. Vultisig provides direct access to THORChain's DeFi features from the DeFi tab.

***

## Available Actions

| Action    | Asset                  | Description                    |
| --------- | ---------------------- | ------------------------------ |
| Bond      | RUNE                   | Bond to THORChain nodes        |
| Unbond    | RUNE                   | Remove bond from nodes         |
| Stake     | RUNE, TCY, yRUNE, yTCY | Stake tokens for protocol fees |
| Unstake   | RUNE, TCY, yRUNE, yTCY | Remove staked tokens           |
| Add LP    | Various pairs          | Provide liquidity to pools     |
| Remove LP | Various pairs          | Withdraw liquidity             |
| Custom    | —                      | Advanced memo transactions     |

***

## Bond / Unbond

Bonding RUNE to THORChain nodes supports network security and earns rewards.

### How to Bond

1. Open **DeFi tab** → **THORChain** → **Bond**
2. Enter the **node address** (must have whitelisted your address)
3. Enter the **RUNE amount** to bond
4. (Optional) Specify provider and operator fee
5. Sign with your devices

{% hint style="info" %}
Bonding is an advanced feature. Only use if you are in direct contact with a node operator who has whitelisted your address.
{% endhint %}

### How to Unbond

1. Open **DeFi tab** → **THORChain** → **Unbond**
2. Enter the **node address**
3. Enter the **RUNE amount** to unbond
4. (Optional) Specify provider
5. Sign with your devices

### Leave

The "Leave" function is for node operators who wish to exit or disable a node. See [THORChain documentation](https://docs.thorchain.org/thornodes/leaving#leaving) for details.

***

## Staking

Stake tokens to earn passive income from THORChain protocol fees.

### Available Staking Assets

| Asset     | Description            |
| --------- | ---------------------- |
| **RUNE**  | Native THORChain token |
| **TCY**   | THORChain yield token  |
| **yRUNE** | Yield-bearing RUNE     |
| **yTCY**  | Yield-bearing TCY      |
| **RUJI**  | RUJIRA ecosystem token |

### How to Stake/Unstake RUNE

1. Open **DeFi tab** → **THORChain** → **Stake**
2. Select **RUNE**
3. Enter the amount to stake or unstake
4. Sign with your devices

### How to Stake/Unstake TCY

1. Open **DeFi tab** → **THORChain** → **Stake**
2. Select **TCY**
3. Enter the amount to stake or unstake
4. Sign with your devices

### How to Stake/Unstake yRUNE

1. Open **DeFi tab** → **THORChain** → **Stake**
2. Select **yRUNE**
3. Enter the amount to stake or unstake
4. Sign with your devices

{% hint style="info" %}
yRUNE is a yield-bearing version of RUNE. Staking yRUNE allows users to earn additional protocol fees.
{% endhint %}

### How to Stake/Unstake yTCY

1. Open **DeFi tab** → **THORChain** → **Stake**
2. Select **yTCY**
3. Enter the amount to stake or unstake
4. Sign with your devices

{% hint style="info" %}
yTCY is a yield-bearing version of TCY. Staking yTCY allows users to earn additional protocol fees.
{% endhint %}

### How to Stake/Unstake RUJI

1. Open **DeFi tab** → **THORChain** → **Stake**
2. Select **RUJI**
3. Enter the amount to stake or unstake
4. Sign with your devices

{% hint style="success" %}
For details on RUJI tokenomics, see the [RUJIRA documentation](https://docs.rujira.network/understanding-ruji-token).
{% endhint %}

***

## RUJI Merge

Users can merge eligible THORChain tokens into RUJI.

### Merge Tokens

1. Open **DeFi tab** → **THORChain** → **Merge RUJI**
2. Select the **token to merge**
3. Enter the **amount**
4. Sign with your devices

### Withdraw Merged RUJI

After merging, withdraw RUJI from the merge contract:

1. Open **DeFi tab** → **THORChain** → **Withdraw RUJI**
2. Select the **token**
3. Enter the **amount of shares**
4. Sign with your devices

### Withdraw RUJI Rewards

Staked RUJI accumulates USDC rewards. To withdraw:

1. Open **DeFi tab** → **THORChain** → **Withdraw RUJI Rewards**
2. Enter the **USDC amount** to withdraw
3. Sign with your devices

***

## Liquidity Pools

Provide liquidity to THORChain trading pairs and earn swap fees.

### How to Add Liquidity

1. Open **DeFi tab** → **THORChain** → **LPs**
2. Select a **trading pair**
3. Enter the **amount** to provide
4. Sign with your devices

### How to Remove Liquidity

1. Open **DeFi tab** → **THORChain** → **LPs**
2. Select your **active position**
3. Enter the **amount** to withdraw
4. Sign with your devices

***

## Custom Transactions

Advanced users can create custom memo transactions to interact with the THORChain ecosystem.

{% hint style="warning" %}
Custom transactions are for advanced users only. Incorrect memos can result in errors or loss of funds.
{% endhint %}

***

## Related

* [DeFi Overview](/app-guide/defi)
* [MayaChain](/app-guide/defi/maya)
* [THORChain Docs](https://docs.thorchain.org/)


# MayaChain

MayaChain DeFi in Vultisig: bond to nodes, stake CACAO, and provide liquidity. Access MayaChain features directly from your vault.

MayaChain (MAYA Protocol) is a cross-chain liquidity protocol with extended asset support. Vultisig provides direct access to MayaChain's DeFi features from the DeFi tab.

***

## Available Actions

| Action    | Asset         | Description                      |
| --------- | ------------- | -------------------------------- |
| Bond      | LP Units      | Bond liquidity to Maya nodes     |
| Unbond    | LP Units      | Remove bond from nodes           |
| Stake     | CACAO         | Stake CACAO for protocol fees    |
| Unstake   | CACAO         | Remove staked CACAO              |
| Add LP    | Various pairs | Provide liquidity to CACAO pools |
| Remove LP | Various pairs | Withdraw liquidity               |
| Custom    | —             | Advanced memo transactions       |

***

## Bond / Unbond

Bond liquidity pool units to MayaChain nodes to support network security and earn rewards.

### How to Bond

1. Open **DeFi tab** → **MayaChain** → **Bond**
2. Enter the **node address** (must have whitelisted your address)
3. Select the **asset to bond**
4. Enter the **LP Units amount**
5. Sign with your devices

{% hint style="info" %}
Bonding is an advanced feature. Only use if you are in direct contact with a node operator.
{% endhint %}

### How to Unbond

1. Open **DeFi tab** → **MayaChain** → **Unbond**
2. Enter the **node address**
3. Select the **asset to unbond**
4. Enter the **LP Units amount**
5. Sign with your devices

### Leave

The "Leave" function is for node operators who wish to exit or disable a node. See [MayaChain documentation](https://docs.mayaprotocol.com/node-docs/mayanodes/leaving) for details.

***

## CACAO Pool

### Add to CACAO Pool

Provide liquidity to CACAO pools:

1. Open **DeFi tab** → **MayaChain** → **Add to CACAOPool**
2. Enter the amount
3. Sign with your devices

### Remove from CACAO Pool

Withdraw liquidity from CACAO pools:

1. Open **DeFi tab** → **MayaChain** → **Remove from CACAOPool**
2. Enter the amount to withdraw
3. Sign with your devices

***

## Liquidity Pools

Provide liquidity to MayaChain trading pairs and earn swap fees.

### How to Add Liquidity

1. Open **DeFi tab** → **MayaChain** → **LPs**
2. Select a **trading pair**
3. Enter the **amount** to provide
4. Sign with your devices

### How to Remove Liquidity

1. Open **DeFi tab** → **MayaChain** → **LPs**
2. Select your **active position**
3. Enter the **amount** to withdraw
4. Sign with your devices

***

## Related

* [DeFi Overview](/app-guide/defi)
* [THORChain](/app-guide/defi/thorchain)
* [MayaChain Docs](https://docs.mayaprotocol.com/)


# TRON

TRON freeze and unfreeze in Vultisig: freeze TRX to earn bandwidth or energy for fee-free transactions, and unfreeze to reclaim your TRX.

Vultisig supports native TRON freezing directly in the DeFi tab. Freeze TRX to earn **bandwidth** (for regular transfers) or **energy** (for smart contract interactions), then unfreeze when you want your TRX back.

***

## Available Actions

| Action   | Description                                                           |
| -------- | --------------------------------------------------------------------- |
| Freeze   | Lock TRX to earn bandwidth or energy                                  |
| Unfreeze | Release frozen TRX (3-day cooldown before it returns to your balance) |

***

## Why Freeze TRX?

Freezing TRX gives you free resources on the TRON network:

* **Bandwidth** — pays for standard transactions like TRX and TRC-10 transfers without burning TRX for fees.
* **Energy** — pays for smart contract execution, including TRC-20 transfers (e.g. USDT).

Frozen TRX is not lost. You keep ownership of every token you freeze — you just lock it in exchange for resources. Unfreezing returns it to your balance after the cooldown.

***

## TRON Dashboard

The TRON screen in the DeFi tab shows:

* **Available balance** — unlocked TRX you can send or freeze
* **Frozen balance** — TRX currently earning bandwidth or energy, broken down by resource type
* **Bandwidth and energy meters** — how much you have and how much you've used
* **Pending withdrawals** — TRX you've unfrozen, with a countdown until it returns to your available balance

***

## Freezing

### How to Freeze

1. Open **DeFi tab** → **TRON** → **Freeze**
2. Choose the **resource type**: Bandwidth or Energy
3. Enter the **amount** of TRX to freeze
4. Sign with your devices

Your bandwidth or energy allowance increases as soon as the transaction confirms.

***

## Unfreezing

### How to Unfreeze

1. Open **DeFi tab** → **TRON** → **Unfreeze**
2. Select the **resource type** to unfreeze (Bandwidth or Energy)
3. Enter the **amount** to unfreeze
4. Sign with your devices

{% hint style="info" %}
**3-day cooldown.** After you unfreeze, your TRX enters a 3-day waiting period. You can see each pending withdrawal with its remaining time in the dashboard. Once the timer ends, the TRX returns to your available balance automatically — no separate claim step is needed.
{% endhint %}

***

## Related

* [DeFi Overview](/app-guide/defi)
* [TRON Documentation](https://developers.tron.network/docs/resource-model)


# Cosmos (IBC)

Cosmos IBC in Vultisig: transfer assets between IBC-enabled chains, switch assets to THORChain, and execute custom transactions.

{% hint style="info" %}
**Accessed via Wallet tab**

Cosmos IBC features are available through the **Functions** button on each Cosmos chain in the **Wallet tab**, not the DeFi tab.
{% endhint %}

Vultisig supports IBC (Inter-Blockchain Communication) transfers for Cosmos ecosystem chains. Users can move assets between IBC-enabled chains and execute custom transactions.

***

## Supported Chains

| Chain          | Features                     |
| -------------- | ---------------------------- |
| **Cosmos Hub** | IBC Transfer, Switch, Custom |
| **Kujira**     | IBC Transfer, Custom         |
| **Osmosis**    | IBC Transfer, Custom         |

***

## IBC Transfer

Transfer assets between IBC-enabled Cosmos chains.

### How to Transfer

1. Open **Wallet tab** → Select chain (Cosmos/Kujira/Osmosis)
2. Tap **Functions** → **IBC Transfer**
3. Enter the **destination chain**
4. Enter the **destination address**
5. Enter the **amount**
6. (Optional) Add a memo
7. Sign with your devices

***

## Switch (Cosmos Hub)

The Switch function transfers assets from Cosmos Hub to THORChain. This is part of the RUJIRA token migration flow.

### How to Switch

1. Open **Wallet tab** → **Cosmos** → **Functions** → **Switch**
2. Select the **asset to switch**
3. Enter the **amount**
4. Sign with your devices

{% hint style="info" %}
For details on the Switch function and RUJI merge, see the [RUJIRA documentation](https://docs.rujira.network/understanding-ruji-token#merge-flow).
{% endhint %}

***

## Custom Transactions

Advanced users can create custom memo transactions to interact with each Cosmos chain's ecosystem.

### How to Execute Custom Transaction

1. Open **Wallet tab** → Select chain
2. Tap **Functions** → **Custom**
3. Enter the **memo** according to chain specifications
4. Sign with your devices

{% hint style="warning" %}
Custom transactions are for advanced users only. Incorrect memos can result in errors or loss of funds.
{% endhint %}

***

## Related

* [DeFi Overview](/app-guide/defi)
* [THORChain](/app-guide/defi/thorchain)


# TON

TON staking in Vultisig: stake and unstake TON directly from the DeFi tab. Native staking support with threshold signature security.

{% hint style="info" %}
**Accessed via Wallet tab**

TON staking is available through the **Functions** button on the TON chain in the **Wallet tab**, not the DeFi tab.
{% endhint %}

Vultisig supports native TON staking. Users can stake TON to validators and earn rewards.

***

## Available Actions

| Action  | Description                |
| ------- | -------------------------- |
| Stake   | Stake TON to a validator   |
| Unstake | Remove staked TON          |
| Custom  | Advanced memo transactions |

***

## Staking

### How to Stake

1. Open **Wallet tab** → **TON** → **Functions** → **Stake**
2. Select a **validator** (or use the prefilled default)
3. Enter the **amount** to stake
4. Sign with your devices

### How to Unstake

1. Open **Wallet tab** → **TON** → **Functions** → **Unstake**
2. Enter the **amount** to unstake
3. Sign with your devices

{% hint style="info" %}
Unstaking may have a cooldown period depending on the validator. Check validator terms before staking.
{% endhint %}

***

## Custom Transactions

Advanced users can create custom memo transactions to interact with the TON ecosystem.

{% hint style="warning" %}
Custom transactions are for advanced users only.
{% endhint %}

***

## Related

* [DeFi Overview](/app-guide/defi)


# dYdX

dYdX governance in Vultisig: vote on proposals directly from the DeFi tab. Participate in protocol governance with threshold signature security.

{% hint style="info" %}
**Accessed via Wallet tab**

dYdX governance is available through the **Functions** button on the dYdX chain in the **Wallet tab**, not the DeFi tab.
{% endhint %}

Vultisig supports dYdX governance participation. Users can vote on dYdX proposals.

***

## Available Actions

| Action | Description                  |
| ------ | ---------------------------- |
| Vote   | Vote on governance proposals |
| Custom | Advanced memo transactions   |

***

## Voting

### How to Vote

1. Open **Wallet tab** → **dYdX** → **Functions** → **Vote**
2. Enter the **Proposal ID**
3. Select your **vote** (Yes/No/Abstain)
4. Sign with your devices

{% hint style="info" %}
To participate in governance, you must hold DYDX tokens in your vault.
{% endhint %}

***

## Custom Transactions

Advanced users can create custom memo transactions to interact with the dYdX ecosystem.

{% hint style="warning" %}
Custom transactions are for advanced users only.
{% endhint %}

***

## Related

* [DeFi Overview](/app-guide/defi)
* [dYdX Documentation](https://docs.dydx.exchange/)


# Vault Management

Manage your Vultisig vault: backup, rename, view details, reshare keys, and upgrade security. Complete guide to vault maintenance.

Vault management options are available in the Settings menu. These features allow users to maintain, backup, and modify their vault configuration.

<figure><img src="/files/rhIVrtCrhdOcNIrapSPa" alt=""><figcaption></figcaption></figure>

***

## Management Options

| Feature                                                    | Description                          |
| ---------------------------------------------------------- | ------------------------------------ |
| [Vault Details](/app-guide/vault-management/vault-details) | View signing parties and public keys |
| [Vault Backup](/app-guide/vault-management/vault-backup)   | Export vault shares for recovery     |
| [Vault Rename](/app-guide/vault-management/vault-rename)   | Change the local vault name          |
| [Vault Reshare](/app-guide/vault-management/vault-reshare) | Add or remove devices                |
| [Vault QR](/app-guide/vault-management/vault-qr)           | Export public keys for sharing       |
| [Vault Upgrade](/app-guide/vault-management/vault-upgrade) | Upgrade from GG20 to DKLS23          |

***

## Vault Backup Verification

{% hint style="info" %}
**Verify your backups exist** — ensure you have backed up all vault shares at least once. After initial backup, you only need to create new backups after a [reshare operation](/app-guide/vault-management/vault-reshare). See [Backup & Recovery](/getting-started/backup-recovery) for best practices.
{% endhint %}

***

## Related

* [Backup & Recovery](/getting-started/backup-recovery) - Essential backup guide
* [Creating a Vault](/app-guide/creating-a-vault) - Vault setup options


# Vault Details

View vault details: signing parties, ECDSA and EdDSA public keys, and vault configuration. Verify your multi-device setup at a glance.

The Vault Details screen displays technical information about the current vault configuration.

<figure><img src="/files/gdwZjnrXXcmxB6LzizAb" alt="" width="188"><figcaption><p>Vault Details view</p></figcaption></figure>

***

## Information Displayed

| Field          | Description                                               |
| -------------- | --------------------------------------------------------- |
| **Vault Name** | Current name of the vault                                 |
| **Vault Type** | TSS protocol used (GG20 or DKLS23)                        |
| **ECDSA**      | Public key for ECDSA signatures (Bitcoin, Ethereum, etc.) |
| **EdDSA**      | Public key for EdDSA signatures (Solana, Polkadot, etc.)  |
| **M of N**     | Signing threshold and total devices                       |

***

## Signing Parties

The M of N section shows all devices participating in the vault:

* **M** = Number of devices required to sign
* **N** = Total number of devices in the vault

Each device is listed with its identifier for verification.

***

## Related

* [Vault QR](/app-guide/vault-management/vault-qr) - Export public keys
* [Vault Reshare](/app-guide/vault-management/vault-reshare) - Modify device configuration


# Vault Backups

Back up your Vultisig vault shares securely. Export, import, and recover vaults without seed phrases. Essential guide to protecting your assets.

{% hint style="danger" %}
**Vault backups are critical.** Without proper backups, device loss means permanent loss of access to funds.
{% endhint %}

For comprehensive backup instructions, storage recommendations, and recovery procedures, see the [Backup & Recovery Guide](/getting-started/backup-recovery).

***

## Quick Reference

### How to Backup

1. Go to **Settings** → **Vault Settings**
2. Select **Backup**
3. (Optional) Set an encryption password
4. Save the `.vult` file to a secure location
5. **Repeat for every device** in your vault

<figure><img src="/files/Q9rj5O6VoQds7YLa2MnD" alt=""><figcaption><p>Backup in Settings</p></figcaption></figure>

### Video Guide

[![Backup Tutorial](/files/T8ARtfgVx4nJ6n5vYjUz)](https://twitter.com/iceman00008/status/1824686908368412732/video/1)

***

## Key Points

* Each device has a **unique vault share** requiring its own backup
* Vault shares use the `.vult` extension
* **Never store multiple shares in the same location**
* Backups become invalid after [resharing](/app-guide/vault-management/vault-reshare) — create new backups

***

## Complete Guide

{% content-ref url="/pages/Khl5UkSsWOHjrDdmqu49" %}
[Backup & Recovery](/getting-started/backup-recovery)
{% endcontent-ref %}


# Vault Rename

Rename your Vultisig vault for easy identification. Local change only—doesn't affect other paired devices. Quick vault organization.

The rename feature allows changing the display name of a vault on the current device.

<figure><img src="/files/VovdjL4hlvyDb7NmQiYv" alt="" width="188"><figcaption></figcaption></figure>

***

## How to Rename

1. Go to **Settings** → **Vault Settings**
2. Select **Rename**
3. Enter the new name
4. Confirm

***

## Notes

{% hint style="info" %}
Renaming only affects the local device. Other devices in the vault will continue to display the original name.
{% endhint %}

This is useful for:

* Organizing multiple vaults
* Distinguishing between Fast and Secure vaults
* Personal labeling preferences

***

## Related

* [Vault Details](/app-guide/vault-management/vault-details) - View vault information


# Vault Reshare

Reshare vault keys to add or remove devices. Upgrade security without changing addresses or moving funds. Advanced feature for vault management.

{% hint style="danger" %}
**Advanced feature.** Access to funds is at risk if not properly managed.
{% endhint %}

<figure><img src="/files/mqnmyC9kxDJjWF7nTIUI" alt=""><figcaption><p>Reshare in settings</p></figcaption></figure>

***

## What is Resharing?

Resharing modifies the number of devices in a vault without changing wallet addresses or moving funds. This feature enables:

* Adding new devices to increase security
* Removing devices that are no longer needed
* Including Vultiserver in an existing Secure Vault
* Replacing a lost device with a new one

<figure><img src="/files/KWSUZ4N9faPvMFU2lXO4" alt="" width="563"><figcaption></figcaption></figure>

***

## Requirements

{% hint style="info" %}
A threshold majority is **always** required. For a 2-of-3 vault, at least 2 devices must be present.
{% endhint %}

***

## Video Guides

**Resharing from 3-of-4 to 2-of-3:**

[![Reshare 3-of-4](/files/T8ARtfgVx4nJ6n5vYjUz)](https://x.com/iceman00008/status/1958446928271900905/video/1)

**Resharing from 2-of-2 to 2-of-3:**

[![Reshare 2-of-2](/files/T8ARtfgVx4nJ6n5vYjUz)](https://twitter.com/iceman00008/status/1825339005673857356/video/1)

***

## How to Reshare

1. Go to **Settings** → **Vault Settings** → **Reshare**
2. Choose whether to include Vultiserver
3. Start the reshare ceremony on the initiating device
4. Join with other devices (scan QR or use relay)
5. Add new devices or exclude devices as needed
6. Complete the keygen process

<figure><img src="/files/1ZzuL2UeAHoDISBYRN6r" alt="" width="188"><figcaption></figcaption></figure>

***

## Use Cases

### Adding Devices

Join additional devices during the reshare ceremony to increase security:

* 2-of-2 → 2-of-3 (adds backup device)
* 2-of-3 → 3-of-4 (increases threshold)

### Removing Devices

Exclude a device by not joining it in the ceremony:

* 3-of-4 → 2-of-3 (reduces complexity)
* Remove a compromised device

### Replacing Lost Devices

If a device is lost but you have threshold access:

1. Initiate reshare with remaining devices
2. Add the replacement device
3. Complete reshare to issue new shares

***

## Critical Warnings

{% hint style="danger" %}
**Backup immediately after resharing!**

After resharing, all vault shares change. Old backups are NOT compatible with new shares.
{% endhint %}

{% hint style="info" %}
Old vault shares can still sign with each other. Resharing does not invalidate the old set—it creates a new parallel set.
{% endhint %}

***

## Related

* [Vault Backup](/app-guide/vault-management/vault-backup) - Essential after resharing
* [Vault Upgrade](/app-guide/vault-management/vault-upgrade) - Change TSS protocol


# Vault QR

Vault QR code contains root public keys and vault ID. Use for pairing and verification—not a backup. Share safely for view-only access.

The Vault QR is a QR code containing the vault's public information for safe sharing and verification.

<figure><img src="/files/9EaXLtwJsmKkM1OTU17l" alt="" width="188"><figcaption><p>Example Vault QR</p></figcaption></figure>

***

## What's Included

| Data                 | Description               |
| -------------------- | ------------------------- |
| **ECDSA Public Key** | Root key for ECDSA chains |
| **EdDSA Public Key** | Root key for EdDSA chains |
| **Vault UID**        | Unique identifier         |
| **Vault Name**       | Display name              |

***

{% hint style="warning" %}
**The Vault QR is NOT a backup.** It contains only public information and cannot be used to sign transactions or recover funds.
{% endhint %}

***

## How to Export

1. Open the vault home screen
2. Tap the QR icon in the top right corner
3. Save or share the QR code

<figure><img src="/files/Mdpri4QWFtX1pI5RLQQS" alt="" width="188"><figcaption><p>QR export location</p></figcaption></figure>

***

## Use Cases

### Airdrop Registration

The Vault QR can be imported into the [Vultisig Airdrop page](https://airdrop.vultisig.com/) to register for the [$VULT airdrop](/vult-token/airdrop).

### View-Only Access

Share the QR to allow others to view your vault's public addresses without granting signing access.

### Verification

Compare Vault QRs across devices to verify they belong to the same vault.

***

## Related

* [Vault Details](/app-guide/vault-management/vault-details) - View public keys directly
* [Airdrop](/vult-token/airdrop) - VULT token distribution


# Vault Upgrade

Upgrade your Vultisig vault from GG20 to DKLS23 protocol. Faster signing, better security. Same addresses, no fund migration needed.

{% hint style="info" %}
Upgrades are only available for vaults created with the GG20 protocol.
{% endhint %}

***

## What is Upgrading?

Upgrading changes the underlying TSS protocol from GG20 to DKLS23. Benefits include:

* **Faster signing** — improved keygen and signing speed
* **Extension compatibility** — required for [Vultisig Extension](/ecosystem/vultisig-extension)
* **Same addresses** — no need to migrate funds

Technical details are available in the [TSS section](/security-and-technology/overview).

***

## How to Upgrade

The upgrade can be initiated from:

* The banner on the home screen
* **Settings** → **Vault Settings** → **Upgrade**

<div><figure><img src="/files/AXyrl6kmEh3xNjsKXIr0" alt=""><figcaption><p>Settings option</p></figcaption></figure> <figure><img src="/files/8GtTFEfiKc7uPtpFsH6A" alt=""><figcaption><p>Home banner</p></figcaption></figure></div>

### Requirements

* All original devices from vault creation must be present
* This is a full keygen ceremony (similar to creating a new vault)

### Steps

1. Initiate upgrade on one device
2. Join with all other devices
3. Complete the keygen process
4. **Backup all new vault shares immediately**

***

## Backup After Upgrade

{% hint style="warning" %}
New vault shares are created during upgrade. Store them with the same security precautions as original shares.
{% endhint %}

### Distinguishing Backups

| Protocol | File naming                 |
| -------- | --------------------------- |
| GG20     | `vault-xxxx-part1of2.vult`  |
| DKLS23   | `vault-xxxx-share1of2.vult` |

***

## Upgrading Active Vaults

{% hint style="info" %}
Active Vaults are a discontinued feature with a different upgrade procedure.
{% endhint %}

To upgrade an Active Vault:

1. Import the server share onto a third device
2. Initiate upgrade from other devices
3. Join with all three devices
4. Complete upgrade

The result is a standard [Secure Vault](/app-guide/creating-a-vault/secure-vault) without Vultiserver involvement.

{% hint style="info" %}
If Fast signing is still desired, create a new [Fast Vault](/app-guide/creating-a-vault/fast-vault) after upgrading.
{% endhint %}

***

## Related

* [TSS Protocols](/security-and-technology/overview) - Technical details
* [Vultisig Extension](/ecosystem/vultisig-extension) - Requires DKLS23


# Referrals

Earn swap fee rebates with Vultisig referrals. Share your code, get rewards via THORChain nested affiliates. Passive income from your network.

## What are Vultisig Referrals

Vultisig Referrals uses [THORChain Nested Affiliates](https://dev.thorchain.org/affiliate-guide/affiliate-fee-guide.html) to redistribute a portion of swap fees back to users.

<figure><img src="/files/DdWLJRaCaeIhGlsOEGaG" alt="" width="375"><figcaption></figcaption></figure>

## What do Vultisig users gain?

* Users who refer others — *referrers* — earn 10 basis points (0.10%) on each referred swap.
* Users who use a referral code save 5 basis points (0.05%) on each swap.

## How do they work?

When a swap is made, the app creates a memo for the swap on THORChain. This memo includes the user's chosen affiliate and redistributes the fees directly to the affiliate's owner.

## How to manage the Vultisig Referrals

In the Referrals section of the app (Settings → Referral Code), you can:

* Create your own referral code and start earning.
* Enter a friend's code and start saving.
* Edit or change your saved referral code.

{% hint style="info" %}
Note: You can replace your friend's referral code at any time, but cannot leave the field blank once a code has been entered.
{% endhint %}

<figure><img src="/files/fXJz1rzoi5v97ft4URpF" alt=""><figcaption></figcaption></figure>

***

## Related

* [Swapping](/app-guide/wallet/swapping) — Swap tokens using THORChain/Maya
* [THORChain](/app-guide/defi/thorchain) — THORChain DeFi integration


# Overview

How Vultisig security works. Threshold Signature Schemes (TSS), DKLS23 protocol, keysigning process, and cryptographic foundations explained.

Vultisig's security is built on Threshold Signature Schemes (TSS), a form of Multi-Party Computation (MPC) that eliminates single points of failure. This section explains the cryptographic foundations and technical processes that secure your assets.

***

## Core Concepts

### No Private Key Ever Exists

Unlike traditional wallets, Vultisig never constructs a complete private key. Instead, cryptographic operations are performed across distributed vault shares using zero-knowledge proofs. Even during signing, the key remains split—only the signature is assembled.

### Threshold Security

Vultisig uses a `t`-of-`n` threshold model. For a 2-of-3 vault, any 2 devices can sign, but no single device can act alone. This provides both security (no single point of compromise) and redundancy (one device can be lost).

***

## TSS Protocols

Vultisig supports two TSS protocols:

| Protocol                                            | Status  | Signing Rounds | Speed        |
| --------------------------------------------------- | ------- | -------------- | ------------ |
| [GG20](/security-and-technology/how-gg20-works)     | Legacy  | 6 rounds       | Baseline     |
| [DKLS23](/security-and-technology/how-dkls23-works) | Current | 3 rounds       | 5-10x faster |

New vaults use DKLS23 by default. Existing GG20 vaults can be [upgraded](/app-guide/vault-management/vault-upgrade).

***

## Key Operations

| Operation          | Description                            | Guide                                               |
| ------------------ | -------------------------------------- | --------------------------------------------------- |
| **Key Generation** | Creating vault shares across devices   | [TSS Actions](/security-and-technology/tss-actions) |
| **Key Signing**    | Threshold devices signing transactions | [Keysign](/security-and-technology/keysign)         |
| **Re-sharing**     | Adding/removing devices from a vault   | [TSS Actions](/security-and-technology/tss-actions) |

***

## Security Comparisons

Understanding how Vultisig compares to alternative approaches:

* [Difference to Multi-Signatures](/security-and-technology/difference-to-multi-sig) — Why TSS is superior to traditional multi-sig
* [Difference to Passkeys](/security-and-technology/difference-to-passkeys) — Why passkeys aren't suitable for crypto

***

## Emergency Procedures

In the unlikely event that Vultisig software becomes unavailable, vault shares can be recombined to extract a traditional private key:

* [Emergency Recovery](/security-and-technology/emergency-recovery) — Last-resort key extraction

{% hint style="danger" %}
Emergency recovery permanently converts a TSS vault to a single-signature wallet. Only use if Vultisig software is completely unavailable.
{% endhint %}

***

## Technical Deep Dives

{% content-ref url="/pages/hvh5VgnerNSmhqVKROpH" %}
[How DKLS23 Works](/security-and-technology/how-dkls23-works)
{% endcontent-ref %}

{% content-ref url="/pages/RwtjmmA2OjpBtiTJurvx" %}
[How GG20 Works](/security-and-technology/how-gg20-works)
{% endcontent-ref %}

{% content-ref url="/pages/hdg0XuEAf6kdr6axEQfy" %}
[TSS Actions](/security-and-technology/tss-actions)
{% endcontent-ref %}

{% content-ref url="/pages/byreqeVuoXVFweD2bV5v" %}
[Keysign](/security-and-technology/keysign)
{% endcontent-ref %}


# Keysign

How Vultisig keysigning works. Multi-device threshold signing process for Fast Vaults and Secure Vaults. QR pairing, verification, and broadcast.

Keysigning is the process by which threshold devices collaborate to sign a transaction. This page explains how signing works for both Fast Vaults and Secure Vaults.

<figure><img src="/files/3Da2gNoacHOGfTqw3nVu" alt="" width="375"><figcaption></figcaption></figure>

***

## How It Works

<figure><img src="/files/SgDUjsM5wyxVTD3IVF9K" alt=""><figcaption><p>Transaction signing flowchart</p></figcaption></figure>

### Session Initiation

A device initiates a cryptographic session to sign a transaction. It transforms user input into the transaction payload while acting as the session host. The initiating device sends session metadata (including session ID) to the Vultisig relay server or broadcasts it over the local network. A QR code is generated containing session-specific details for pairing devices.

### Device Pairing

Pairing devices scan the QR code to join the session using the embedded session ID and encrypted hex chain code. The initiating device monitors joining devices and initiates the keysigning ceremony when the required threshold is reached.

### Signing Ceremony

During the keysigning ceremony, participating devices jointly sign the transaction using threshold signature cryptography. No single device ever has access to the complete private key—only the final signature is assembled.

### Broadcast

Upon successful completion, the initiating device propagates the signed transaction to the blockchain and distributes the transaction hash to other participating devices for verification.

***

## Fast Vault Signing

Fast Vaults provide a single-device signing experience with the Vultiserver as the automatic co-signer.

### Steps

1. Prepare the transaction (Send or Swap)
2. Tap **Continue** or **Swap**

<div><figure><img src="/files/0UHOWJ0zqgmLEBgToNNv" alt="" width="188"><figcaption><p>Send screen</p></figcaption></figure> <figure><img src="/files/BnTCa4ZoNglh92M9Tb9A" alt="" width="188"><figcaption><p>Swap screen</p></figcaption></figure></div>

3. Verify transaction details

<div><figure><img src="/files/fkCIwRf5rIJOiowsFtmv" alt="" width="188"><figcaption><p>Send verification</p></figcaption></figure> <figure><img src="/files/yjapD3m1YxhVLX2r2aXl" alt="" width="188"><figcaption><p>Swap verification</p></figcaption></figure></div>

4. Enter your password
5. Wait for signing to complete

<figure><img src="/files/imb2VR7KOXodO4lu2uyK" alt="" width="188"><figcaption></figcaption></figure>

***

## Secure Vault Signing

Secure Vaults require threshold devices to physically participate in signing.

### Video Guide

[![Signing Tutorial](/files/T8ARtfgVx4nJ6n5vYjUz)](https://twitter.com/iceman00008/status/1824690627843592573/video/1)

### Preparation

Depending on your vault configuration (2-of-2, 2-of-3, 3-of-4, or m-of-n), have the threshold number of devices ready.

{% hint style="info" %}
One device creates the transaction, other devices verify and co-sign. Both devices will co-sign but only one transaction is sent—no duplicates.
{% endhint %}

### On the Main Device

1. Prepare the transaction (Send, Swap, or DeFi action)
2. Tap **Continue** or **Swap**

<div><figure><img src="/files/0UHOWJ0zqgmLEBgToNNv" alt="" width="188"><figcaption><p>Send screen</p></figcaption></figure> <figure><img src="/files/BnTCa4ZoNglh92M9Tb9A" alt="" width="188"><figcaption><p>Swap screen</p></figcaption></figure></div>

3. Verify all details on the confirmation screen
4. Check reminder boxes and tap **Sign**

<div><figure><img src="/files/eD0QaG9RCrec8XKCgR2D" alt="" width="188"><figcaption></figcaption></figure> <figure><img src="/files/yjapD3m1YxhVLX2r2aXl" alt="" width="188"><figcaption></figcaption></figure></div>

5. A QR code will appear

{% hint style="info" %}
Select **Local mode** to sign without using the Vultisig relay server (requires same WiFi network).
{% endhint %}

<figure><img src="/files/P0riRSo6wOoYWb7zHWJq" alt="" width="188"><figcaption></figcaption></figure>

### On the Pair Device(s)

1. Select the same vault
2. Tap the **Camera** icon
3. Scan the QR code from the main device

<figure><img src="/files/wOkDpzAIdVUKV8sDa4L4" alt="" width="188"><figcaption></figcaption></figure>

4. Verify transaction details match
5. Tap **Join key sign**

<div><figure><img src="/files/fkCIwRf5rIJOiowsFtmv" alt="" width="188"><figcaption></figcaption></figure> <figure><img src="/files/yKXLYwJfAM1Aa4yr6v62" alt="" width="188"><figcaption></figcaption></figure></div>

### Completion

Signing starts automatically when the threshold of devices has joined. The transaction signs and broadcasts from one of the devices.

<figure><img src="/files/HV1IwB0ZwFMcxHPfp8te" alt="" width="188"><figcaption></figcaption></figure>

***

## Network Modes

| Mode         | Description               | Use Case                      |
| ------------ | ------------------------- | ----------------------------- |
| **Internet** | Via Vultisig relay server | Devices on different networks |
| **Local**    | Via local WiFi (mDNS)     | Same network, maximum privacy |

***

## Related

* [TSS Actions](/security-and-technology/tss-actions) — Key generation, signing, resharing
* [Sending](/app-guide/wallet/sending) — How to send transactions
* [Swapping](/app-guide/wallet/swapping) — How to swap assets


# TSS Actions

TSS operations explained: Key Generation (vault creation), Key Signing (transactions), and Resharing (device changes). Core MPC actions.

Vultisig's Threshold Signature Scheme supports three core operations:

1. Key Generation
2. Key Signing
3. Re-Sharing

***

## Key Generation

Key generation (keygen) is the process by which devices prove access to a secret and generate a shared public key. This requires 100% of devices to be online.

The shared public key creates on-chain addresses (the "vault") for receiving funds. These addresses resemble simple wallet addresses (externally-owned accounts) and do not appear as special contracts or scripts.

{% hint style="success" %}
**Important:** Individual vault shares do not contain funds. The actual private key never exists in normal operation. Vault shares can be safely stored, emailed, or uploaded—they reveal nothing about the vault's location or contents.
{% endhint %}

{% hint style="danger" %}
**Never store multiple vault shares together.** A malicious party with enough shares could recombine them to access the vault:

1. Do not back up more than one vault share to the same device, email, or cloud storage
2. Do not upload more than one vault share to the same website

Following these guidelines prevents unauthorized vault access.
{% endhint %}

***

## Key Signing

Key signing is the process where a threshold of parties (67% minimum) collaborate to prove access to a secret and generate a signed transaction.

For a 2-of-3 vault, only 2 of 3 devices need to participate. This ensures the signing process remains secure and efficient while maintaining vault integrity.

The signing process:

1. Initiating device creates transaction payload
2. Threshold devices join via QR code or relay
3. Devices jointly compute signature shares
4. Signature is assembled and transaction broadcasts

See [Keysign](/security-and-technology/keysign) for detailed signing procedures.

***

## Re-share

Re-sharing allows the vault configuration to adapt by replacing devices or modifying the threshold.

Use cases:

* **Adding devices**: Upgrade from 2-of-2 to 2-of-3 or 3-of-4
* **Removing devices**: Exclude a lost or compromised device
* **Replacing devices**: Substitute a non-responsive device with a new one

{% hint style="info" %}
Re-sharing requires the current signing threshold. For a 2-of-3 vault, at least 2 devices must participate in the reshare ceremony.
{% endhint %}

{% hint style="warning" %}
After resharing, all vault shares change. Old backups are NOT compatible with new shares. Always backup immediately after resharing.
{% endhint %}

See [Vault Reshare](/app-guide/vault-management/vault-reshare) for step-by-step instructions.

***

## Related

* [Keysign](/security-and-technology/keysign) — Detailed signing process
* [Vault Reshare](/app-guide/vault-management/vault-reshare) — How to reshare
* [How DKLS23 Works](/security-and-technology/how-dkls23-works) — Technical protocol details


# How GG20 Works

GG20 threshold signature protocol explained. How Vultisig's legacy TSS works: secret sharing, MPC signing rounds, and security model.

## Concept

The Threshold Signature Scheme (TSS) is part of the broader field of Multi-Party Computation (MPC) and has evolved significantly over the past few decades. The concept of secret sharing was originally introduced by Adi Shamir in 1979, with threshold signatures developing as an extension of this foundational work.

In 2018, [the "GG18" paper by Gennaro-Goldfeder](https://eprint.iacr.org/2019/114.pdf) introduced significant advancements, simplifying and enhancing the efficiency of TSS. This was further improved in 2020 with the ["GG20" paper](https://eprint.iacr.org/2020/540), which introduced "identifiable abort"—the ability to identify which party caused a protocol failure.

Vultisig utilizes this improved version of TSS, implemented in a comprehensive [library from Binance](https://github.com/bnb-chain/tss-lib) and thoroughly tested in production by THORChain.

GG20 TSS integrates Homomorphic Secret Sharing, Zero Knowledge Proofs, and Multi-Party Computation (MPC) to securely sign transactions without revealing sensitive information.

{% hint style="info" %}
For an excellent summary of MPC protocol history: <https://www.cryptologie.net/article/605/whats-out-there-for-ecdsa-threshold-signatures/>
{% endhint %}

***

## Homomorphic Secret Sharing

The homomorphic secret sharing employed by Vultisig is founded on the Paillier encryption scheme, introduced by Pascal Paillier in 1999. This additive homomorphic encryption method allows ciphertexts to be combined through mathematical addition, enabling secure computations on encrypted data.

{% hint style="info" %}
Homomorphic encryption preserves the structure of data, allowing mathematical operations on encrypted objects without altering their underlying integrity.
{% endhint %}

In GG20, Paillier encryption plays a crucial role in the Multiplicative-to-Additive (MtA) conversion process, essential for threshold ECDSA signatures. This allows parties to securely compute the product of their secret values without revealing those values.

***

## Zero Knowledge Proof

Zero Knowledge Proof (ZKP) enables a proving entity to convince a verifying entity that a statement is true without disclosing additional information.

Key properties of ZKPs:

* **Zero-Knowledge**: The verifier learns nothing beyond the statement's truth
* **Soundness**: Computationally infeasible to prove false statements
* **Completeness**: True statements can be proven with high probability

In GG20, multiple zero-knowledge proofs verify that participants follow the protocol correctly, including proofs of knowledge for discrete logarithms and range proofs to ensure values are within appropriate bounds.

***

## Multi-Party Computation (MPC)

MPC enables secure computation even with potentially dishonest participants. Functions are computed on secret shares without revealing those shares.

{% hint style="success" %}
The private key is never actually constructed in Vultisig.
{% endhint %}

The GG20 protocol requires 6 rounds of communication between participants to generate a valid signature. This provides "identifiable abort"—if something goes wrong, the system can identify which participant caused the failure.

Since MPC is an offline computation, it offers several advantages:

* The number of shares can be freely set and reconfigured
* On-chain footprint equals a single signature
* Faster and more efficient signing computations

<figure><picture><source srcset="/files/SpCVG9FDIpiA0S05y6w4" media="(prefers-color-scheme: dark)"><img src="/files/juFozoMBXF1z3sUGdN0h" alt="" width="375"></picture><figcaption><p>Signing Transaction</p></figcaption></figure>

***

## Conclusion

GG20 provides a robust security framework with features like identifiable abort. While it requires 6 communication rounds and involves computationally intensive operations, it offers strong security guarantees when properly implemented.

***

## References

1. Gennaro, R., & Goldfeder, S. (2020). ["One Round Threshold ECDSA with Identifiable Abort."](https://eprint.iacr.org/2020/540)
2. Shamir, A. (1979). "How to share a secret." Communications of the ACM, 22(11), 612-613.
3. Paillier, P. (1999). "Public-key cryptosystems based on composite degree residuosity classes."


# How DKLS23 Works

DKLS23 protocol deep-dive. Vultisig's modern TSS: faster signing, fewer rounds, improved security. Developed with Silence Laboratories.

## Evolution and Innovation

The [DKLS23 protocol](https://eprint.iacr.org/2023/765), introduced in 2023 by Doerner, Kondi, Lee, and Shelat, represents a significant advancement in threshold ECDSA. Building upon GG18 and GG20, DKLS23 reduces communication rounds from 6 to 3 while maintaining robust security.

This protocol shifts from homomorphic encryption toward more efficient oblivious transfer techniques—simpler to implement correctly with fewer potential vulnerabilities.

DKLS23 integrates Oblivious Transfer, Zero Knowledge Proofs, and Multi-Party Computation (MPC) to create a threshold signature system with exceptional performance.

***

## Three-Round Architecture

The most distinctive feature of DKLS23 is its streamlined three-round signing process—a 50% reduction from GG20.

### Round 1: Commitment Phase

* Participants generate and exchange commitments to secret values
* Nonce generation and sharing are combined (unlike GG20's separate rounds)
* Uses an intermediate representation of ECDSA signatures

### Round 2: Multiplication Phase

* Secure two-party multiplication via oblivious transfer
* Replaces GG20's computationally intensive MtA conversion
* Statistical consistency checks ensure security

### Round 3: Signature Completion

* Final signature components computed and combined
* Result is indistinguishable from standard ECDSA signature

### Performance Implications

* **Reduced Latency**: Fewer communication rounds
* **Improved Reliability**: Fewer failure points
* **Enhanced Scalability**: Maintains efficiency as participants increase

***

## Oblivious Transfer

While GG20 relies on Paillier's homomorphic encryption, DKLS23 uses oblivious transfer (OT)—a cryptographic primitive offering significant efficiency advantages.

### Understanding Oblivious Transfer

In 1-out-of-2 OT, a sender transfers one of two messages to a receiver without learning which was chosen. This enables secure two-party computation without revealing private inputs.

### OT Extensions

OT extensions allow many OT instances from a small number of base OTs. DKLS23 leverages these for a two-round vectorized multiplication protocol, eliminating computationally intensive homomorphic operations.

### Efficiency Advantages

* **Computational Efficiency**: OT operations faster than Paillier encryption
* **Reduced Bandwidth**: Smaller message sizes
* **Better Parallelization**: More opportunities for parallel computation

***

## Statistical Security Measures

DKLS23 uses statistical consistency checks rather than complex zero-knowledge proofs:

* **Commitment Schemes**: Prevent input changes after seeing others' values
* **Statistical Checks**: Verify consistent behavior throughout protocol
* **Simplified ZKPs**: Where used, they are simpler and more efficient

### Security Properties

DKLS23 provides information-theoretic UC-security against malicious adversaries with dishonest majority:

* **Reduced Attack Surface**: Fewer cryptographic primitives
* **No Paillier Vulnerabilities**: Not susceptible to "Alpha-Rays Attack"
* **No Early Nonce Leakage**: Protocol design prevents R leakage
* **Simpler Security Proofs**: Fewer assumptions

***

## Why Vultisig Upgraded to DKLS23

In early 2025, Vultisig transitioned to DKLS23 in cooperation with [Silence Laboratories](https://github.com/silence-laboratories/dkls23):

1. **Faster transactions**: Signing in milliseconds rather than seconds
2. **Better reliability**: Fewer rounds mean less chance of network failures
3. **Improved compatibility**: Works efficiently on resource-constrained devices
4. **Enhanced battery life**: Less computational work
5. **WASM Compatibility**: Enables the Vultisig Extension

***

## Comparing the Protocols

| Feature              | GG20           | DKLS23       | User Impact                 |
| -------------------- | -------------- | ------------ | --------------------------- |
| Signing Speed        | Slower         | 5-10x faster | Quicker approvals           |
| Communication Rounds | 6 rounds       | 3 rounds     | Works on spotty connections |
| Security Level       | Very High      | Very High    | Both excellent              |
| Network Reliability  | More sensitive | More robust  | Fewer failed transactions   |

***

## References

* Doerner, J., Kondi, Y., Lee, E., & Shelat, A. (2023). ["Threshold ECDSA in Three Rounds."](https://eprint.iacr.org/2023/765)
* Gennaro, R., & Goldfeder, S. (2020). ["One Round Threshold ECDSA with Identifiable Abort."](https://eprint.iacr.org/2020/540)
* Silence Laboratories. ["Silent Shard's threshold ECDSA signatures implementing DKLS23."](https://github.com/silence-laboratories/dkls23)


# Difference to Multi-Signatures

TSS vs Multi-Sig explained. Why threshold signatures are superior: no private key reconstruction, chain-agnostic, lower fees, better privacy.

The main difference between Threshold Signature Schemes (TSS) and Multi-Signatures (MS) lies in their approach to generating signatures. In TSS, the signature is created by combining vault shares using Zero-Knowledge Proofs—no single private key is ever constructed. In contrast, MS involves multiple private keys, each contributing to the final signature.

***

## Visualization: Threshold Signatures

<div align="center"><figure><picture><source srcset="/files/SpCVG9FDIpiA0S05y6w4" media="(prefers-color-scheme: dark)"><img src="/files/juFozoMBXF1z3sUGdN0h" alt="" width="375"></picture><figcaption><p><strong>Threshold Signatures</strong></p></figcaption></figure></div>

## Visualization: Multi-Signatures

<figure><picture><source srcset="/files/3RW4T26lVXcTcx5XY73u" media="(prefers-color-scheme: dark)"><img src="/files/I2LHBIcb0359Hrz2bN1e" alt="" width="375"></picture><figcaption><p><strong>Multi-Signatures</strong></p></figcaption></figure>

***

## Comparison

| Factor                  | Threshold Signature Scheme                            | Multi-Signature                       |
| ----------------------- | ----------------------------------------------------- | ------------------------------------- |
| **Private Key Storage** | No private key constructed; uses vault shares and ZKP | Multiple private keys held by parties |
| **On-Chain Footprint**  | Single signature on-chain                             | Multiple signatures visible on-chain  |
| **Redundancy**          | High; lost shares can be re-shared                    | Low; lost keys require fund migration |
| **Compatibility**       | Multi-chain: ECDSA and EdDSA                          | Single chain support                  |
| **Flexibility**         | Adjustable thresholds, replaceable devices            | Fixed once created                    |
| **Adding Participants** | Supported                                             | Not supported                         |

***

## Key Advantages of TSS

### No Key Reconstruction

In TSS, the private key never exists in one place. Multi-sig requires each signer to hold a complete private key, creating multiple single points of failure.

### Chain Agnostic

TSS works identically across all blockchains that support standard signatures. Multi-sig implementations vary by chain and often aren't available.

### Lower Fees

TSS produces a single signature regardless of threshold. Multi-sig requires multiple on-chain signatures, increasing transaction fees.

### Better Privacy

TSS transactions appear identical to normal single-signature transactions. Multi-sig transactions expose the signing structure on-chain.

### Flexibility

TSS allows resharing to add/remove devices without changing addresses. Multi-sig typically requires fund migration for any configuration change.

***

## Conclusion

Flexibility and security advantages make TSS the superior approach for managing digital assets compared to traditional multi-signature schemes.

***

## Related

* [How DKLS23 Works](/security-and-technology/how-dkls23-works)
* [TSS Actions](/security-and-technology/tss-actions)


# Difference to Passkeys

TSS vs Passkeys comparison. Why threshold signatures offer better crypto security: multi-device, no single point of failure, true self-custody.

## What is a Passkey?

A passkey is an advanced method for securely storing sensitive data, developed under the FIDO (Fast IDentity Online) Alliance. Initially adopted by Apple, Microsoft, and Google, passkeys are gaining traction as an alternative to traditional passwords.

***

## How Passkeys Work

Passkeys utilize asymmetric cryptography—a private key and public key pair—similar to cryptocurrencies. Keys are generated locally on the user's device using secure hardware modules (TPM or Secure Enclave).

The public key is stored by the application server, while the private key remains on the user's device, protected by biometric authentication.

During authentication:

1. The server generates a cryptographic challenge
2. The device signs the challenge with the private key
3. The server verifies the signature with the stored public key

The private key is never transmitted, maintaining security and privacy.

***

## Why Vultisig Doesn't Use Passkeys

While passkeys are secure for general authentication, they have critical limitations for cryptocurrency custody:

### Centralization Concerns

Although passkey technology is open source, it relies on centralized authentication platforms operated by large corporations. This raises concerns about data collection and transparency.

### Single Point of Failure

The authentication process constitutes a single point of failure. A physical attack on the device holding the private key can lead to complete security compromise.

### Crypto-Specific Limitations

1. **Lack of Multi-Chain Support**: Passkeys aren't designed to operate across multiple blockchain networks
2. **Single Signature Mechanism**: Insufficient security for high-stakes transactions that benefit from multi-factor authentication

***

## Vultisig's Approach

Recognizing these shortcomings, Vultisig developed a solution tailored for cryptocurrency:

1. **Open Source Everything**: Transparency through open-source protocols
2. **Multi-Chain Compatibility**: Seamless interoperability across blockchain networks
3. **Multi-Factor Authentication**: Multiple devices eliminate single points of failure

***

## Comparison

| Factor                      | Passkeys                           | Vultisig TSS                    |
| --------------------------- | ---------------------------------- | ------------------------------- |
| **Single Point of Failure** | Yes (one device)                   | No (distributed across devices) |
| **Multi-Chain**             | No                                 | Yes (30+ chains)                |
| **Self-Custody**            | Partial (corporate infrastructure) | Full (no third parties)         |
| **Device Loss Recovery**    | Dependent on platform              | Threshold redundancy            |
| **Open Source**             | Partial                            | Fully open source               |

***

## Conclusion

While passkeys represent progress in general authentication, they don't meet the security requirements for cryptocurrency custody. Vultisig's threshold signature approach provides the multi-factor, multi-chain, fully self-custodial solution that digital assets require.

***

## Related

* [Security & Technology Overview](/security-and-technology/overview)
* [Difference to Multi-Signatures](/security-and-technology/difference-to-multi-sig)


# Emergency Recovery

Emergency recovery tool for Vultisig vaults. Reconstruct keys if TSS software becomes unavailable. Last-resort fund recovery process.

{% hint style="danger" %}
**Last Resort Only**

Emergency recovery permanently converts a TSS vault to a single-signature wallet. Only use if Vultisig software is completely unavailable.
{% endhint %}

***

## What is the Emergency Recovery Tool?

In Vultisig, the private key never exists during normal operation—this significantly improves security since there's no private key to be extracted or stolen.

However, it is possible to recombine vault shares and generate the private key for use in other wallets. Scripts are provided for this purpose if Vultisig software ever becomes unavailable.

***

## Recommended: Vault Share Decoder

For most users, the community-built **Vault Share Decoder** is the easiest way to recover:

* **Website**: <https://share-decoder.vultisig.com>
* **Repository**: [GitHub](https://github.com/vultisig/community-tools/tree/main/recovery-tools/vultisig-share-decoder)

This tool provides a user-friendly interface to decode vault shares and recover private keys without requiring developer tools.

{% hint style="info" %}
The Vault Share Decoder is the preferred method for emergency recovery. Only use the CLI/Web options below if the community tool is unavailable.
{% endhint %}

***

## Prerequisites

* [Go (Golang)](https://golang.org/dl/) installed on your system
* Access to threshold number of vault shares

***

## Option 1: Web UI Version

1. **Clone the Repository:**

```sh
git clone https://github.com/vultisig/mobile-tss-lib
```

2. **Navigate to the Recovery Web Directory:**

```sh
cd mobile-tss-lib/cmd/recovery-web
```

3. **Run the Web Server:**

```sh
make
```

Access the recovery UI via your web browser.

***

## Option 2: CLI Version

1. **Clone the Repository:**

```sh
git clone https://github.com/vultisig/mobile-tss-lib
```

2. **Navigate to the Recovery CLI Directory:**

```sh
cd mobile-tss-lib/cmd/recovery-cli
```

3. **Run the Recovery CLI Tool:**

```sh
go run main.go
```

Follow the terminal instructions to proceed with recovery.

***

## Supported Assets

{% hint style="danger" %}
Only the following assets are supported: Bitcoin, Bitcoin Cash, Litecoin, Dogecoin, Ethereum, THORChain, MayaChain.

**Warning:** Before using this tool, the private key never existed. This is a one-way function—once the private key is created, the vault is no longer a TSS vault but a single-signature wallet.

Never use a single-signature wallet for significant value again.
{% endhint %}

***

## Resources

* Web UI: <https://github.com/vultisig/mobile-tss-lib/tree/main/cmd/recovery-web>
* CLI: <https://github.com/vultisig/mobile-tss-lib/tree/main/cmd/cli>

***

## Related

* [Backup & Recovery](/getting-started/backup-recovery) — Standard backup procedures
* [TSS Actions](/security-and-technology/tss-actions) — How threshold signatures work


# Vultisig Extension

Vultisig browser extension for Chrome. Connect your vault to DeFi dApps and Web3 sites with MPC security. No seed phrase exposure.

<figure><img src="/files/XIcnJ3k6qSslwemR0xuE" alt="" width="375"><figcaption></figcaption></figure>

## What is Vultisig Extension?

The Vultisig Extension is the browser equivalent of mobile apps, enabling users to access assets stored in their Vultisig Vaults on most available Web3 and DeFi dApps.

With the extension, you can access the full DeFi and Web3 universe while keeping your digital assets completely secure.

It's a secure and efficient way to interact with DeFi on your terms — rest assured that your assets are secure and accessible at any time.


# How to use Vultisig Extension

Install and use the Vultisig Chrome extension. Connect your vault to DeFi dApps step-by-step. Pair devices and sign transactions securely.

## How to install Vultisig Extension

Install Vultisig Extension for your Chrome Browser, over the Chrome Extension Store or directly over [Github](https://github.com/vultisig/vulticonnect)

{% embed url="<https://chromewebstore.google.com/detail/ggafhcdaplkhmmnlbfjpnnkepdfjaelb?utm_source=item-share-cb>" %}

## How to use Vultisig Extension

The extension can be used in the same way as the mobile and desktop apps, and all actions can be read in the [App Guide](/app-guide/overview).


# Web3 support

Supported dApps and Web3 sites for Vultisig Extension. DeFi, NFT marketplaces, and utilities. Native integration or wallet injection fallback.

The Vultisig Extension aims to support all dApps and interfaces where a wallet connection is possible.\
It either is natively integrated or allows connections via other wallet injections if dedicated Vultisig Extension support is unavailable.

As we add more chains supported by the Vultisig Extension, we will also constantly expand connectivity to the whole web3 space.\
\
This it the current list of supported dApps and interfaces:

| Dex/DeFi                                      | NFT Marketplace                     | Utilities                          |
| --------------------------------------------- | ----------------------------------- | ---------------------------------- |
| [Uniswap](https://app.uniswap.org/)           | [OpenSea](https://opensea.io/)      | [Etherscan](https://etherscan.io/) |
| [LeoDex](https://leodex.io/)                  | [Magic Eden](https://magiceden.io/) | [Venice.ai](https://venice.ai/)    |
| [SushiSwap](https://app.sushi.com/)           | [Rarible](https://rarible.com/)     |                                    |
| [ShapeShift](https://app.shapeshift.com/)     |                                     |                                    |
| [1inch](https://app.1inch.io/)                |                                     |                                    |
| [KyberSwap](https://kyberswap.com/)           |                                     |                                    |
| [Trader Joe](https://traderjoexyz.com/)       |                                     |                                    |
| [Rango Exchange](https://app.rango.exchange/) |                                     |                                    |
| [Thorswap](https://app.thorswap.finance/)     |                                     |                                    |
| [Jupiter](https://jup.ag/)                    |                                     |                                    |

***

{% hint style="info" %}
If you want to request a dApp being supported or encounter an issue connecting, please raise an ticket in our [discord](https://discord.gg/c5wZgWa5wn).\
OR\
If a supported and working interface is missing please create a issue [here](https://github.com/vultisig/docs/issues) to get it added to the docs.
{% endhint %}


# Plugin Marketplace

Self-custodial automation marketplace. Plugins for scheduled workflows, AI Agents for autonomous strategies — all MPC-secured, multi-chain, without giving up custody.

## Overview

The Vultisig Plugin Marketplace is a marketplace for self-custodial automation. Install plugins to automate your crypto management — from fixed workflows like DCA and scheduled payments, to autonomous AI Agents that make decisions based on market conditions — all without giving up custody of your funds.

Unlike traditional automation that requires handing over your keys, Vultisig plugins use MPC technology to keep you in control. Your vault executes automations securely — no third parties, no smart contract risks, no seed phrase exposure.

The Marketplace supports two types of automation:

|                  | Plugins                                         | AI Agents                                                       |
| ---------------- | ----------------------------------------------- | --------------------------------------------------------------- |
| **What they do** | Fixed, repeatable workflows on a schedule       | Autonomous strategies that react to conditions                  |
| **Triggers**     | Time-based (every Monday, every 4 hours)        | Event-based (price drops 5%, portfolio drifts, arb opportunity) |
| **Logic**        | Configurable parameters within a fixed strategy | Condition-based strategies with flexible triggers               |
| **Setup**        | Browse, install, configure rules                | Browse, install, define conditions and limits                   |
| **Examples**     | DCA, recurring payments, scheduled swaps        | Rebalancing bot, trend follower, cross-chain arbitrage          |

Both share the same MPC architecture — the Verifier validates every transaction before signing, ensuring nothing outside your rules gets executed.

Browse plugins and agents at [apps.vultisig.com](https://apps.vultisig.com). Developers can build and publish their own — see the [Developer Documentation](/developer-docs/marketplace) for details.

***

## How It Works

Vultisig plugins use a **proposing/validating architecture** that keeps you in control through every step.

### Setup & Installation

Installing a plugin creates a secure connection between your vault and the plugin's automation service. Here's what happens:

**Step 1: Browse & Select**

Visit [apps.vultisig.com](https://apps.vultisig.com), connect your Vultisig vault, and choose a plugin.

**Step 2: Install the Plugin**

Approve the installation to connect your vault to the plugin. This creates a secure link between your vault and the plugin's Verifier service:

| What Changes        | Before Installation       | After Installation                |
| ------------------- | ------------------------- | --------------------------------- |
| **Signing parties** | Your device + Vultisigner | Your device + Plugin Verifier     |
| **Who can propose** | Only you                  | Plugin (within your rules)        |
| **Who validates**   | —                         | Verifier checks every transaction |

{% hint style="info" %}
**Technical note:** Under the hood, installation performs a "reshare"—your vault's signing arrangement is reconfigured so the plugin's Verifier can participate in signing, but ONLY for transactions you authorize.
{% endhint %}

**Step 3: Configure Your Rules**

Now set your automation parameters:

* Which assets to use
* How much per transaction (amount limits)
* How often (schedule/frequency)
* Where to send (recipient addresses)

**Step 4: Automation Goes Live**

Your automation policy is now active. The plugin can propose transactions within your configured limits, and the Verifier ensures nothing outside your rules ever gets signed.

### Execution Flow

Once installed, your automation runs automatically:

| Step             | What Happens                                                         |
| ---------------- | -------------------------------------------------------------------- |
| **1. Trigger**   | Scheduler triggers based on your rules (e.g., "every Monday at 9am") |
| **2. Propose**   | Plugin creates an unsigned transaction matching your policy          |
| **3. Validate**  | Verifier checks the transaction against your exact rules             |
| **4. Sign**      | MPC signs only if validation passes—keys never leave your devices    |
| **5. Broadcast** | Signed transaction is sent to the blockchain                         |

{% hint style="info" %}
**Security guarantee:** The Verifier rejects any transaction that doesn't match your configured rules exactly. If a plugin tries to send more than you authorized, to a different address, or at the wrong time—it gets blocked.
{% endhint %}

***

## Available Plugins

Current plugins available at [apps.vultisig.com](https://apps.vultisig.com):

### Recurring Swaps (DCA)

Automate dollar-cost averaging into any asset. Convert one token to another on a schedule you define.

**Use cases:**

* Weekly Bitcoin accumulation
* Monthly portfolio rebalancing
* Gradual position building

### Recurring Sends

Schedule automatic payments to any address. Set up payroll, subscriptions, or regular transfers.

**Use cases:**

* Payroll automation
* Subscription payments
* Regular savings transfers

### AI Agents

AI Agents are plugins with more autonomy. Instead of running on a fixed schedule, they monitor conditions and act when triggers are met — rebalancing when your portfolio drifts, buying dips when prices drop, or capturing arbitrage opportunities across chains.

They use the same Marketplace infrastructure as standard plugins — same installation flow, same Verifier validation, same MPC signing. The difference is in what triggers them and how much flexibility they have in deciding what to execute.

**How they differ from standard plugins:**

* **Reactive triggers** — respond to price movements, portfolio drift, on-chain events (not just schedules)
* **Strategy flexibility** — developers define the decision logic, not just parameters
* **Continuous monitoring** — agents watch conditions in real time and act when thresholds are met

**Use cases:**

* Portfolio rebalancing when allocations drift beyond a threshold
* Buying the dip — accumulate an asset when it drops by a set percentage
* Cross-chain arbitrage between DEXs
* Trend-following strategies based on price momentum

{% hint style="info" %}
AI Agents share the same security model as plugins. The Verifier enforces your configured limits on every transaction — agents cannot exceed your rules, regardless of their strategy logic.
{% endhint %}

***

## For Users

### Getting Started

1. Open [apps.vultisig.com](https://apps.vultisig.com)
2. Connect your Vultisig vault
3. Browse and select a plugin
4. Approve the installation
5. Configure your automation rules

Each plugin shows its risk level and fee structure before installation.

### Security Features

| Feature                  | What It Means                                                   |
| ------------------------ | --------------------------------------------------------------- |
| **Risk ratings**         | Plugins are reviewed and assigned risk levels (Low/Medium/High) |
| **Rule-based execution** | Plugins can only do what you've configured—nothing more         |
| **No key exposure**      | Your private keys never leave your devices                      |
| **Transparent fees**     | All costs shown upfront before you install                      |

***

## For Developers

Build plugins for Vultisig users and earn 70% of the revenue. Plugins are reviewed for quality and security before listing.

**What you can build:**

* Trading bots and DCA strategies
* Portfolio management tools
* Payment automation
* DeFi integrations
* Cross-chain workflows

{% hint style="info" %}
Ready to build? Check the [Developer Documentation](/developer-docs/marketplace) for Plugins and join [Discord](https://discord.gg/Cugw9T2NrP) for support.
{% endhint %}

***

## Fee Structure

Plugin revenue is split:

| Recipient        | Share |
| ---------------- | ----- |
| Plugin developer | 70%   |
| $VULT token      | 30%   |

<figure><img src="/files/taWPfypWB4r03fGrruWV" alt="70/30 revenue split visualization"><figcaption><p>Revenue split: 70% to developers, 30% to $VULT</p></figcaption></figure>

**Fee models available to developers:**

* **Per-transaction** — charged each time the plugin executes
* **Subscription** — monthly or yearly recurring fee
* **Per-installation** — one-time setup fee

***

## Vultisig vs Alternatives

How does Vultisig Marketplace compare to other automation options?

| Feature                  | Vultisig Marketplace | CEX Recurring Buy | Smart Contract Bots     | Custodial Services |
| ------------------------ | -------------------- | ----------------- | ----------------------- | ------------------ |
| **Self-custody**         | ✅ Yes                | ❌ No              | ⚠️ Partial              | ❌ No               |
| **Seed phrase exposure** | ✅ None               | N/A               | ⚠️ Often required       | ❌ Full access      |
| **Multi-chain**          | ✅ 10+ chains         | ❌ Single platform | ⚠️ Per-chain deployment | ⚠️ Varies          |
| **Smart contract risk**  | ✅ None               | ✅ None            | ❌ Yes                   | ✅ None             |
| **Rule-based limits**    | ✅ Enforced by MPC    | ❌ No limits       | ⚠️ Contract-dependent   | ❌ No limits        |
| **Transparent fees**     | ✅ Upfront            | ⚠️ Hidden spreads | ⚠️ Gas + protocol fees  | ⚠️ Varies          |
| **Works with DeFi**      | ✅ Yes                | ❌ No              | ✅ Yes                   | ⚠️ Limited         |

**Key differentiators:**

* **True self-custody:** Unlike CEX recurring buys, your funds stay in your vault
* **No smart contract risk:** Unlike DeFi bots, there's no contract to exploit
* **Cross-chain native:** One setup works across Bitcoin, Ethereum, Solana, and more
* **Enforced limits:** MPC verification ensures apps can't exceed your rules

***

## FAQ

### General

<details>

<summary><strong>What happens if I run out of funds?</strong></summary>

The automation simply skips that execution. No failed transactions, no wasted gas. The scheduler will try again at the next scheduled time. You'll see a notification in the app.

</details>

<details>

<summary><strong>Can I cancel or pause an automation?</strong></summary>

Yes. You can pause, modify, or delete any automation at any time from apps.vultisig.com. Changes take effect immediately.

</details>

<details>

<summary><strong>What chains are supported?</strong></summary>

The Marketplace supports all chains that Vultisig supports, including:

* EVM chains (Ethereum, Polygon, Arbitrum, Base, Optimism, Avalanche, BSC)
* Bitcoin
* Solana
* THORChain
* And more

Each plugin specifies which chains it supports.

</details>

<details>

<summary><strong>Do I need to keep my devices online?</strong></summary>

No. Once you've set up an automation, it runs on Vultisig's infrastructure. Your devices only need to be online for the initial setup and any changes.

</details>

### Security

<details>

<summary><strong>Can a plugin drain my wallet?</strong></summary>

No. Plugins can only execute transactions that match your configured rules exactly. The Verifier service validates every transaction before MPC signing. If a plugin tries to send more than you authorized or to a different address, the transaction is rejected.

</details>

<details>

<summary><strong>What if Vultisig's servers go down?</strong></summary>

Your funds remain safe in your vault. Automations would pause until service is restored. You can always access your funds directly through the Vultisig app—the Marketplace is an optional feature.

</details>

<details>

<summary><strong>How are plugins reviewed?</strong></summary>

All plugins go through a security review before listing. We check:

* Code quality and security practices
* Transaction logic matches declared functionality
* No hidden fees or unexpected behaviors
* Proper error handling

Plugins are assigned risk ratings (Low/Medium/High) based on their complexity and permissions.

</details>

<details>

<summary><strong>Is my seed phrase ever exposed?</strong></summary>

No. Vultisig is seedless by design. There's no seed phrase to expose. The MPC architecture means your private key is never reconstructed—not even during signing.

</details>

### Fees

<details>

<summary><strong>What fees do I pay?</strong></summary>

You pay two types of fees:

1. **Plugin fees** — Set by the developer (shown before installation)
2. **Network fees** — Standard blockchain gas fees for each transaction

There are no hidden Vultisig platform fees.

</details>

<details>

<summary><strong>How do subscription fees work?</strong></summary>

If a plugin uses subscription pricing, the fee is collected automatically at the start of each billing period. You can cancel anytime—you'll retain access until the current period ends.

</details>

***

## What's Next

The Marketplace is actively growing. Upcoming features include:

* More automation plugins from third-party developers
* Advanced DeFi integrations (yield farming, liquidity provision)
* Cross-chain yield strategies
* Community-built tools
* Enhanced analytics and reporting

Want to request a plugin or feature? Join the [Discord](https://discord.gg/Cugw9T2NrP) and share your ideas.


# Web App

Vultisig web app for view-only vault access. Perfect for DAOs and treasuries to share holdings publicly. Track your airdrop position.

The web app is a "view-only" version of all Vultisig Vaults, giving DAOs and Treasuries the perfect tool to share their holdings without fear that any stakeholder will be able to access the assets.

It is also used to display the ongoing [airdrop](/vult-token/airdrop) of $VULT to the community.

The website can be accessed here:

{% embed url="<https://airdrop.vultisig.com>" %}

## How to connect to the Web App

1. Get your [Vault QR](/app-guide/vault-management/vault-qr) code from your Vultisig Vault
2. Open the [web app](https://airdrop.vultisig.com)
3. Upload your QR code
4. Access the web app


# Vultisig SDK

MPC Wallet Infrastructure for Developers & AI Agents

The Vultisig SDK gives developers and AI agents direct access to Vultisig's multi-party computation (MPC) technology. Instead of relying on seed phrases that create a single point of failure, the SDK splits wallet keys across multiple devices using threshold signatures. The result: secure, self-custodial wallets that work across 40+ blockchains.

Whether you're building a web app, a backend service, or an AI agent that needs to hold and move crypto — the SDK handles vault creation, balance checks, token swaps, and transaction signing.

## What Can You Build With It?

* **Web3 applications** — Onboard users into seedless, cross-chain wallets with MPC security built in
* **AI agent wallets** — Give autonomous agents their own self-custodial crypto wallets, with optional human co-signing for oversight
* **Backend services** — Programmatic vault creation, balance checks, swaps, and signing from your server
* **Desktop & browser apps** — Works in Electron, any modern browser, and Node.js

## How It Works

The SDK supports two vault types:

* **Fast Vault** — A 2-of-2 setup between your app and VultiServer. Signing is instant. Great for quick setup and individual use.
* **Secure Vault** — A multi-device setup (2-of-3, 3-of-5, etc.) where multiple devices must approve transactions. Other participants join by scanning a QR code with the Vultisig mobile app. Best for teams or high-value wallets.

Both vault types support 40+ chains including Bitcoin, Ethereum, Solana, THORChain, Cosmos, and the broader EVM, UTXO, and Cosmos ecosystems. Cross-chain swaps are powered by THORChain, with 1inch for same-chain DEX trades and LiFi for cross-EVM routes.

There's also a full CLI (`@vultisig/cli`) that mirrors the SDK's capabilities from the command line.

## For AI Agents

AI agents can use the SDK or CLI to create wallets, check balances, send tokens, and execute swaps autonomously. Two trust models are available:

| Mode             | How it works                  | Signing                    | Use case                             |
| ---------------- | ----------------------------- | -------------------------- | ------------------------------------ |
| **Fast Vault**   | Agent + VultiServer (2-of-2)  | Instant, no human needed   | Full agent autonomy                  |
| **Secure Vault** | Agent + human device (2-of-2) | Human approves via QR scan | Human oversight on every transaction |

The CLI makes agent integration simple:

```bash
npm install -g @vultisig/cli

vultisig create
vultisig balance ethereum -o json
vultisig send ethereum 0xRecipient 0.1
vultisig swap ethereum bitcoin 0.1
```

JSON output, silent mode, and environment variable config (`VAULT_PASSWORD`) plug directly into agent pipelines. Stateless usage is also supported — load a vault file, operate, discard.

For the full agent operating procedure, see [vultisig.com/SKILL.md](https://vultisig.com/SKILL.md).

## Getting Started

Install the SDK:

```bash
npm install @vultisig/sdk
```

Create a vault and start using it:

```typescript
import { Vultisig, MemoryStorage } from '@vultisig/sdk'

const sdk = new Vultisig({ storage: new MemoryStorage() })
await sdk.initialize()

const vaultId = await sdk.createFastVault({
  name: 'My Wallet',
  email: 'user@example.com',
  password: 'SecurePassword123!',
})

const vault = await sdk.verifyVault(vaultId, code)

const address = await vault.address('Ethereum')
const balance = await vault.balance('Ethereum')
```

For the full API reference, CLI documentation, and detailed usage guides, head to the developer docs:

{% content-ref url="/pages/wmX4xojbg9FnrrhCOGPW" %}
[SDK](/developer-docs/vultisig-sdk)
{% endcontent-ref %}

## Resources

* [SDK Repository on GitHub](https://github.com/vultisig/vultisig-sdk)
* [AI Agent Operating Procedure (SKILL.md)](https://vultisig.com/SKILL.md)
* [Machine-readable Agent Manifest (agent.json)](https://vultisig.com/.well-known/agent.json)
* [Full SDK & CLI Documentation](/developer-docs/vultisig-sdk)


# Community Tools

Community-built Vultisig tools: Vault Share Decoder and more. Open source ecosystem—approved and endorsed applications.

## Vault Share Decoder

This app helps users decode their vault shares and access additional information when needed. It can also be used to easily recover private keys by combining the threshold of shares, similar to the [Emergency Recovery](/security-and-technology/emergency-recovery) process.

{% hint style="warning" %}
You should only recreate the private keys if it is absolutely necessary, as doing so will compromise the security of Vultisig.
{% endhint %}

Website: <https://share-decoder.vultisig.com>

Repo: <https://github.com/vultisig/community-tools/tree/main/recovery-tools/vultisig-share-decoder>


# The $VULT Token

$VULT serves as the cornerstone of the rapidly expanding Vultisig Ecosystem, offering multiple valuable utilities to it's holders and stakers.

## Token Info

Ticker: `$VULT`

Network: Ethereum; ERC-20

Contract Address: [`0xb788144DF611029C60b859DF47e79B7726C4DEBa`](https://etherscan.io/token/0xb788144df611029c60b859df47e79b7726c4deba?a=0x57f80f1ff0e9a3571c343ca623c53124f4f0f5fe)

Token Supply: 100,000,000

Availability:

* DEX: Uniswap
* CEX: Kraken

***

## Utility of $VULT token

The main benefit lies in the various mechanisms provided, through which $VULT holders receive discounts and other benefits for holding $VULT.

In general, VULT will unlock trading fee discounts, voting rights, preferential pricing, and exclusive access to premium features across the Vultisig marketplace. As our ecosystem grows, the utility and value of holding VULT tokens will increase as well.

All current and future utility is aimed at driving value to the VULT token, displaying the project's current adoption and value accrual.

The Utility is separated into 3 pillars:

* In-App Utility
* Marketplace Utility
* Governance Utility

***

### Value Accrual

All value generated in the Vultisig ecosystem is designed to flow back into the $VULT token, this consists mainly of fee revenue and other income streams.

<table><thead><tr><th width="373">Fee</th><th>Amount</th></tr></thead><tbody><tr><td>Swap Fees (Cross-chain and Token swaps)</td><td>Starting at 50 basis points</td></tr><tr><td>Bridge Fees (Between EVMs and IBC, to be implemented)</td><td>10 basis points</td></tr><tr><td>Marketplace Fees (Plugins and Ai Agents)</td><td>30% of generated revenue</td></tr></tbody></table>

***

### Token Buybacks

All fees generated by Vultisig products will be used to buy back $VULT tokens periodically.

This reduces the circulating supply and has a direct positive impact on the token itself depending on the adoption and usage of Vultisig products, like the plugins and the marketplace.

The bought back [$VULT](https://x.com/search?q=%24VULT\&src=cashtag_click) tokens will be held in the fee treasury until the distribution mechanism are determined and set in place.

***

## The $VULT Tokenomics

### Allocations

<figure><img src="/files/LoqmkqhsLYJZ9QQXUV3l" alt=""><figcaption><p>Allocations</p></figcaption></figure>

## Vesting

Following vestings apply to above mentioned parties:

<figure><img src="/files/MuNYYyzmLHfgtKxH2lAG" alt=""><figcaption></figcaption></figure>

### **Launch Liquidity Allocation:**

* 24% of $VULT tokens are allocated to initial investors as an LP position, with a 1-year cliff to provide sufficient initial liquidity
* Up to 11% of $VULT tokens come from the project treasury to add sufficient liquidity and will be carefully managed for specific growth initiatives but intended to stay in the LP.

{% hint style="success" %}
The Treasury allocation remains partially unlocked to fund exceptional opportunities that drive Vultisig adoption, including strategic partnerships, community giveaways, and hackathons.\
All Treasury token usage will be strictly limited to initiatives that directly increase Vultisig ecosystem value.
{% endhint %}

### **Token Allocation**

#### **Community and Strategic Allocations:**

* 6% of VULT reserved for community airdrop, rewarding early supporters. Unlocking with ending seasons and distributed to airdrop participants.
* 10% of $VULT dedicated to the $WEWE → $VULT merger.
* 1.7% of $VULT allocated to a strategic partnership with CoinMarketCap to significantly expand Vultisig’s reach and adoption. Locked with a 1-year cliff.

#### **Team Commitment:**

* 17.3% of VULT allocated to the team with a 4-year linear vesting schedule, ensuring long-term alignment with project success

#### **Early Investor Structure:**

* 30% of $VULT distributed to early investors who fulfilled all their obligations by providing crucial funding that enables 3+ years of development runway and will be unlocked on launch.
* These investors initially bought in at a $70M fully diluted valuation (FDV), while the public launch begins at just $3M FDV, creating strong incentive alignment with the community
* Many investors have committed to providing additional liquidity at launch, helping stabilize price action and deepen the trading pool

{% hint style="info" %}
You can view the full token unlock timeline on [CoinMarketCap](https://coinmarketcap.com/currencies/vultisig/#token_unlocks), which provides a detailed breakdown of vesting schedules and circulating supply.
{% endhint %}


# In-App Utility

$VULT in-app utility: Trading fee discounts up to 50% based on holdings. Tier system from Bronze to Diamond. Hold more, pay less.

## Trading Fee Discounts

As previously mentioned, utilizing the cross-chain swap functionality of Vultisig incurs a 50-bps fee for each swap executed.

Hold the $VULT token in the Vultisig Vaults to obtain in-app swap fee reductions and different tiers of discounts, rewarding stronger believers.

\
The Tiers are the following:

* Bronze: 1,500 [$VULT](https://x.com/search?q=%24VULT\&src=cashtag_click)= 5 bps
* Silver: 3,000 [$VULT](https://x.com/search?q=%24VULT\&src=cashtag_click)= 10 bps
* Gold: 7,500 [$VULT](https://x.com/search?q=%24VULT\&src=cashtag_click)= 20 bps
* Platinum: 15,000 [$VULT](https://x.com/search?q=%24VULT\&src=cashtag_click)= 25 bps
* Diamond: 100,000 [$VULT](https://x.com/search?q=%24VULT\&src=cashtag_click)=35 bps
* Ultimate: 1,000,000 [$VULT](https://x.com/search?q=%24VULT\&src=cashtag_click)= Complete Vultisig fee waive, will also clear referral.

<figure><img src="/files/DDBu4RMmMU1crMEorw6f" alt=""><figcaption></figcaption></figure>

## Holding a THORGuard NFT

Holding a [@THORGuards](https://x.com/@THORGuards) NFT (<https://opensea.io/collection/thorguards>) in your Vault will increase the discount tier by one!

Example:

Hold 1,500 $VULT to be eligable for the Bronze Discount Tier. If you hold at least 1 THORGuard NFT you will automatically be upgraded to Silver Discount Tier.

*This is only be applicable up until Platinum Tier.*


# Marketplace Utility

$VULT Marketplace utility: Developer registration fees, plugin listing fees, and premium placement. Token burns drive scarcity.

{% hint style="info" %}
The Marketplace is not yet fully rolled out. The exact fees for each category are still to be determined. They will be updated as soon as they are finalized.
{% endhint %}

## **Developer and Plugin Registration Fee**

To improve plugin quality and prevent malicious plugins on the Marketplace, Vultisig developers will pay a one-time registration fee and a per-plugin registration fee in [$VULT](https://x.com/search?q=%24VULT\&src=cashtag_click), which will be burned.\
This system provides better oversight of developers in the Vultisig ecosystem.

***

## **Reduced Fees for Users**

Users will be able to pay with [$VULT](https://x.com/search?q=%24VULT\&src=cashtag_click) instead of [$USDC](https://x.com/search?q=%24USDC\&src=cashtag_click) and receive a discount on installation fees in the Marketplace. Additionally, users will receive reduced fees on recurring purchases, such as subscriptions or bulk purchases, when staking [$VULT](https://x.com/search?q=%24VULT\&src=cashtag_click). The exact amounts are yet to be determined before the complete Marketplace rollout.

***

## **Premium Plugins**

Developers can apply for a "Premium Plugin" or "Vultisig Approved" label. This will incur a one-time fee in VULT, which will be considered revenue. The Vultisig team will audit and perform a regression test on the developer's plugin, which will increase the credibility of the plugin.

***

## **Boost Visibility**

Developers will be able to increase their visibility in the Marketplace by spending [$VULT](https://x.com/search?q=%24VULT\&src=cashtag_click) . The specific packages will be determined before the Marketplace rollout.

***

## **Developer Income Boost**

Developers will be able to stake and lock up tokens to increase their share of the fees. Stake and Lock:

* 500.000 VULT for 1 year, receive 80% of fees
* 1.000.000 VULT for 1 year, receive 90% of fees

These will be one-year subscriptions and will be available at a later point, after the Marketplace rollout.


# Governance Utility

$VULT governance utility: Vote on treasury allocation, protocol decisions, and ecosystem development. Staked VULT = voting power.

Vultisig will gradually transition to a governance voting structure owned by the community, which will utilize staked $VULT. This structure will decide how to allocate the bought-back $VULT.

This transition will happen gradually. During this time, we will continue to buy back $VULT with the accumulated revenue.

This will enable us to act in the project’s best interest and avoid regulatory issues, providing an interesting and fair distribution structure. The exact governance structure and voting options will be decided in the near future.


# Launch of $VULT

The launch of the Vultisig Token to the world.

> **Last updated:** 2025‑10‑20 - reflects the “Token Launch Update and New Principles for Community Communication” Medium post. [Read the full announcement](https://vultisig.medium.com/token-launch-update-and-new-principles-for-community-communication-a57898b5614e).

## TL;DR / FAQ

**Launch window:** *27th of October 2025*. The DEX launch will occur **24 hours&#x20;*****before*****&#x20;our CEX listing**.

* **DEX → CEX cadence:** DEX launches **24 hours before the CEX listing**.
* **Liquidity & pricing:** \~35% of supply seeded in a Uniswap V3 pool starting at \~$3M FDV.
* **Whitelist: Up to** 1,500 slots with staggered purchase caps ($1k first hour → $10k thereafter).
* **IOU VULT holders:** $VULT will be claimable shortly after the launch.

***

Our CEX partners determine their own go‑live schedule. Once our CEX partner publicly confirms their listing schedule, we will coordinate transparently and clearly communicate the DEX launch date. Committing prematurely has already created confusion, so we are moving to an evidence‑based timeline:

1. Confirmed date with CEX.
2. We subtract 24 h from the confirmed CEX listing date and lock that in as the DEX launch time - meaning you’ll know the DEX launch timing as soon as the CEX date is announced.
3. Announcement will happen with enough due time (1-2 weeks) until launch but as soon as date is set.
4. Joint marketing push‑up with the CEX + Vultisquad until launch.

This approach guarantees we never miss a published date again and keeps the community first in the information flow.

***

## Launch Liquidity

### Initial Funding

Vultisig has raised **$2.4M** in initial funding of LP investors. Up to 35% of the total supply is paired with USDC in a Uniswap V3 1% fee pool. Concentrated-liquidity ranges will span **$3M → $1B FDV**, ensuring sufficient liquidity from the first block.

### Pool Composition

* **24%** - strategic investors
* **\~11%** - Treasury allocation

### Initial Valuation

The FDV at pool inception will start at **$3M** and increases organically after the first buys.

***

## Launch Flow

### Phase 1 - Whitelisted Trade-Only (24h)

* Up to 1,500 addresses
* Hour 1 cap: **$1k**
* Hour 2 → 24h cap: **$10k**
* No lock-ups; free to LP or trade

### Phase 2 - Public Launch

* Pool opens to everyone simultaneously with the availability of $VULT on our CEX partner
* No caps, no throttles; full market dynamics

<figure><img src="/files/lo0vSqmHmZTfBxvxyfFi" alt=""><figcaption><p>Launch Roadmap</p></figcaption></figure>

***

## Further Information

* Strategic investors entered at **$70M FDV** (\~23× public launch valuation).
* Investors will optionally LP more USDC/VULT at launch to stabilize price discovery.
* Launch LP remains on Uniswap V3 (1% fee tier).

***

*Questions?* Join the discussion in `#-announcements` and `#-wl-launch` on Discord.


# Airdrop

Vultisig $VULT airdrop details. Earn rewards based on vault value and time held. Season structure, eligibility, and how to maximize points.

{% hint style="warning" %}
This is the setup for the current Season 0 and will be discontinued after the current season ends, starting with [Airdrop V2](/vult-token/airdrop/airdrop-v2) to further enhance the airdrop experience. Read more about it [here](https://medium.com/@vultisig/vultisig-airdrop-2-0-how-were-transforming-the-experience-f20c146f2f29) .
{% endhint %}

***

Early adopters of the Vultisig wallet security standard are highly valued by the project, so Vultisig wants to give back to these high conviction members.

The future $VULT airdrop will be proportionate to:

$$
vault\_asset\_value\*time\_in\_vault
$$

With the distribution date of 12 months after registration goes live.\
See further calculation [here](#airdrop-process).\
\
Users will receive full information about how to register for this airdrop in the coming weeks.

***

## Airdrop Process

To register their vaults for the Airdrop, users send their exported Vault public Keys to an Airdrop Registry, which will scan for presence of funds on chains, and then begin counting airdrop value.\
**See the exact instructions** [**here.**](#how-to-register-for-the-airdrop)\
\
This will include most actions performed in Vultisig (like bonding to nodes and staking, etc.).

A new scan will be performed each cycle (day), and the user airdrop value accumulates in form of VULTIES (Points).\
Users that keep the funds the longest in Vultisig will earn the highest airdrop value.

$$
user\_VULTIES += $\text{total\_vault\_value}
$$

The final share of the Airdrop is the pro-rata share of the airdrop allocation.

$$
\text{user\_airdrop\_share} = 1,000,000 \times \left( \frac{\text{user\_VULTIES}}{\text{total\_VULTIES}} \right)
$$

<figure><img src="/files/xZPzSUQiqQKcaN62UmEi" alt="" width="375"><figcaption></figcaption></figure>

### Eligible assets

Assets must have a dollar value from an external provider in order to accumulate VULTIES (airdrop points).\
Supported Assets are:

* L1 tokens supported by Vultisig
* Tokens supported by 1inch and displayed on the airdrop website
* BASE.WEWE
* WEWESWAP LP
* THORChain Bonds, LP(dual and single), RUNEPool, Savers
* MAYA Protocol Bonds, LP(dual and single)
* vTHOR
* TGT stakers
* Staked TON

### Initial Airdrop

The initial Airdrop is 5,000,000 $VULT, which will be distributed after the first year. After which, all public keys are purged and a new airdrop period begins.

### Ongoing Airdrop

The Ongoing Airdrop Process will continue for another 5 years, and the dedicated supply of $VULT will be airdropped on the anniversary of the token launch every year.

***

## How to register for the airdrop

1. [Export](/app-guide/vault-management/vault-qr) the Vault QR of the Vultisig Vault\\

   <figure><img src="/files/9EaXLtwJsmKkM1OTU17l" alt="" width="188"><figcaption></figcaption></figure>
2. Connect to the [airdrop](https://airdrop.vultisig.com/import) page with your [Vultisig Extension](/ecosystem/vultisig-extension) or by uploading your Vault QR\\

   <figure><img src="/files/29lE6jqMeztMFOwpuCT8" alt="" width="375"><figcaption></figcaption></figure>
3. Join the Airdrop with your connected Vault with clicking `Join Airdrop` on the website\\

   <figure><img src="/files/xZPzSUQiqQKcaN62UmEi" alt="" width="188"><figcaption></figcaption></figure>
4. Go to the `Balance` tab and enable **ALL a**ssets you want to have counted towards the airdrop
5. Earn VULTIES (Airdrop points) and track the leaderboard
6. Register multiple Vaults

{% hint style="warning" %}
You need to enable all Chains and Tokens you want to have counted towards the airdrop once!
{% endhint %}

***

## Airdrop point multiplier

In order to make the Vultisig Airdrop more game-like and to further increase the possible reach of the Vultisig Airdrop, we will introduce more possibilities to multiply the already collected airdrop points.

The multiplier will accumulate, similar to the VULTIES (airdrop points) and will be calculated at the end of the airdrop phase to get the complete airdrop share.

This gives the opportunity to increase the personal multiplier over the course of the ongoing 12 month Airdrop without affecting the VULTIES.

The multiplier will start at 1 and will increase depending on the activities and programms, set by the Vultisig team.

### How to increase the Multiplier

At the heart of the Airdrop multiplier is the [Referral Program](#referral-program).

{% hint style="info" %}
There will be special programs and opportunities to increase this as the airdrop progresses. They are listed below.
{% endhint %}

#### Referral Program

Vultisig team has built a [Telegram bot](/help-and-legal/vultisig-bot) to easily invite friends and track the referred people.

* Invite people
* Let them install Vultisig
* Funding the wallet with at least $50 of assets
* **Increase your referral count and airdrop share**

**The referred people will have a strong impact on the multiplier.**

## Privacy

{% hint style="warning" %}
Do not register for the Airdrop if you do not wish for your public keys to be sent to the Airdrop Registry.\
Note, after the Airdrop has finished, your public keys will be purged. No other user information is collected.
{% endhint %}

Read the [Privacy Policy](/help-and-legal/privacy)


# Airdrop V2

Vultisig Airdrop V2: Enhanced rewards system. Earn $VULT based on vault value × time held. Achievement tiers, daily drops, and multipliers.

Early adopters of the Vultisig wallet security standard are highly valued by the project, so Vultisig wants to give back to these high conviction members.

The future $VULT airdrop will be proportional:

$$
vault\_asset\_value\*time\_in\_vault
$$

While taking into account other multipliers, such as swap volume and referral multipliers, to further increase the virality.\
See further calculation [here](#calculations).

***

## Airdrop Process

To register their vaults for airdrop, users send their exported vault public keys to an airdrop registry, which checks for the presence of funds on chains and then begins counting the airdrop value.

This will include most actions performed in Vultisig (such as binding to nodes and staking, etc.).

**A new scan is performed every cycle (day), and the user's airdrop value accumulates in the form of VULTIES (airdrop points).**

Therefore, users who keep their funds in Vultisig the longest and use the vault actively will earn the highest airdrop value.

The airdrop points are reset after each [season](#seasons) and can be multiplied with special multipliers, which are listed [below](#multipliers). The final share of the airdrop per season is the pro rata share of the airdrop allocation.

***

## Eligible assets

Assets must have a dollar value from an external provider in order to accumulate VULTIES (airdrop points).

<figure><img src="/files/dQRnM9ocgjk7KJaJsv68" alt=""><figcaption><p>BTC</p></figcaption></figure>

Supported Assets are:

* L1 tokens supported by Vultisig
* Tokens supported by 1inch, Jupiter and displayed on the airdrop website
* THORChain Bonds, LP(dual and single)
* MAYA Protocol Bonds, LP(dual and single)
* vTHOR
* Staked TON

Assets will be auto-discovered. In the case of non-discovery, assets can be added manually to verify if they are eligible.

***

## Airdrop amount

The airdrop will have a total amount of **6,000,000 $VULT** (6% of total supply) and will be split into:

Season 0 : 1,000,000 $VULT\
Season 1-4: 5,000,000 $VULT, distributed at the end of each season.

***

## Seasons

In order to create a more dynamic and inclusive airdrop system, a seasonal structure will be implemented, giving both early supporters and newcomers meaningful opportunities to participate.

Each season will last 1 quarter and will have an airdrop share of 1,250,000 $VULT to distribute.

**Airdrop points will be reset after each season.**

***

## Multipliers

To make the airdrop more interesting, several multipliers will be introduced starting with Season 1.

### **Swap Volume Multiplier**

To incentivize trading and make the airdrop more dynamic, a swap multiplier will be introduced. This will reward active users of Vultisig with a higher airdrop share based on their swap volume. The multiplier will reset each season to prevent excessive advantages and maintain fairness.

### **Referral Multiplier**

The [Referral Program](#referral-program) is tracking referred wallets via the [Referral Telegram bot](/help-and-legal/vultisig-bot) of registered users.

For a referral to be considered valid, the referred wallet must fund with at least $50 and take part in the airdrop.

{% hint style="info" %}
The referred wallet must continuously have at least $50 in the vault; otherwise, the referral will be voided.
{% endhint %}

This multiplier logarithmically multiplies and caps at 500 referrals, providing up to a maximum of 2x boost in your total airdrop points. The referral bonus, in contrast to other multipliers, will not reset between seasons, so you can build and retain your network advantage between seasons.

### Dedicated tokens and community multipliers

To attract more attention and expand the Vultisquad community, a special multiplier will be introduced for holding selected tokens or NFTs that will be selected in the coming future.

The first token to receive this treatment will be $VULT itself, which will grant holders a 1.5x multiplier on its dollar value within the airdrop calculation.

The following tokens and NFTs have a higher multiplier:

| Token | Multiplier |
| ----- | ---------- |
| $VULT | 1.5        |
| $RUNE | 1.3        |

***

| NFT        | Multiplier |
| ---------- | ---------- |
| Thorguards | 1.3        |

***

## Calculations

### Daily airdrop points per user

$$
user\_VULTIES += SQRT($\text{total\_vault\_value})
$$

### Swap Volume multiplier

$$
\text{swap\_volume\_multiplier} = 1+0.002\*SQRT(\text{swap\_volume\_per\_season})
$$

### Referral multiplier

$$
\text{referral\_multiplier} = \min\left(2, 1+\frac{\log(1+\text referred\_wallets)}{\log(1+500)}\right)
$$

### Adjusted airdrop points per user

$$
\text adjusted\_user\_VULTIES = \text user\_VULTIES\times \text {swap\_volume\_multiplier} \times \text{referral\_multiplier}
$$

### Seasonal $VULT share

$$
\text{user\_airdrop\_share} = 1,250,000 \times \left( \frac{\text{adjusted\_user\_VULTIES}}{\text{total\_adjusted\_VULTIES}} \right)
$$

***

## How to register for the airdrop

* Download and open your Vultisig app

<figure><img src="/files/1XqBvEgyzWv2wme1JD41" alt="" width="279"><figcaption></figcaption></figure>

* [Export](/app-guide/vault-management/vault-qr) the Vault QR of the Vultisig Vault

<figure><img src="/files/PcUchWmEsHeiEZdg0jRv" alt="" width="279"><figcaption></figcaption></figure>

* Connect to the [airdrop](https://airdrop.vultisig.com/import) page with your [Vultisig Extension](https://chromewebstore.google.com/detail/ggafhcdaplkhmmnlbfjpnnkepdfjaelb?utm_source=item-share-cp) or with uploading your Vault QR\\

  <figure><img src="/files/29lE6jqMeztMFOwpuCT8" alt="" width="375"><figcaption></figcaption></figure>
* Join the Airdrop with your connected Vault with clicking `Join Airdrop` on the [web app](/ecosystem/web-app)\\

  <figure><img src="/files/FfiVeSv4LEwEpn2ps2Xc" alt="" width="225"><figcaption></figcaption></figure>
* Go to the `Balances` tab and check for auto-discovery or enable **ALL a**ssets you want to have counted towards the airdrop
* Earn VULTIES (Airdrop points) and track the leaderboard
* Register multiple Vaults

{% hint style="warning" %}
You need to enable all Chains and Tokens you want to have counted towards the airdrop once!
{% endhint %}

***

### Referral Program

Vultisig team has built a [Telegram bot](/help-and-legal/vultisig-bot) to easily invite friends and track the referred people.

* Invite people
* Let them install Vultisig
* Funding the wallet with at least $50 of assets
* **Increase your referral count and airdrop share**

**The referred people will have a strong impact on the multiplier.**

## Privacy

{% hint style="warning" %}
Do not register for the Airdrop if you do not wish for your public keys to be sent to the Airdrop Registry.\
**Note, after the Airdrop has finished, your public keys will be purged. No other user information is collected.**
{% endhint %}

Read the [Privacy Policy](/help-and-legal/privacy)


# Overview

Vultisig infrastructure: Vultiserver for auto-signing and Relay Server for secure device communication. Trustless design, no tracking.

Vultisig aims to be as trustless as possible while still providing the best service possible.

To achieve this, Vultisig doesn't use any tracking or data collection in-app, see more here.

Nevertheless, it provides two solutions to improve the user experience, which are the Vultiserver and the Relay-Server:

{% content-ref url="/pages/BKSmhvSnAPSlKe82CI1M" %}
[Vultiserver](/infrastructure/what-is-vultisigner)
{% endcontent-ref %}

{% content-ref url="/pages/kFmcJMM5fGQnmYbU95tL" %}
[Relay Server](/infrastructure/relay-server)
{% endcontent-ref %}


# Vultiserver

Vultiserver enables automatic co-signing for Fast Vaults. One-device experience with multi-factor security. Configurable transaction policies.

Vultiserver is an infrastructure feature of Vultisig that enables automatic co-signing of transactions within a user's Vault, but only under [pre-defined parameters](/infrastructure/what-is-vultisigner/what-can-be-configured) set by the Vault owner. It acts as an automatic co-signer that can also engage when only certain user-defined criteria are met.

This functionality allows users to manage a Vultisig "Fast Vault" that inherently functions as a multi-device, multi-factor vault, while providing the user experience of a single-signature wallet when signing transactions.\
This setup is called a 2 of 2 device Fast Vault configuration.

Therefore, the Vultiserver feature ensures a smooth "one-device" experience, which (if desired) undergoes automatic security checks on sending that are consistently met once configured. These features can be modified by obtaining the threshold majority of Vault shares and signing a transaction, providing flexibility in maintaining and updating security protocols.


# How does a Fast Vault work?

Technical overview of Vultiserver Fast Vault setup. 2-of-2 keygen ceremony, vault share storage in secure enclave, and signing flow.

## Set Up

### 2-of-2 Fast Vault

In this setup, the Vault is created together with a user's device and the Vultisigner server.\
The user registers a keygen request with the Vultisigner server, which creates a new Vault that records the connection to the user's device. A keygen ceremony is then executed, which creates the Vault shares on the user's device and on the Vultisigner server. \\

## Vault Share storage

The Vultisigner's Vault Shares are stored on a dedicated Vultisigner server, which contains the Vault Shares along with configured instructions for signing transactions.\\

For security reasons, the Vultisigner's Vault share is password encrypted and the user must provide an email address to which the Vault share will be sent during setup, for backup and independent access.

<figure><img src="/files/WRMRwKc2uvf6Mo7UTgxo" alt="" width="563"><figcaption></figcaption></figure>

## Transaction Signing

When a user wishes to sign a transaction, the request is sent to the Vultisigner server.\
The appropriate Vultisigner Vault will verify that the configured transaction policies are met before participating in the Keysign process.\
If they are met, the Vultisigner joins the Keysign ceremony and the transaction is broadcasted to the blockchain.

<figure><img src="/files/8ua29YV4caHohuVpXns1" alt=""><figcaption><p>Vultisigner Flowchart</p></figcaption></figure>

{% hint style="info" %}
In case the Vultisigner server is offline and unable to sign, the user needs to import the Vultisigner share received via email into another device and sign like a normal Keysign.
{% endhint %}


# Transaction Policies

Vultiserver transaction policies (coming soon): Spending limits, whitelisted addresses, time delays, and custom rules for automated co-signing.

{% hint style="info" %}
Transaction Policies will be available soon
{% endhint %}

## What can be configured?

The transaction policies for Vultisigner can be configured to meet the specific needs of each user.\
The default transaction policy can look like this:

* Only allow swaps inside the vault (from pubkey to pubkey)
* Max. $1k-$10k-$100k per day transaction limits
* Only send to whitelist addresses
* Send to non-whitelist addresses with 24 hour delay
* Add new address whitelist with 24-hour delay
* Only able to swap certain routes


# Why is it safe?

Vultiserver security model: Single share can't sign alone, server can't initiate transactions, secure even if compromised. Backup procedures.

Since the Vultiserver always holds only one Vault Share, it will never be able to sign a transaction on its own without the participation and consent of the user, even in the event that the server is compromised.\
\
In addition, the server is configured so that it can never initiate a transaction; it can only be a participant in the key signing process.\\

In the event that the Vultisig server is offline, the user will still need the threshold majority required to perform Keysign ceremonies.

The Vultisigner's password-encrypted Vault Share which was emailed to the user during setup must be stored securely by the user (at a separate location from the user's own device's Vault Share) for this reason.


# Relay Server

Vultisig Relay Server enables encrypted device-to-device communication. End-to-end encrypted keygen and keysign messaging. Open source.

The Vultisig Relay Server is an infrastructure feature of Vultisig that enables encrypted messaging between user devices over the Internet.

The Vultisig Relay Server is nothing more than a messaging service to ensure efficient and smooth messaging between devices that have Vultisig installed.

It relays all Keygen and Keysign messages from collaborating user devices completely end-to-end encrypted so that no other party can intercept the information being passed.

See the code [here](https://github.com/vultisig/vultisig-relay).


# Developer Home

Build on Vultisig's secure, multi-chain infrastructure. Whether you're creating automated trading strategies, integrating wallet connectivity into your dApp, or building applications with programmatic vault management, Vultisig provides the tools you need.

## What Can You Build?

| Use Case                    | Example                                                      |
| --------------------------- | ------------------------------------------------------------ |
| **Automated Trading**       | DCA bots, yield optimizers, portfolio rebalancers            |
| **AI Agents**               | Autonomous trading agents with secure key management         |
| **dApp Wallet Integration** | Connect Vultisig to your DeFi protocol or NFT marketplace    |
| **Custodial Services**      | Multi-sig treasury management, institutional custody         |
| **Portfolio Apps**          | Cross-chain portfolio trackers with transaction capabilities |

These are just examples. Vultisig's MPC infrastructure is chain-agnostic and protocol-agnostic—if it exists on-chain, you can automate it. Get creative.

## Choose Your Path

### AI Agents

Give agents multi-chain wallet capabilities and choose between autonomous, policy-bound, and human-approved signing.

* **Languages**: TypeScript, shell, or Go
* **Best for**: Coding agents, trading bots, payment automation, and portfolio strategies

{% content-ref url="/pages/gD0NYNOTeEmCMAMterX9" %}
[AI Agents](/developer-docs/ai-agents)
{% endcontent-ref %}

### Marketplace Plugins

Build automation plugins that run on Vultisig's infrastructure and are distributed through the Marketplace.

* **Language**: Go
* **Best for**: Backend developers building trading bots, yield strategies, or AI agents
* **Revenue**: 70/30 split (developer/treasury)

{% content-ref url="/pages/Ddr8dZAJr8vwRuzC4kQo" %}
[Marketplace Plugins](/developer-docs/marketplace)
{% endcontent-ref %}

### SDK

Build applications that create and manage Vultisig vaults programmatically using the TypeScript SDK.

* **Language**: TypeScript
* **Best for**: Building apps with embedded vault functionality, custodial services, or portfolio management

{% content-ref url="/pages/wmX4xojbg9FnrrhCOGPW" %}
[SDK](/developer-docs/vultisig-sdk)
{% endcontent-ref %}

### Extension Integration

Add Vultisig wallet connectivity to your web application, similar to MetaMask integration.

* **Language**: JavaScript
* **Best for**: dApp developers adding wallet connect functionality

{% content-ref url="/pages/mSxWzJwi1nOR082ENqLs" %}
[Extension Integration](/developer-docs/vultisig-extension-integration-guide)
{% endcontent-ref %}

## Core Technology

New to Vultisig's architecture? These resources explain the underlying security model:

* [How TSS Works](/security-and-technology/tss-actions) - Threshold signature scheme overview
* [How DKLS23 Works](/security-and-technology/how-dkls23-works) - The signing protocol
* [Vultiserver](/infrastructure/what-is-vultisigner) - Fast vault infrastructure

## Support

Questions or need help getting started? Join our developer community:

* **Discord**: [discord.gg/Cugw9T2NrP](https://discord.gg/Cugw9T2NrP) - Dedicated third-party developer section
* **GitHub**: [github.com/vultisig](https://github.com/vultisig) - Source code and issue tracking


# AI Agents

Build AI agents with multi-chain wallet capabilities and choose exactly how much signing authority they receive.

Vultisig gives AI agents a programmable, seedless wallet across 40+ blockchains. Agents can inspect portfolios, prepare transactions, send assets, swap across chains, and sign messages without ever holding a complete private key.

The defining choice is not whether an agent can transact. It is **how much authority the agent should have**.

## Why Vultisig for agents?

Vultisig supports multiple signing models through the same multi-chain MPC infrastructure, so developers can match an agent's authority to the workflow.

| Operating model                 | Best for                                                      | Signing authority                                                                |
| ------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| **Autonomous Fast Vault**       | Bots and services that must transact without a person present | The agent and VultiServer each hold one share of a 2-of-2 MPC vault              |
| **Policy-bound automation**     | Autonomous strategies with explicit user limits               | A Marketplace plugin proposes; the Verifier enforces the configured rules        |
| **Human-approved Secure Vault** | Higher-value workflows requiring approval                     | The configured threshold of human-controlled devices joins every signing session |

Use the least authority that still lets the workflow succeed. See [Authority and security](/developer-docs/ai-agents/authority-and-security) for the full decision guide.

## What agents can do

### Portfolio intelligence

> "Summarize my holdings across Bitcoin, Ethereum, Solana, and Cosmos."

Query addresses, native and token balances, and fiat values without signing a transaction.

### Preview and execute transactions

> "Prepare a 0.1 ETH transfer, show me the fee and total, then wait for approval."

Prepare and inspect transaction details before entering the selected signing flow.

### Cross-chain swaps

> "Swap 0.1 ETH to BTC using the best available route."

Request quotes and execute swaps through supported providers such as THORChain, 1inch, KyberSwap, and LiFi.

### Policy-bound strategies

> "Rebalance when BTC moves outside 45-55% of the portfolio, but never trade more than $500 per day."

Marketplace agents can monitor conditions and propose transactions while a Verifier enforces the user's rules.

## Start building

* **Give any agent a wallet (start here):** the [CLI](/developer-docs/vultisig-sdk/cli) is the fastest path — structured JSON, stable exit codes, and a natural-language `agent ask` mode built for AI-to-AI use. It runs unattended in non-interactive environments with no extra setup.
* **Embed wallet logic into your own service:** integrate the [TypeScript SDK](/developer-docs/vultisig-sdk).
* **Publish constrained autonomous strategies:** build a [Marketplace plugin](/developer-docs/marketplace).
* **Choose the right approval model:** read [Authority and security](/developer-docs/ai-agents/authority-and-security).
* **Compare the available developer surfaces:** read [Integration options](/developer-docs/ai-agents/integration-options).


# Authority and Security

Choose between autonomous, policy-bound, and human-approved agent signing models with Vultisig.

MPC removes the complete private key as a single point of failure. It does not make an agent's decisions correct. Choose a signing model based on the value at risk, the workflow's speed requirements, and the controls that must remain outside the agent.

## Compare signing models

### Autonomous Fast Vault

A Fast Vault combines an agent-controlled share with a VultiServer share. The agent can sign without a person present.

**Use when:** the workflow requires unattended execution and the vault can be funded according to a defined risk budget.

**Primary controls:** isolated vaults, limited funding, protected credentials, transaction previews, monitoring, and tested backups.

### Policy-bound Marketplace automation

A Marketplace plugin proposes unsigned transactions. The Verifier checks each proposal against the user's configured policy before participating in MPC signing.

**Use when:** an autonomous strategy should operate inside explicit limits, such as allowed assets, destinations, amounts, or timing.

**Primary controls:** narrowly scoped rules, Verifier policy validation, plugin review, monitoring, and the ability to disable the automation.

### Human-approved Secure Vault

A Secure Vault requires the configured threshold of devices to join each signing session. In a human-approved setup, the agent prepares the action and the human-controlled shares complete the signing threshold.

**Use when:** every transaction requires human review or multiple participants must approve.

**Primary controls:** transaction review, device separation, threshold configuration, backups, and clear approval procedures.

## Responsibilities that remain with the developer

Your application remains responsible for:

* Prompt and tool-call security
* Strategy logic and economic outcomes
* Token, contract, route, and destination selection
* Transaction parameters and fee limits
* Vault passwords, backups, logs, and runtime credentials
* Monitoring, incident response, and disabling compromised agents

## Recommended controls

* Start with read-only portfolio access.
* Require previews before enabling signing.
* Use separate vaults for separate agents or strategies.
* Fund autonomous vaults only to an explicit risk budget.
* Prefer policy-bound automation when rules can constrain the workflow.
* Prefer Secure Vaults for high-value or irreversible actions.
* Treat arbitrary message and byte signing as high-risk capabilities.
* Never embed vault passwords or backups in prompts, source code, or logs.

{% hint style="warning" %}
Fast Vaults enable unattended signing. Only grant an agent the assets and capabilities its workflow requires.
{% endhint %}


# Integration Options

Choose between the Vultisig CLI, TypeScript SDK, Marketplace plugins, and MCP tooling for AI agent integrations.

## CLI (start here)

The CLI is the fastest way to give an AI agent a wallet. Any agent that can run shell commands gets multi-chain balances, sends, swaps, and signing — through structured JSON, stable exit codes, and a natural-language `agent ask` mode built for AI-to-AI use. No SDK build step, no embedding.

```bash
npm install -g @vultisig/cli

# Structured wallet commands
vultisig portfolio --output json
vultisig swap-quote ethereum bitcoin 0.1 --output json
vultisig swap ethereum bitcoin 0.1 --output json

# Natural-language, one-shot — designed for AI agent integration
vultisig agent ask "What is my ETH balance?" --password "$VAULT_PASSWORD" --json
```

The CLI auto-detects non-interactive (non-TTY) environments and skips the prompts that would otherwise hang an agent, so the same commands run unattended in scripts and pipelines. Set `VAULT_PASSWORD` to avoid interactive password entry, and branch on the documented exit codes and error codes for reliable orchestration.

See the [CLI reference](/developer-docs/vultisig-sdk/cli), including the AI agent integration guide.

## TypeScript SDK

Use `@vultisig/sdk` when you are embedding wallet capabilities directly into your own agent, bot, or service in TypeScript. The SDK handles vault creation, balances, portfolio tracking, sends, swaps, message signing, and transaction broadcasting.

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

const sdk = new Vultisig()
await sdk.initialize()

const vault = await sdk.getActiveVault()
if (!vault) throw new Error('No active vault')

const portfolio = await vault.portfolio('usd')
const preview = await vault.send({
  chain: Chain.Ethereum,
  to: '0xRecipient',
  amount: '0.1',
  dryRun: true,
})
```

Start with the [SDK guide](/developer-docs/vultisig-sdk) and [implementation guide](/developer-docs/vultisig-sdk/sdk-users-guide).

## Marketplace plugins

Use a Marketplace plugin when an agent should act within user-defined rules instead of receiving broad wallet authority. The plugin proposes an unsigned transaction; the Verifier checks the proposal before participating in signing.

Start with the [Marketplace developer docs](/developer-docs/marketplace).

## Agent discovery resources

| Resource                                                  | Purpose                                                                                                    |
| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| [SKILL.md](https://vultisig.com/SKILL.md)                 | Operating instructions for balances, sends, swaps, gas estimation, and vault workflows                     |
| [llms.txt](https://vultisig.com/llms.txt)                 | Compact documentation index                                                                                |
| [llms-full.txt](https://vultisig.com/llms-full.txt)       | Full SDK context and examples                                                                              |
| [agent.json](https://vultisig.com/.well-known/agent.json) | Structured capabilities manifest                                                                           |
| [MCP server](https://github.com/vultisig/mcp)             | MCP tools for multi-chain queries, unsigned transaction building, DeFi interactions, and plugin management |


# Marketplace Plugins

Build automation plugins that run on Vultisig's infrastructure and distribute them through the Marketplace. Plugins leverage Vultisig's MPC technology to execute transactions on behalf of users while maintaining self-custody—users never give up their private keys.

## Getting Started

1. **Understand the architecture**: Learn [what a plugin is](/developer-docs/marketplace/plugins) and how the [services](/developer-docs/marketplace/services) work together
2. **Build your plugin**: Follow the [quick start guide](/developer-docs/marketplace/basics-quick-start) and reference the [App Recurring](https://github.com/vultisig/app-recurring) plugin
3. **Submit for review**: Complete the [submission process](/developer-docs/marketplace/submission-process) to list on the Marketplace

## Documentation

### Architecture

* [What is a Plugin](/developer-docs/marketplace/plugins) - Core concepts and security model
* [Services Architecture](/developer-docs/marketplace/services) - HTTP Server, Worker, Scheduler, TX Indexer
* [Policy Rules](/developer-docs/marketplace/metarules) - MetaRules and Direct Rules for transaction validation
* [Infrastructure Overview](/developer-docs/marketplace/infrastructure) - System components and interactions

### Building

* [Quick Start](/developer-docs/marketplace/basics-quick-start) - Step-by-step guide to your first plugin
* [Build Your Plugin](/developer-docs/marketplace/build-your-plugin) - Detailed developer guide
* [Adding a New Chain](/developer-docs/marketplace/build-your-plugin/adding-a-new-chain) - Extend chain support

### Publishing

* [Submission Process](/developer-docs/marketplace/submission-process) - Review and approval workflow
* [Revenue](https://github.com/vultisig/docs/blob/main/developer-docs/marketplace/infrastructure-overview/revenue.md) - Fee structures and 70/30 revenue split

## Reference Implementation

The [App Recurring](https://github.com/vultisig/app-recurring) plugin is the official reference implementation. Clone it as a starting point for your own development.

Each plugin is an independent service — you define your own recipe (transaction rules), authentication flow, and business logic. The reference plugin shows integration patterns, but your plugin can be structured however you need.

## Support

* **Discord**: [discord.gg/Cugw9T2NrP](https://discord.gg/Cugw9T2NrP) - Join the third-party developer section
* **GitHub**: [github.com/vultisig](https://github.com/vultisig) - Source code and issues


# What is a Plugin

Vultisig plugins are vault automation workflows created by Vultisig or third-party developers that enable automatic on-chain interactions for users. Due to Vultisig's use of MPC technology, these plugins are not limited by any specific chain, action, or protocol interaction. This gives developers the freedom to design secure, self-custodial automations without users giving up private keys or granting full access to wallet funds.

## How Plugins Work

A plugin operates as a trusted automation layer between the user and the blockchain:

1. **User Installs Plugin**: The user selects a plugin from the Marketplace and configures their automation (e.g., "buy $100 of ETH every week")
2. **Policy Creation**: The plugin creates a policy—a signed set of rules defining exactly what transactions are allowed
3. **Verifier Validation**: When the plugin wants to execute a transaction, it submits it to the Verifier, which checks it against the user's policy
4. **TSS Signing**: If compliant, the Verifier participates in a threshold signing ceremony to approve the transaction
5. **Broadcast**: The plugin broadcasts the signed transaction to the blockchain

```
┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│     User     │     │   Plugin     │     │   Verifier   │
│              │     │              │     │              │
│ • Installs   │────►│ • Runs logic │────►│ • Validates  │
│ • Configures │     │ • Builds txs │     │ • Signs      │
│ • Sets rules │     │ • Broadcasts │     │              │
└──────────────┘     └──────────────┘     └──────────────┘
```

## Plugin Independence

Every plugin is a standalone, independent service. There is no shared runtime or plugin framework that constrains what you build. Each plugin:

* **Runs its own infrastructure** — your own HTTP server, workers, database, and task queue
* **Defines its own recipe** — the rules and constraints governing what transactions it can request
* **Sets its own auth and configuration** — each plugin determines what users need to configure and how policies are structured
* **Controls its own business logic** — DCA schedules, AI trading strategies, payroll batches, or anything else you design

The [App Recurring](https://github.com/vultisig/app-recurring) plugin is a reference starting point, not a rigid template. The Vultisig ecosystem provides the security layer (Verifier + TSS signing) and distribution (Marketplace). Everything else is yours to build.

Users must configure policies specific to each installed plugin. A DCA plugin's policies look different from a payroll plugin's policies. Your plugin's `Suggest()` function guides users toward the right rules and constraints for your specific use case.

## Key Security Properties

**Self-Custodial**: Users never give up their private keys. Plugins cannot access funds outside the defined policy rules.

**Policy-Bound**: Every transaction must match the policy the user signed. A plugin configured for "weekly ETH buys" cannot suddenly drain the wallet.

**Multi-Party Signing**: Transactions require TSS coordination—the plugin alone cannot sign transactions without the Verifier's participation.

**Transparent Rules**: Policies use a rules system (MetaRules and Direct Rules) that maps to specific blockchain operations, making permissions auditable.

## Types of Plugins

| Category                | Examples                         | Description                                    |
| ----------------------- | -------------------------------- | ---------------------------------------------- |
| **DeFi Automation**     | DCA, yield farming, rebalancing  | Recurring or conditional trading strategies    |
| **AI Agents**           | Trading bots, portfolio managers | Autonomous agents with constrained permissions |
| **Treasury Management** | Multi-sig ops, payroll           | Organizational fund management                 |
| **Cross-Chain**         | Bridge automation, arbitrage     | Operations spanning multiple blockchains       |

## Plugin Components

A complete plugin consists of:

| Component         | Purpose                                                           | Required |
| ----------------- | ----------------------------------------------------------------- | -------- |
| **HTTP Server**   | API endpoints for reshare, sign, and automation management        | Yes      |
| **Specification** | Defines UI, validation rules, and supported operations            | Yes      |
| **Worker**        | Background processing for TSS signing and transaction monitoring  | Yes      |
| **Trigger**       | Initiates transactions (scheduler, event listener, HTTP endpoint) | Varies   |

See [Services Architecture](/developer-docs/marketplace/services) for detailed component documentation.

## Reference Implementation

The [App Recurring](https://github.com/vultisig/app-recurring) plugin is the reference implementation for building Vultisig plugins. Use it as a starting point — not a template you must follow. Your plugin defines its own recipe, configuration flow, and business logic.


# Services Architecture

## TL;DR

The Vultisig app ecosystem uses a distributed architecture with four core services: **HTTP Server** (API interface and app management), **Worker Service** (asynchronous transaction processing), **Scheduler Service** (time-based triggers and recurring operations), and **Transaction Indexer** (blockchain monitoring and event processing). These services communicate through Redis queues and interact with Vultisig's managed Verifier infrastructure for TSS-based transaction signing. To build your own app, implement the HTTP Server and transaction logic locally, import the Scheduler and TX Indexer from the verifier package, test against local Vultisig infrastructure, then submit an app configuration YAML for production deployment where only your custom services run while the [Verifier](https://github.com/vultisig/verifier) and [Fee App](https://github.com/vultisig/feeplugin) remain Vultisig-managed. Key packages include `github.com/vultisig/verifier/plugin`, `github.com/vultisig/recipes/engine`, `github.com/hibiken/asynq` for queuing, and blockchain-specific clients for EVM, Solana, and Bitcoin networks.

## Overview

The Vultisig app ecosystem is built on a distributed architecture with specialized services that handle different aspects of automated transaction processing. Each service has distinct responsibilities and communicates through well-defined interfaces to ensure security, scalability, and maintainability.

## Core Services Architecture

![](/files/qh5LppIgBXcA5uyGBH1f)

This is a diagram of the verifier's components, but in general all apps have the same structure

***

## Service Components

### 1. HTTP Server

The HTTP Server is the primary interface for external interactions and app management.

**Responsibilities:**

* Handle API requests from users and external systems
* Manage app installation and configuration
* Serve automation creation and management endpoints
* Provide real-time status and monitoring information
* Handle authentication and authorization

**Key API Endpoints:**

```go
// Plugin Management
pluginGroup.POST("/policy", s.CreatePluginPolicy)
pluginGroup.PUT("/policy", s.UpdatePluginPolicyById)
pluginGroup.DELETE("/policy/:policyId", s.DeletePluginPolicyById)
pluginGroup.GET("/recipe-specification", s.GetRecipeSpecification)

// Vault Operations
vaultGroup.POST("/reshare", s.ReshareVault)
vaultGroup.GET("/get/:pluginId/:publicKeyECDSA", s.GetVault)
vaultGroup.GET("/exist/:pluginId/:publicKeyECDSA", s.ExistVault)
vaultGroup.DELETE("/:pluginId/:publicKeyECDSA", s.DeleteVault)

// Transaction Management
vaultGroup.POST("/sign", s.SignMessages)
vaultGroup.GET("/sign/response/:taskId", s.GetKeysignResult)
```

**Technology Stack:**

* **Framework**: Echo (Go HTTP framework)
* **Authentication**: JWT tokens
* **Validation**: Custom middleware for request validation
* **Monitoring**: Built-in health check endpoints

**Configuration Example:**

```json
{
  "server": {
    "host": "0.0.0.0",
    "port": "8080",
    "read_timeout": "30s",
    "write_timeout": "30s"
  },
  "cors": {
    "allowed_origins": ["*"],
    "allowed_methods": ["GET", "POST", "PUT", "DELETE"],
    "allowed_headers": ["*"]
  }
}
```

***

### 2. Worker Service

The Worker Service handles asynchronous job processing and transaction execution.

**Responsibilities:**

* Process transaction signing requests
* Execute scheduled tasks and recurring operations
* Handle retry logic for failed operations
* Manage resource-intensive computations
* Coordinate with the Verifier for TSS operations

**Job Processing Pipeline:**

1. **Job Reception**: Receive jobs from Redis queue
2. **Validation**: Validate job parameters and automation compliance
3. **Transaction Construction**: Build blockchain transactions using Recipes
4. **Signing Request**: Request signature from Verifier
5. **Broadcasting**: Submit signed transactions to blockchain networks
6. **Result Handling**: Process results and update job status

**Key Features:**

* **Concurrency Control**: Configurable worker pools
* **Error Handling**: Automatic retry with exponential backoff
* **Resource Management**: Memory and CPU usage monitoring
* **Monitoring**: Job processing metrics and logging

***

### 3. Scheduler Service

The Scheduler Service manages time-based triggers and recurring operations.

**Responsibilities:**

* Queue periodic tasks (subscriptions, recurring payments)
* Manage execution timing and frequency
* Handle rate limiting and throttling
* Coordinate with business logic for trigger conditions
* Maintain scheduling state and persistence

**Scheduling Patterns:**

* **Fixed Intervals**: Execute every N seconds/minutes/hours
* **Cron-like Scheduling**: Complex time-based triggers
* **Event-driven**: Triggered by blockchain events or external conditions
* **Rate Limited**: Ensure compliance with automation rate limits

**Implementation:**

```go
type SchedulerConfig struct {
    MaxTxsPerWindow     int           `json:"max_txs_per_window"`
    RateLimitWindow     time.Duration `json:"rate_limit_window"`
    CheckInterval       time.Duration `json:"check_interval"`
    EnabledScheduleJobs []string      `json:"enabled_schedule_jobs"`
}
```

**Example Usage:**

```go
// Schedule a recurring payment
scheduler.ScheduleRecurring(ScheduleRequest{
    PolicyID:    "policy-123",
    Interval:    24 * time.Hour,
    StartTime:   time.Now().Add(time.Hour),
    JobType:     JobTypeScheduledPayment,
    Parameters:  paymentParams,
})
```

***

### 4. Transaction Indexer

The Transaction Indexer monitors blockchain networks and processes relevant events.

**Responsibilities:**

* Monitor blockchain networks for transaction confirmations
* Index app-related transactions and events
* Trigger post-transaction processing
* Maintain transaction history and state
* Provide blockchain data for business logic

**Supported Networks:**

* **EVM Chains**: Ethereum, Polygon, Arbitrum, Base, Optimism, Avalanche, BSC, Blast, Cronos, zkSync, Mantle, Sei (and other EVM chains as supported)
* **UTXO Chains**: Bitcoin, Litecoin, Dogecoin, Bitcoin Cash, Dash, Zcash
* **Solana**: Program logs and account changes
* **THORChain / MayaChain**: Cross-chain transaction tracking
* **Other**: XRP, Tron

**Event Processing:**

```go
type EventProcessor interface {
    ProcessBlock(ctx context.Context, blockHeight uint64) error
    ProcessTransaction(ctx context.Context, txHash string) error
    ProcessEvent(ctx context.Context, event BlockchainEvent) error
    GetLatestBlock(ctx context.Context) (uint64, error)
}
```

**Key Features:**

* **Real-time Monitoring**: WebSocket connections for live updates
* **Historical Indexing**: Backfill missed blocks during downtime
* **Multi-chain Support**: Unified interface across different blockchains
* **Reliable Processing**: Checkpoint-based progress tracking

***

## Service Interaction Patterns

```mermaid
sequenceDiagram
    participant Scheduler
    participant Worker
    participant Indexer
    participant Verifier

    Scheduler->>Scheduler: Check Schedule
    Scheduler->>Worker: Queue Scheduled Job
    Worker->>Verifier: Request Policy Validation
    Verifier->>Worker: Validate and Sign
    Worker->>Worker: Execute Transaction
    Worker->>Indexer: Report Completion
    Indexer->>Scheduler: Update Next Schedule
```

## Building Your Own App Services

### Service Deployment Model

**For Development and Testing:**

* Developers can run local instances of all services including Verifier and Fee App
* Use provided Docker configurations for local development
* Test your app against local Vultisig infrastructure

**For Production Deployment:**

* Only your custom app services (HTTP Server, Worker, Scheduler, TX Indexer) are deployed
* Verifier and Fee App remain Vultisig-managed infrastructure
* Submit app configuration YAML for review and approval

### App Proposal Process

To deploy your app to production:

1. **Develop and Test Locally** using the full Vultisig stack
2. **Prepare App Configuration YAML** (see App Configuration section below)
3. **Submit App Proposal** to Vultisig for review
4. **Security Review** by Vultisig team
5. **Production Deployment** on approved infrastructure

### Required Components

To build a complete app, you need to implement these core components:

#### 1. HTTP Server for core functionality (reshare, automations, etc.)

For reference, you may use [app-recurring](https://github.com/vultisig/app-recurring)

#### 2. TX preparation and proposing logic

Do it in accordance with user's signed automations

#### 3. Scheduler and Tx indexer

You can import it from verifier package

### Essential Packages

#### Core Packages

```go
// Verifier integration
"github.com/vultisig/verifier/plugin"
"github.com/vultisig/verifier/plugin/server"
"github.com/vultisig/verifier/plugin/policy"
"github.com/vultisig/verifier/vault"

// Recipes for blockchain integration
"github.com/vultisig/recipes/engine"
"github.com/vultisig/recipes/types"
"github.com/vultisig/recipes/sdk/evm"

// Queue management
"github.com/hibiken/asynq"

// Database
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgxpool"

// HTTP framework
"github.com/labstack/echo/v4"
```

#### Blockchain Clients

```go
// EVM chains
"github.com/ethereum/go-ethereum/ethclient"

// Solana
"github.com/gagliardetto/solana-go"
"github.com/gagliardetto/solana-go/rpc"

// Bitcoin
"github.com/btcsuite/btcd/rpcclient"
```


# Policy Rules

## TL;DR

Vultisig's automation engine uses two rule types: **MetaRules** (high-level like `ethereum.send` or `solana.swap`) that automatically expand to protocol-specific implementations, and **Direct Rules** (low-level, ABI/IDL-mapped like `ethereum.erc20.transfer`) for precise control. Rules support seven constraint types (`FIXED`, `MAX`, `MIN`, `MAGIC_CONSTANT`, `ANY`, `REGEXP`, `UNSPECIFIED`) and use Magic Constants from `vultisig/recipes` for transparent address resolution. All app transactions require Verifier approval based on these rules before TSS signing.

## Overview

Vultisig's policy engine supports two rule types that govern how apps interact with blockchain networks:

* **MetaRules**: High-level, chain-agnostic abstractions automatically mapped to specific implementations.
* **Direct Rules**: Low-level, protocol-specific rules that strictly follow blockchain or contract semantics.

All app transactions must comply with these rules and be approved by the Verifier before signing.

***

## MetaRules: Protocol-Agnostic Abstractions

MetaRules summarize cross-chain actions (like send, swap) via simplified resource identifiers such as `{chain}.send`. The system expands these abstractions into concrete, protocol-specific Direct Rules tailored for each network.

### Example MetaRules

| MetaRule        | Expands to (Examples)                                               | Chains Supported |
| --------------- | ------------------------------------------------------------------- | ---------------- |
| `ethereum.send` | `ethereum.eth.transfer` (native), `ethereum.erc20.transfer` (ERC20) | Ethereum         |
| `solana.send`   | `solana.system.transfer`, `solana.spl_token.transfer`               | Solana           |
| `bitcoin.send`  | `bitcoin.btc.transfer`                                              | Bitcoin          |
| `ethereum.swap` | 1inch, Uniswap V2/V3 calls                                          | Ethereum         |
| `solana.swap`   | Jupiter aggregator calls                                            | Solana           |

### MetaRule Expansion (Go Example)

```go
func (m *MetaRule) TryFormat(resource string, constraints map[string]*types.Constraint) ([]string, error) {
	parts := strings.Split(resource, ".")
	if len(parts) != 2 {
		return nil, fmt.Errorf("invalid meta-rule format: %s", resource)
	}
	chain := parts[0]
	protocol := metaProtocol(parts[1])
	switch protocol {
	case send:
		return m.expandSendRule(chain, constraints)
	case swap:
		return m.expandSwapRule(chain, constraints)
	default:
		return nil, fmt.Errorf("unsupported meta-protocol: %s", protocol)
	}
}
```

***

## Direct Rules: Protocol-Specific Operations

Direct Rules are mapped directly to the target protocol's ABI (EVM) or IDL (Solana), providing fine-grained policy enforcement for app calls.

### Rule Structure (`protobuf`)

```protobuf
message Rule {
  string resource = 1;
  Effect effect = 2;
  string description = 3;
  map<string, Constraint> constraints = 4;
  Authorization authorization = 5;
  string id = 6;
  repeated ParameterConstraint parameter_constraints = 7;
  Target target = 13;
}
```

### Example Direct Rules

#### ERC-20 Transfer (Ethereum)

```json
{
  "resource": "ethereum.erc20.transfer",
  "effect": "EFFECT_ALLOW",
  "target": {
    "target_type": "TARGET_TYPE_ADDRESS",
    "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
  },
  "parameter_constraints": [
    {
      "parameter_name": "to",
      "constraint": {
        "type": "CONSTRAINT_TYPE_WHITELIST",
        "whitelist": ["0x742b15...a92E"],
        "required": true
      }
    }
  ]
}
```

#### Solana SPL Token Transfer

```json
{
  "resource": "solana.spl_token.transfer",
  "effect": "EFFECT_ALLOW",
  "parameter_constraints": [
    {
      "parameter_name": "amount",
      "constraint": {
        "type": "CONSTRAINT_TYPE_RANGE",
        "min_value": "1000000",
        "max_value": "100000000",
        "required": true
      }
    }
  ]
}
```

***

## Supported Blockchains & Protocols

| Chain        | Features Supported                       |
| ------------ | ---------------------------------------- |
| Ethereum     | ERC-20, Uniswap, 1inch, custom contracts |
| Bitcoin      | Native BTC transfers                     |
| Solana       | SPL tokens, Jupiter aggregator, Metaplex |
| Polygon      | Polygon bridges, DEXs                    |
| ARB, BSC etc | Layer2 & EVM-specific features           |
| THORChain    | Cross-chain liquidity/swaps              |
| XRPL         | XRP Ledger native operations             |

***

## Constraint Types

Based on `constraint.proto`:

| Type                              | Description                                               |
| --------------------------------- | --------------------------------------------------------- |
| CONSTRAINT\_TYPE\_FIXED           | Enforce fixed value for parameter                         |
| CONSTRAINT\_TYPE\_MAX             | Maximum allowed value                                     |
| CONSTRAINT\_TYPE\_MIN             | Minimum allowed value                                     |
| CONSTRAINT\_TYPE\_MAGIC\_CONSTANT | Special constant (system address, treasury, router, etc.) |
| CONSTRAINT\_TYPE\_ANY             | Accept any value                                          |
| CONSTRAINT\_TYPE\_REGEXP          | Regular expression match for string params                |
| CONSTRAINT\_TYPE\_UNSPECIFIED     | Not specified - usually treated as deny                   |

### Magic Constants

Magic Constants are **predefined system addresses and values** maintained in the `vultisig/recipes` library that provide standardized references to important protocol addresses, treasury wallets, and infrastructure endpoints. They enable transparent, auditable automations while simplifying the user experience.

| Name               | Value | Purpose                    |
| ------------------ | ----- | -------------------------- |
| VULTISIG\_TREASURY | 1     | Treasury address           |
| THORCHAIN\_VAULT   | 2     | Router/vault for THORChain |
| THORCHAIN\_ROUTER  | 3     | Router for THORChain swaps |

#### What Are Magic Constants?

Magic Constants are symbolic references that resolve to actual blockchain addresses or protocol-specific values at runtime. Instead of hardcoding addresses directly in rules or requiring users to input complex addresses, developers reference these constants by name, and the Vultisig system automatically resolves them to the correct values based on the target chain and current protocol state.

**Key characteristics:**

* **Centrally Defined**: All magic constants are defined and maintained in the `vultisig/recipes` repository, ensuring consistency across all apps
* **Chain-Aware**: The same constant can resolve to different addresses on different chains (e.g., VULTISIG\_TREASURY resolves to the appropriate treasury address for Ethereum, Solana, etc.)
* **Version-Safe**: When protocol addresses change (upgrades, migrations), constants are updated centrally without breaking existing app rules
* **Auditable**: Users can verify exactly which addresses are being used by inspecting the recipes library

#### When to Use Magic Constants

Use magic constants in these scenarios:

1. **Protocol Infrastructure Addresses**
   * DEX routers (Uniswap, THORChain, MayaChain, Jupiter)
   * Vault contracts
   * Official protocol treasury addresses
2. **Cross-Chain Operations**
   * Bridge contracts
   * Cross-chain routers
   * Liquidity pool addresses
3. **User-Friendly Automations**
   * When users shouldn't need to know specific addresses
   * For operations that always use the same infrastructure
   * To prevent user errors from incorrect address input

***

## Rule Development Guidelines

* **MetaRules**: Use for simple, cross-chain actions or consistent business logic.
* **Direct Rules**: Apply for advanced protocol features, fine-grained control, or where ABI details matter.
* **Constraints**: Use principle of least privilege; always review all allowed parameters and document constraints.
* **Testing**: Validate with protocol ABIs/IDLs and ensure all value constraints are respected before allow.
* **Magic Constants**: Use system-defined constants for seamless app integrations and parameter substitutions.


# Infrastructure

## Services and Modules

![Vultisig ecosystem](/files/RcrnF0oob8syoui6vAiD)

<table><thead><tr><th align="center">Component</th><th align="center" valign="middle">Role / Description</th></tr></thead><tbody><tr><td align="center"><strong>Recipes</strong></td><td align="center" valign="middle">Shared library and integration framework for standardized blockchain logic and protocol modules. Provides building blocks for apps and services to interact securely and consistently across supported blockchains.</td></tr><tr><td align="center"><strong>Fees</strong></td><td align="center" valign="middle">Fee calculation and treasury logic; enforces fee-related rules and automates processing for transactions and treasury operations. Utilized by apps and Verifier automations.</td></tr><tr><td align="center"><strong>Verifier</strong></td><td align="center" valign="middle">Centralizes automation management. Receives transaction requests from apps, validates them against custom automations, and performs TSS-based signing for compliant transactions. Does NOT initiate or broadcast transactions; strictly enforces rules and maintains security boundaries.</td></tr><tr><td align="center"><strong>App A/B/...</strong></td><td align="center" valign="middle">Applications that implement custom business logic or user-facing features. Compose and initiate transactions and handle broadcasting. Submit transactions to the Verifier for validation and signing, ensuring automation compliance.</td></tr><tr><td align="center"><strong>Blockchains</strong></td><td align="center" valign="middle">Supported external networks such as Bitcoin, Ethereum, Solana, etc. Recipes standardizes their interfaces for system-wide compatibility.</td></tr></tbody></table>

## Key Interactions

* All applications interface with [Recipes](https://github.com/vultisig/recipes) modules for standardized logic.
* Fee computations and treasury operations are funneled through the [Fees](https://github.com/vultisig/feeplugin) module.
* Every transaction is routed to the [Verifier](https://github.com/vultisig/verifier) for strict automation compliance and TSS signing.
* Blockchains are kept external, with all interaction managed through the Recipes abstraction layer.


# Quick Start

This guide provides a quick step-by-step walkthrough for building your first Vultisig plugin. By the end of this guide, all building blocks and how to integrate your application into the ecosystem

## Overview

### Components

There are multiple components needed for your Plugin to interact with the Marketplace and let users install your Plugin, get a complete overview [here](https://docs.vultisig.com/developer-docs/marketplace/infrastructure-overview/infrastructure):

* [Plugin Server](#plugin-server)
* [Plugin Specifications](#plugin-specifications)
* [Plugin Worker](#worker)
* [Triggers](#triggers)

{% hint style="info" %}
All basic building blocks can be found in our [hello-world](https://github.com/vultisig/docs/tree/main/developer-docs/marketplace/create-a-plugin/build-your-plugin/hello-world) section in the documentation and get be used to get started right away.
{% endhint %}

To integrate your application with the Vultisig ecosystem, you need to build an app that at least supports:

{% tabs fullWidth="false" %}
{% tab title="Mandatory" %}

* `/reshare` and `/sign` endpoints for TSS operations
* API structure for automation management
  {% endtab %}

{% tab title="Optional" %}

* Transaction indexing for monitoring blockchain confirmations
* Scheduler for time-based or event-driven automations
  {% endtab %}
  {% endtabs %}

***

## Plugin Server

### Getting Started with the Server

The fastest way to get started is to import the [`Server`](https://github.com/vultisig/docs/tree/main/developer-docs/marketplace/create-a-plugin/build-your-plugin/hello-world/server) component from the Vultisig library.

This provides all the necessary API infrastructure, including the required endpoints for signing, resharing, and automation management, so you don't need to implement them from scratch.

### Why use the built-in Server?

* **Handles TSS complexity**: All the cryptographic protocol complexity is abstracted away
* **Standardized endpoints**: Provides the exact API structure that the Vultisig Verifier expects
* **Built-in middleware**: Includes authentication, rate limiting, and error handling out of the box
* **Storage integration**: Automatically connects with Redis, PostgreSQL, and S3-compatible storage
* **Compatibility guarantee**: Ensures your plugin works seamlessly with the Vultisig mobile app and web interface

### Implementation

The server is your plugin's main entry point. It initializes all infrastructure components (database, cache, storage), sets up the automation engine, and starts the HTTP server to handle requests from the Vultisig ecosystem.

**Key responsibilities:**

* Set up S3-compatible storage for encrypted vault data (key shares)
* Apply database migrations automatically
* Register your plugin specification (capabilities and UI configuration)
* Create async task for worker(s)

**Full example**: [Server](https://github.com/vultisig/docs/blob/main/developer-docs/marketplace/create-a-plugin/build-your-plugin/hello-world/server/server.go)

***

## Plugin Specifications

### Defining Your Plugin Specification

The specification defines what your plugin does and how it appears in the Vultisig UI.

### What the Spec Does

* **UI Configuration**: Defines the form fields users see when creating an automation (e.g., asset selector, addresses, amounts)
* **Validation Rules**: Ensures user input meets your requirements before creating a policy
* **Permission Policies**: Translates high-level user intent into specific, security-constrained execution rules
* **Resource Declaration**: Tells the Verifier which blockchain operations your plugin can perform
* **Rate Limiting**: Sets transaction frequency limits to prevent abuse

### Key Components

* `GetRecipeSpecification()`: Returns JSON Schema for the UI form
* `ValidatePluginPolicy()`: Validates user input against your schema
* `Suggest()`: Converts user configuration into specific execution rules with constraints

**Full example**: [Specifications](https://github.com/vultisig/docs/blob/main/developer-docs/marketplace/create-a-plugin/build-your-plugin/hello-world/server/spec.go)

***

## Worker

### Setting Up the Worker

The worker process handles background tasks asynchronously, separate from the HTTP server. This architecture ensures that long-running cryptographic operations don't block API requests.

### Worker Responsibilities

* **TSS Signing**: Participates in multi-party signing ceremonies to approve transactions
* **Key Resharing**: Creates distributed key shares for enhanced security
* **Transaction Monitoring**: Tracks submitted transactions and updates their status
* **Task Queue Processing**: Consumes jobs from Redis queue using Asynq

### Architecture Benefits

Running the worker separately from the server provides:

* **Scalability**: Can run multiple worker instances for high throughput
* **Isolation**: Cryptographic operations don't impact API responsiveness
* **Retry Logic**: Failed tasks can be automatically retried
* **Monitoring**: Easy to track task queue depth and processing metrics

### Key Components

* Initializes the Vault Management Service for TSS operations
* Sets up Transaction Indexer to monitor blockchain confirmations
* Registers handlers for `TypeKeySignDKLS` and `TypeReshareDKLS` tasks
* Processes tasks with configurable concurrency (default: 10 parallel tasks)

**Full example**: [Worker](https://github.com/vultisig/docs/blob/main/developer-docs/marketplace/create-a-plugin/build-your-plugin/hello-world/worker/worker.go)

***

## Triggers

### Example: Transaction Trigger Implementation

The trigger service demonstrates **one possible implementation approach** for initiating transactions programmatically. This is not a required component, but serves as a reference for understanding the complete transaction lifecycle.

### What This Example Shows

* How to retrieve and decrypt vault data to derive blockchain addresses
* How to construct unsigned transactions using the EVM SDK
* How to create a `PluginKeysignRequest` and submit it to the TSS network
* How to broadcast signed transactions to the blockchain

{% hint style="success" %}

#### Important Note:

This is **not a prescriptive pattern**—it's one of many ways to trigger transactions. Your plugin might:

* Listen to blockchain events instead of HTTP requests
* Use a scheduler for recurring transactions
* React to price feeds, governance votes, or other external data
* Implement custom business logic specific to your use case
  {% endhint %}

The trigger example is provided to help you understand how the signing flow works end-to-end, not as a template you must follow.

**Full example**: [Trigger Code](https://github.com/vultisig/docs/blob/main/developer-docs/marketplace/create-a-plugin/build-your-plugin/hello-world/worker/tx.go)

***

## Next Steps

Now that you understand the basic structure, you can:

1. **Clone the example** [**repository**](https://github.com/vultisig/docs/tree/main/developer-docs/marketplace/create-a-plugin/build-your-plugin/hello-world) and modify it for your use case
2. **Define your plugin specification** with the chains and operations you need
3. **Implement your business logic** as part of the worker or create separate service
4. **Test locally** with local verifier and Marketplace UI


# Build Your Plugin

{% hint style="success" %}
**Reference Implementation**: The [App Recurring](https://github.com/vultisig/app-recurring) plugin is the official reference. Clone it as your starting point and modify for your use case.
{% endhint %}

### Introduction

This document provides a comprehensive guide for developers on how to integrate their applications into the Vultisig ecosystem. By following these instructions, you can build a plugin that leverages Vultisig's decentralized security infrastructure for transaction signing and management.

The guide covers mandatory requirements, optional features, project setup, and implementation details.

### Your Plugin, Your Rules

Your plugin is an independent Go service that you fully own and operate. The only integration points with Vultisig are:

1. **`/reshare` and `/sign` endpoints** — receive TSS key material and signing tasks
2. **Recipe specification** — define what transactions your plugin is allowed to request
3. **Policy validation** — validate user-configured policies match your schema

Beyond these three touch points, you have complete freedom. Your architecture, your triggers, your auth flow, your infrastructure.

***

### Core Integration Requirements

To ensure seamless integration with the Vultisig ecosystem, your application must meet several architectural requirements.

#### Mandatory Components

* **/reshare and /sign Endpoints**: Your application must expose these API endpoints to handle core TSS (Threshold Signature Scheme) operations for key resharing and transaction signing.
* **Automation API Support**: It must adopt the Vultisig API structure for managing and executing automations (policies).

#### Optional Components

* **Transaction Indexing**: You can optionally implement a service to index and track the status of transactions your application submits to the blockchain.
* **Scheduler**: A scheduler can be included to trigger time-based or event-driven actions, such as recurring transactions.

***

### Getting Started

To accelerate development, you can import the [`Server`](https://github.com/vultisig/verifier/tree/main/plugin/server) component from the [`github.com/vultisig/verifier/plugin`](https://github.com/vultisig/verifier/tree/main/plugin) package. This provides a pre-built foundation that includes all the necessary API structures.\
The main entry point of the service, `server/main.go`, is responsible for initializing and connecting all the essential components.

### Project Structure

The example code is organized into the following key packages:

* `/server`: The primary HTTP server that exposes the plugin's API endpoints.
* `/spec`: Defines the plugin's capabilities, supported blockchains, and policy validation rules.
* `/worker`: Manages asynchronous background jobs, such as transaction signing and resharing, using a task queue.
* `/trigger`: An example service for initiating transactions via an external HTTP request.

### Server Initialization (`server/main.go`)

The `main` function in `server/main.go` orchestrates the setup of your service by initializing and wiring together several key components:

* **Configuration**: Loads application settings from environment variables into a `struct` using the `envconfig` library.
* **Redis**: Establishes a connection to a Redis instance, which serves as both a cache and a message broker for `asynq`.
* **Asynq**: Initializes the `asynq` client and inspector, which are used to enqueue and manage asynchronous background tasks.
* **Block Storage (Vault)**: Connects to an S3-compatible object storage service (like Minio). This storage is used to securely store vault data containing the reshared keys required for signing.
* **PostgreSQL**: Connects to a PostgreSQL database used for storing automation policies and transaction data. Database migrations are applied automatically on startup.
* **Policy Service**: Initializes the service responsible for creating, validating, and managing automation policies.
* **HTTP Server**: Creates and starts the main web server (`server.NewServer`), which bundles all the services and middleware.

### Defining the Plugin Specification (`spec/`)

This part of the application defines your plugin's capabilities and how it is presented within the Vultisig user interface.

* **Constants**: You must define a `PluginID` (a unique ID provided by the Vultisig team), a `PluginName`, and a list of `supportedChains`.
* **GetRecipeSpecification**: This function defines the "recipe" for an automation, specifying the configurable properties that users will see in the UI (e.g., `asset`, `toAddress`, `amount`) using a JSON schema. You should also provide a `ConfigurationExample` to guide users.
* **ValidatePluginPolicy**: This function is a hook for validating the data that a user enters in the UI against your defined schema.
* **Suggest**: Based on a user's initial input, this function can suggest a complete policy configuration, including `Rules` (e.g., `ethereum.send`) and security parameters like rate limits (`MaxTxsPerWindow`).
* **buildSupportedResources**: This function generates a list of all resources and actions supported by the plugin, such as signing a transaction (`chain.send`), and the parameters required for each action.

### Asynchronous Worker (`worker/`)

The worker is a background process that handles time-consuming or asynchronous tasks, ensuring the main server remains responsive.

* **Initialization**: The worker connects to Redis to listen for jobs on the `asynq` queue, initializes a `TxIndexer` for monitoring transaction statuses, and sets up the `VaultService` for handling `/reshare` and `/sign` operations.
* **Task Handling**: It subscribes to task types like `tasks.TypeKeySignDKLS` and `tasks.TypeReshareDKLS`. When a task is received, the corresponding handler in `VaultService` is executed to perform the cryptographic operations.
* **Trigger Service**: The worker also initializes and runs the `trigger` service, which exposes an HTTP server to listen for external requests to create and sign transactions.

### Triggering Transactions (`trigger/`)

This module provides an example of how to programmatically initiate a signing request. It runs an HTTP server on port `:8090` with a `/trigger` endpoint.

#### Workflow

1. The `/trigger` endpoint receives a request with the policy `uuid`, `pubkey`, and transaction details like `toAddress` and `amount`.
2. It retrieves the encrypted vault from block storage using the policy information.
3. It constructs an unsigned transaction. In the example, it creates a native token transfer for Ethereum using `recipes/sdk/evm`.
4. It wraps the policy and transaction data into a `PluginKeysignRequest`.
5. It calls `signer.Sign()`, which dispatches the signing job to the Vultisig network and the local worker queue.
6. Once the transaction is signed, it broadcasts the completed transaction to the Ethereum network via an RPC endpoint.

***

### Build and Troubleshooting

#### Dependency Management

To ensure compatibility, you may need to add the following `replace` directives to your `go.mod` file:

```go
replace (
    github.com/agl/ed25519 => github.com/binance-chain/edwards25519 v0.0.0-20200305024217-f36fc4b53d43
    github.com/gogo/protobuf => github.com/gogo/protobuf v1.3.2
    nhooyr.io/websocket => github.com/coder/websocket v1.8.6
)
```

#### macOS Development

* If you encounter a `dyld[...] Library not loaded` error when running the application locally, you must set the `DYLD_LIBRARY_PATH` environment variable to the path of the `libgodkls.dylib` library. You can find the latest libraries at the [vultisig/go-wrappers](https://github.com/vultisig/go-wrappers) GitHub repository.
* **Example**: `export DYLD_LIBRARY_PATH=/path/to/your/libs`

#### Docker Build Performance

* Building the application in a Docker container can be very slow on ARM-based Macs (Apple Silicon) because of the compilation process for the underlying `dkls` cryptography library.
* For a more efficient development cycle, it is recommended to run the plugin service directly on your host machine and use Docker only for the other infrastructure components (e.g., PostgreSQL, Redis).


# Adding a New Chain

The how to steps to add a missing chains to the Marketplace ecosystem

## Overview

This document provides a high-level overview of the steps required to add support for a new blockchain across the Vultisig Marketplace ecosystem. The process involves multiple repositories and follows a dependency chain where each layer builds upon the previous.

{% hint style="info" %}
The process is unlikely due to Vultisig's constant increase in chain coverage for the Marketplace ecosystem.
{% endhint %}

***

Adding a new chain requires changes across five main repositories:

1. **vultisig-go** - Core address generation and chain definitions
2. **recipes** - Transaction parsing, validation rules, and policy engine
3. **verifier** - Transaction indexing and status monitoring
4. **app-recurring** - Automation services (send/swap execution)
5. **plugin-marketplace** - Frontend UI support

***

## Step by step Guide

*Note that if you run into any issues please contact us in the Vultisig discord.*

### 1. Vultisig-go (Foundation Layer)

**Purpose**: Provides the foundational chain definitions and address derivation logic.

#### What Needs to Be Added

**Chain Enumeration (`common/chain.go`)**

* Add the new chain to the `Chain` enum constant
* Add the chain to `chainToString` mapping for serialization
* Add the derivation path to `chainDerivePath` mapping (HD wallet path)
* Add the native symbol to `NativeSymbol()` method
* If EVM-compatible, add the chain ID to `EvmID()` method
* If EdDSA-based (like Solana, Sui), update `IsEdDSA()` method

**Address Generation (`address/`)**

* Create a new file (e.g., `newchain.go`) implementing address derivation
* Implement the address encoding specific to the chain (e.g., bech32, base58check, hex)
* Add the chain case to `GetAddress()` in `address.go` to route to the new implementation
* Create corresponding test file with address derivation test vectors

#### Trust Wallet Core Dependency

**Important**: Address generation may or may not require Trust Wallet Core support depending on the chain type:

* **ECDSA chains** (Bitcoin-like, EVM): Use `tss.GetDerivedPubKey()` from `mobile-tss-lib` for key derivation, then custom address encoding
* **EdDSA chains** (Solana, Sui, etc.): Typically use the root public key directly without derivation
* **Cosmos chains**: Use bech32 encoding with chain-specific HRP (human-readable prefix)
* **Custom curves**: May require Trust Wallet Core or custom implementation

The `mobile-tss-lib` package handles the TSS key derivation, while address encoding is typically implemented directly in vultisig-go.

***

### 2. Recipes (Policy & Validation Layer)

**Purpose**: Defines how transactions are parsed, validated, and what policy rules can be applied.

#### What Needs to Be Added

**Chain Implementation (`chain/{chaintype}/`)**

Create a new directory structure (or add to existing category like `utxo/`, `evm/`):

1. **`chain.go`** - Implements the `types.Chain` interface:
   * `ID()` - Unique chain identifier (lowercase, e.g., "zcash")
   * `Name()` - Human-readable name
   * `Description()` - Brief description
   * `SupportedProtocols()` - List of protocol IDs (e.g., \["zec"])
   * `ParseTransaction()` - Decode raw transaction bytes into structured format
   * `GetProtocol()` - Return protocol handler by ID
   * `ComputeTxHash()` - Compute transaction hash with signatures applied
2. **`decode.go`** - Transaction deserialization logic:
   * Parse raw transaction bytes into chain-specific transaction structure
   * Handle version detection, input/output parsing, signatures
3. **`protocol.go`** - Implements the `types.Protocol` interface:
   * Define supported functions (transfer, swap, etc.)
   * Implement `MatchFunctionCall()` for policy constraint validation
   * Extract and validate transaction parameters against policy rules

**Registry Registration (`chain/registry.go`)**

* Import the new chain package
* Add `RegisterChain(newchain.NewChain())` in `init()`

**Engine Implementation (`engine/{chaintype}/`)**

Create the rule evaluation engine:

1. **Engine struct** - Wraps chain-specific validation logic:
   * `Supports()` - Return true for the supported chain(s)
   * `Evaluate()` - Validate a transaction against policy rules
   * Parse transaction, extract parameters, check constraints
2. **Constraint validation** - Validate output addresses, amounts, data fields

**Engine Registry (`engine/registry.go`)**

* Import the new engine package
* Add engine registration in `NewChainEngineRegistry()`

#### Why Each Component Is Needed

| Component | Purpose                                                  |
| --------- | -------------------------------------------------------- |
| Chain     | Identifies the blockchain and routes to correct handlers |
| Protocol  | Defines what operations are possible (transfer, swap)    |
| Engine    | Validates transactions match allowed policy rules        |
| Decoder   | Parses raw bytes into structured transaction data        |

***

### 3. Verifier (Transaction Monitoring Layer)

**Purpose**: Tracks transaction status on-chain and computes final transaction hashes.

#### What Needs to Be Added

**TX Indexer Chain Implementation (`plugin/tx_indexer/pkg/chain/`)**

1. **`newchain.go`** - Implements `chain.Indexer` interface:
   * `ComputeTxHash()` - Compute transaction hash from proposed transaction and signatures
   * Typically wraps the recipes chain implementation

**RPC Client (`plugin/tx_indexer/pkg/rpc/`)**

1. **`newchain.go`** - Blockchain RPC client:
   * `GetTxStatus()` - Query transaction confirmation status
   * Return `TxOnChainPending`, `TxOnChainSuccess`, or `TxOnChainFailed`
   * Use appropriate API (native RPC, block explorer API like Blockchair, etc.)

**Chains List (`plugin/tx_indexer/chains_list.go`)**

* Register the new chain in the supported chains list
* Wire up the indexer and RPC client

#### What the Verifier Checks

The verifier performs several critical functions:

1. **Policy Validation** - Ensures transaction matches the approved policy rules
2. **Transaction Tracking** - Monitors transaction from proposal to confirmation
3. **Hash Computation** - Computes final transaction hash after signatures are applied
4. **Status Monitoring** - Polls blockchain for confirmation status

***

### 4. App-recurring (Automation Layer)

**Purpose**: Executes automated transactions (sends, swaps) based on scheduled policies.

#### What Needs to Be Added

**Network Package (`internal/{chain}/`)**

Create a new directory with:

1. **`types.go`** - Define chain-specific types:
   * `From` struct (address, amount, public key)
   * `To` struct (chain, asset ID, address)
   * `TxInput`, `TxOutput` structures
   * Any chain-specific interfaces (e.g., `TxBroadcaster`)
2. **`network.go`** - Network service orchestration:
   * Initialize all chain services
   * Provide `Send()` and `Swap()` entry points
   * Coordinate between services
3. **`send_service.go`** - Build send transactions:
   * `BuildTransfer()` - Create transaction outputs for a simple transfer
   * Handle change output calculation
4. **`swap_service.go`** - Build swap transactions:
   * `FindBestAmountOut()` - Query swap providers for best rate
   * Aggregate results from multiple providers
5. **`swap_provider.go`** - DEX/swap provider integration:
   * `MakeOutputs()` - Build transaction outputs for swap
   * Integrate with Thorchain, MayaChain, or other DEXs
6. **`signer_service.go`** - Transaction signing and broadcast:
   * `SignAndBroadcast()` - Coordinate TSS signing
   * Build keysign request with message hashes
   * Apply signatures and broadcast to network
7. **`client.go`** - Blockchain RPC client:
   * `GetUTXOs()` - Fetch unspent outputs (for UTXO chains)
   * `GetBalance()` - Query account balance
   * `BroadcastTransaction()` - Submit signed transaction
   * `GetFeeRate()` - Query current network fees
8. **`fee_provider.go`** - Fee estimation:
   * Query network for current fee rates
   * Calculate transaction fees
9. **`address.go`** (if needed) - Address utilities:
   * Address validation
   * Script generation (P2PKH, P2SH, etc.)

**Consumer Integration (`internal/recurring/consumer.go`)**

1. **Add Network to Consumer struct**:
   * Add field for the new chain's Network service
   * Add to `NewConsumer()` constructor
2. **Add pubkey-to-address helper**:
   * `newchainPubToAddress()` - Derive chain address from vault public key
3. **Add operation handlers**:
   * `handleNewchainSend()` - Execute send operations
   * `handleNewchainSwap()` - Execute swap operations
4. **Update handle() routing**:
   * Add chain detection in the main handler
   * Route to appropriate send/swap handler

**Worker Initialization (`cmd/worker/main.go`)**

* Initialize the new chain's Network service
* Add to DCA Consumer constructor
* Configure RPC endpoints and dependencies

**Supported Chains (`internal/recurring/spec.go`)**

* Add the chain to `supportedChains` slice
* This enables dynamic policy generation for the new chain

#### What the App Does

The app-recurring service:

1. **Schedules** - Triggers transactions based on policy schedule (hourly, daily, etc.)
2. **Builds Transactions** - Constructs appropriate transaction for send or swap
3. **Signs** - Coordinates TSS signing across vault participants
4. **Broadcasts** - Submits signed transaction to the blockchain
5. **Tracks** - Monitors transaction until confirmation

***

### 5. Plugin-marketplace (Frontend Layer)

**Purpose**: Provides the user interface for creating and managing policies.

#### What Needs to Be Added

**Chain Configuration (`src/utils/chain.ts`)**

1. **Add to chain category**:
   * For EVM: Add to `evmChains` and `evmChainInfo` with viem chain config
   * For UTXO: Add to `utxoChains`
   * For other: Add to `otherChains`
2. **Add ticker**: Add native token ticker to `tickers` mapping
3. **Add RPC URL** (if EVM): Add to `evmRpcUrls` mapping

**Storage (`src/storage/chain.ts`)**

* Usually no changes needed - uses the chain types from utils

**UI Components**

Depending on chain characteristics, may need:

* Token images in `public/tokens/`
* Chain-specific validation logic
* Custom UI for chain-specific features

***

### Summary Checklist

#### vultisig-go

* [ ] Add chain enum and mappings
* [ ] Implement address derivation
* [ ] Add tests with known test vectors

#### recipes

* [ ] Create chain implementation (ID, name, protocols)
* [ ] Implement transaction parser/decoder
* [ ] Create protocol with function definitions
* [ ] Implement constraint matching
* [ ] Create validation engine
* [ ] Register in chain and engine registries

#### verifier

* [ ] Create chain indexer for hash computation
* [ ] Create RPC client for status checking
* [ ] Register in chains list

#### app-recurring

* [ ] Create network package with all services
* [ ] Integrate swap provider (Thorchain/MayaChain if supported)
* [ ] Add to consumer with send/swap handlers
* [ ] Initialize in worker
* [ ] Add to supported chains list

#### plugin-marketplace

* [ ] Add chain definition
* [ ] Add ticker mapping
* [ ] Add any chain-specific UI components

***

### Chain Type Patterns

#### UTXO Chains (Bitcoin, Zcash, Litecoin, etc.)

* Require UTXO management (fetching, selection, change calculation)
* Transaction format: inputs referencing previous outputs, new outputs
* Typically use base58check or bech32 addresses
* May have chain-specific features (Zcash's shielded transactions, BCH's CashAddr)

#### EVM Chains (Ethereum, Arbitrum, Base, etc.)

* Simpler: single account model, no UTXO
* Use standard Ethereum address format (0x prefixed hex)
* Can share most infrastructure with existing EVM implementation
* Just need chain ID and RPC configuration

#### Account-Based Non-EVM (Solana, XRP, etc.)

* Account model but different transaction format
* May require chain-specific SDKs
* Often have unique address formats

***

### Testing Recommendations

1. **Unit Tests**: Address derivation from known test vectors
2. **Integration Tests**: Transaction building and parsing round-trips
3. **End-to-End Tests**: Full send/swap flow on testnet
4. **Policy Tests**: Constraint validation with various policy rules


# Submission & Revenue

### TL;DR

Submit your Vultisig plugin by joining Discord's third-party developer section, preparing a `plugin-config.yaml` with plugin details (ID, endpoint, supported chains, fees), and meeting security/performance requirements. The review includes basic sanity checks (documentation, config validity) for marketplace listing, with optional "Vultisig Approved" comprehensive audits available. Developers deploy and maintain their own infrastructure post-approval. Reference plugins include App Recurring for recurring buy automation and other standard/AI-agent categories.

***

## Overview

To launch your plugin in the Vultisig ecosystem, you must submit your plugin/agent for review and approval. After approval, developers are responsible for deploying and maintaining their own applications, ensuring uptime, scaling, and operational security outside of Vultisig core infrastructure.

Each plugin is an independent product. You define your own recipe (transaction rules), user configuration flow, and authentication requirements. Different plugins have different policies, constraints, and user experiences — this is by design.

{% hint style="info" %}
**Note:** Verifier and Fees are managed exclusively by Vultisig and run as core infrastructure services. All other plugins are deployed, operated, and updated directly by their respective developers.
{% endhint %}

{% hint style="danger" %}
Vultisig reserves the right to delist plugins that fail to perform or adhere to Vultisig's quality standards, or that introduce a risk of harming users.
{% endhint %}

***

## Official Plugin Examples

Below are typical plugin types found in Vultisig's ecosystem. Refer to them when designing your own submission:

| Plugin ID         | Title         | Description                      | Category | Endpoint                                           |
| ----------------- | ------------- | -------------------------------- | -------- | -------------------------------------------------- |
| vultisig-dca-0000 | Recurring buy | Dollar Cost Averaging automation | plugin   | <https://apps.vultisig.com/apps/vultisig-dca-0000> |

Marketplace supports both standard plugins with business logic or automation, and agent-based plugins for advanced trading and verification tasks.

***

## Submission Requirements

Create a detailed `plugin-config.yaml` describing:

* ID, title, description, and endpoint (if applicable)
* Category (app or ai-agent)
* Supported blockchains
* Payment requirements

Follow this example:

```
plugins:
  - id: vultisig-dca-0000
    title: DCA Plugin
    description: Dollar Cost Averaging automation plugin
    server_endpoint: https://dca.vultisigplugin.app
    category: plugin
```

***

## Submission Process

{% stepper %}
{% step %}

#### Join the developer discord

Join Discord at [discord.gg/Cugw9T2NrP](https://discord.gg/Cugw9T2NrP), navigate to dedicated section for third-party developers and get real-time support and feedback from the Vultisig team while building your plugin
{% endstep %}

{% step %}

#### Prepare submission

Prepare all necessary code and documentation, like YAML config and documentation.
{% endstep %}

{% step %}

#### Complete Checks

Complete the security checklist and performance requirements for APIs and resource use.
{% endstep %}

{% step %}

#### <mark style="color:orange;">Review and approval</mark>

The review process includes basic sanity checks covering documentation completeness, configuration validity, and automation structure.\
Plugins that pass these checks can be listed in the Marketplace.
{% endstep %}

{% step %}

#### <mark style="color:$info;">Optional: "Vultisig Approved"</mark>

Developers seeking a "Vultisig Approved" badge can request a comprehensive audit, which includes thorough security review, code audit, and performance testing.\
This optional deep audit requires additional resources and time. Use the example plugins above as references for best practices and compliance.
{% endstep %}

{% step %}

#### <mark style="color:$success;">Marketplace Listing</mark>

Once approved, your plugin is provisioned and listed in the Vultisig marketplace alongside other available Plugins. Those examples illustrate category standards, endpoint conventions, and API scope for production plugins.

Revenue sharing models are available for fee, subscription, and premium features, negotiated during approval. Plugin developers receive **70%** of all generated revenue, while **30%** is allocated to the $VULT token treasury to support ecosystem development and maintenance.
{% endstep %}
{% endstepper %}

***

## Support

Questions? Reach out via email, documentation portal, or the developer Discord for guidance on submission and best practices.

***


# Extension Integration

{% hint style="info" %}
**Extension vs SDK**: Use the Extension for web dApps where users connect their existing Vultisig wallet (like MetaMask integration). Use the [SDK](/developer-docs/vultisig-sdk) for building applications that create and manage vaults programmatically.
{% endhint %}

## Table of Contents

1. [Introduction](#introduction)
2. [Supported Chains](#supported-chains)
3. [How Vultisig Extension Works](#how-vultisig-extension-works)
4. [Supported Methods](#supported-methods)
   * [Ethereum](#ethereum-windowvultisigethereum)
   * [THORChain](#thorchain-windowthorchain-and-windowvultisigthorchain)
   * [Cosmos-Based Chains](#cosmos-based-chains-gaiachain-osmosis-kujira-dydx)
   * [Other Chains](#other-chains-windowchain-and-windowvultisigchain)
5. [Steps to Integrate with Vultisig Extension](#steps-to-integrate-with-Vultisig-Extension)
   * [1. Detect Vultisig Extension Support](#1-detect-Vultisig-Extension-support)
   * [2. Connecting to Vultisig Extension](#2-connecting-to-Vultisig-Extension)
   * [3. Connected Accounts](#3-connected-accounts)
   * [4. Managing Active Chain](#4-managing-active-chain)
   * [5. Handling Transactions](#5-handling-transactions)
6. [Custom Message Signing](#6-custom-message-signing)
7. [Querying Transactions](#7-querying-transactions)
8. [Event Handling](#8-event-handling)
9. [Get Vault](#9-get-vault)
10. [Detailed Implementation Examples](#10-detailed-implementation-examples)
11. [Summary](#summary)

***

## Introduction

Vultisig Extension is a Chrome extension that enhances the experience of interacting with decentralized finance (DeFi) applications. It offers a secure way for users to connect with decentralized applications without storing private keys in their browsers. Vultisig Extension introduces:

* **`window.vultisig.ethereum`** for Ethereum integrations (previously `window.vultisig`).
* **`window.vultisig.thorchain` and `window.thorchain`** for THORChain support.
* A MetaMask-compatible interface (`window.ethereum`) to ensure seamless integration with existing DeFi applications.
* Support for multiple other chains including MayaChain, GaiaChain, Osmosis, Kujira, DyDx, BitcoinCash, Dash, DogeCoin, LiteCoin, and Bitcoin.

## Supported Chains

Vultisig Extension currently supports the following chains:

| Chain       | Identifier            |
| ----------- | --------------------- |
| Bitcoin     | `0x1f96`              |
| BitcoinCash | `0x2710`              |
| Dash        | `Dash_dash`           |
| DogeCoin    | `0x7d0`               |
| DyDx        | `dydx-1`              |
| Ethereum    | `0x1`                 |
| GaiaChain   | `cosmoshub-4`         |
| Kujira      | `kaiyo-1`             |
| LiteCoin    | `Litecoin_litecoin`   |
| MayaChain   | `MayaChain-1`         |
| Osmosis     | `osmosis-1`           |
| Polkadot    | `Polkadot_polkadot`   |
| Ripple      | `Ripple_ripple`       |
| Solana      | `Solana_mainnet-beta` |
| THORChain   | `Thorchain_thorchain` |
| Zcash       | `Zcash_zcash`         |

## How Vultisig Extension Works

* **Private Key Security**: Vultisig Extension does not store private keys. Instead, transactions are converted to QR codes that users can scan and sign using VultiSig peer devices.
* **Compatibility**: The extension provides:
  * `window.ethereum` for MetaMask-compatible Ethereum integration.
  * `window.vultisig.ethereum` for Vultisig-Extension-enhanced Ethereum features.
  * `window.vultisig.thorchain` and `window.thorchain` for THORChain functionality.
  * Additional chain support for other chains using `window.vultisig.chain` and `window.chain`.

## Supported Methods

### Ethereum (`window.vultisig.ethereum`)

* **Account Management**:
  * `eth_accounts`
  * `eth_requestAccounts`
* **Chain Management**:
  * `eth_chainId`
  * `wallet_addEthereumChain`
  * `wallet_switchEthereumChain`
* **Transaction Management**:
  * `eth_sendTransaction`
  * `eth_getTransactionByHash`
  * `eth_estimateGas`
* **Other Methods**:
  * `eth_blockNumber`
  * `eth_call`
  * `eth_gasPrice`
  * `eth_getBalance`
  * `eth_getBlockByNumber`
  * `eth_getCode`
  * `eth_getTransactionCount`
  * `eth_getTransactionReceipt`
  * `eth_maxPriorityFeePerGas`
  * `personal_sign`

### THORChain (`window.vultisig.thorchain` and `window.thorchain`)

* **Account Management**:
  * `request_accounts`
  * `get_accounts`
* **Transaction Management**:
  * `send_transaction`
  * `deposit_transaction`
  * `get_transaction_by_hash`

### Solana (`window.vultisig.solana` and `window.solana`)

* **Account Management**:
  * `request_accounts`
  * `get_accounts`
* **Transaction Management**:
  * `send_transaction`
  * `get_transaction_by_hash`

### Cosmos-Based Chains (DyDx, GaiaChain, Kujira, Osmosis)

* **Account Management**:
  * `request_accounts`
  * `get_accounts`
  * `chain_id`
* **Chain Management**:
  * `wallet_add_chain`
  * `wallet_switch_chain`
* **Transaction Management**:
  * `send_transaction`
  * `get_transaction_by_hash`
* **Notes**: Accessing a specific Cosmos-based chain (such as Kujira or Osmosis) requires calling `chain_id` to retrieve the active chain's ID or using `wallet_add_chain` and `wallet_switch_chain` to add or switch to the desired chain.

### Other Chains (`window.vultisig[chain]` )

* **Account Management**:
  * `request_accounts`
  * `get_accounts`
* **Transaction Management**:
  * `send_transaction`
  * `get_transaction_by_hash`

#### Supported Chains

The following chains are fully supported through their respective interfaces:

* Bitcoin
* BitcoinCash
* Dash
* DogeCoin
* LiteCoin
* MayaChain

## Steps to Integrate with Vultisig Extension

### 1. Detect Vultisig Extension Support

```javascript
if (window.vultisig?.ethereum) {
  console.log("Vultisig Extension Ethereum provider is available!");
  // Integration logic for Ethereum
} else if (window.ethereum) {
  console.log("Ethereum provider available (MetaMask or Vultisig Extension)");
  // Fallback to MetaMask-compatible logic
}

if (window.vultisig?.[chain] || window[chain]) {
  console.log(`Vultisig Extension [${chain}] provider is available!`);
  // Integration logic for the chain
} else {
  console.log(`No compatible [${chain}] provider found.`);
}
```

### 2. Connecting to Vultisig Extension

#### Ethereum

```javascript
const connectEthereum = async () => {
  const provider = window.vultisig?.ethereum || window.ethereum;

  if (provider) {
    try {
      await provider.request({ method: "eth_requestAccounts" });

      console.log("Connected to Ethereum wallet");
    } catch (error) {
      console.error("Ethereum connection failed", error);
    }
  } else {
    alert(
      "No Ethereum provider found. Please install Vultisig Extension or MetaMask.",
    );
  }
};
```

#### Other Supported Chains

```javascript
const connectChain = async (chain) => {
  const provider = window.vultisig?.[chain];

  if (provider) {
    try {
      const accounts = await provider.request({ method: "request_accounts" });

      console.log(`Connected to ${chain} wallet:`, accounts);
    } catch (error) {
      console.error(`${chain} connection failed`, error);
    }
  } else {
    alert(`No ${chain} provider found. Please install Vultisig Extension.`);
  }
};
```

Replace `chain` with the desired chain identifier such as `bitcoin`, `bitcoincash`, `cosmos`, `dash`, `dogecoin`, `litecoin`, `maya`, `solana`, `thorchain`, etc.

Each chain uses a unified interface accessible via `window.vultisig?.[chain]` and `window[chain]` for seamless interaction across different blockchain networks.

### 3. Connected Accounts

To get connected accounts to the current dapp, use `eth_accounts` for EVM chains and `get_accounts` for other Vultisig Extension supported chains.

#### Ethereum

```javascript
const getConnectedEthereum = async () => {
  const provider = window.vultisig?.ethereum || window.ethereum;

  if (provider) {
    try {
      const accounts = await provider.request({ method: "eth_accounts" });

      if (accounts.length)
        console.log(`Currently connected address:`, accounts);
      else
        console.log(
          `Currently no account is connected to this dapp:`,
          accounts,
        );
    } catch (error) {
      console.error("Ethereum getting connected accounts failed", error);
    }
  } else {
    alert(
      "No Ethereum provider found. Please install Vultisig Extension or MetaMask.",
    );
  }
};
```

#### Other Supported Chains

```javascript
const getConnectedAccountsChain = async (chain) => {
  const provider = window.vultisig?.[chain] || window[chain];

  if (provider) {
    try {
      const accounts = await provider.request({
        method: "get_accounts",
      });

      if (accounts.length)
        console.log(`Currently connected address:`, accounts);
      else
        console.log(
          `Currently no account is connected to this dapp:`,
          accounts,
        );
    } catch (error) {
      console.error(`${chain} getting connected accounts failed`, error);
    }
  } else {
    alert(`No ${chain} provider found. Please install Vultisig Extension.`);
  }
};
```

### 4. Managing Active Chain

#### Ethereum

To get the current active chain ID of Vultisig Extension:

```javascript
const getEthereumChainId = async () => {
  if (window.vultisig?.ethereum) {
    try {
      const chainId = await window.vultisig.ethereum.request({
        method: "eth_chainId",
      });

      console.log("Current Ethereum Chain ID: ", chainId);
    } catch (error) {
      console.error("Failed to get Ethereum chain ID", error);
    }
  }
};
```

To switch to a desired Ethereum chain:

```javascript
const switchEthereumChain = async (chainId) => {
  if (window.vultisig?.ethereum) {
    try {
      await window.vultisig.ethereum.request({
        method: "wallet_switchEthereumChain",
        params: [{ chainId }],
      });

      console.log(`Switched to Ethereum Chain ID: ${chainId}`);
    } catch (error) {
      console.error("Failed to switch Ethereum chain", error);
    }
  }
};
```

#### Cosmos-Based Chains

To get the current chain ID:

```javascript
const getCosmosChainId = async () => {
  if (window.vultisig?.cosmos) {
    try {
      const chainId = await window.vultisig.cosmos.request({
        method: "chain_id",
      });

      console.log("Current Cosmos Chain ID: ", chainId);
    } catch (error) {
      console.error("Failed to get Cosmos chain ID", error);
    }
  }
};
```

To switch to a desired Cosmos chain:

```javascript
const switchCosmosChain = async (chainId) => {
  if (window.vultisig?.cosmos) {
    try {
      await window.vultisig.cosmos.request({
        method: "wallet_switch_chain",
        params: [{ chainId }],
      });

      console.log(`Switched to Cosmos Chain ID: ${chainId}`);
    } catch (error) {
      console.error("Failed to switch Cosmos chain", error);
    }
  }
};
```

**Note**

Since other providers do not have different active chains, there is no need to switch chains for them. Therefore, the methods `wallet_switch_chain` and `wallet_switchEthereumChain` are not supported for chains other than Cosmos-based and Ethereum.

### 5. Handling Transactions

#### Transaction Details Structure

The txDetails object used in the transaction methods has the following structure:

* from: The sender's Ethereum or chain-specific wallet address,
* to: The receiver's wallet address.
* data: Arbitrary data that can be included with the transaction (e.g., for contract interactions).
* value: The amount to transfer, represented in hexadecimal format (e.g., "0x1" for 1 wei).

Example:

```javascript
const txDetails = {
  from: "0x1234567890abcdef1234567890abcdef12345678",
  to: "0xabcdef1234567890abcdef1234567890abcdef12",
  data: "0x", // Optional data
  value: "0x0", // Sending 0 ETH/wei
};
```

#### Ethereum

```javascript
const sendEthereumTransaction = async (txDetails) => {
  if (window.vultisig?.ethereum) {
    try {
      const transactionHash = await window.vultisig.ethereum.request({
        method: "eth_sendTransaction",
        params: [txDetails],
      });

      console.log("Ethereum Transaction Hash: ", transactionHash);
    } catch (error) {
      console.error("Ethereum transaction failed", error);
    }
  }
};
```

#### Other Supported Chains

```javascript
const sendChainTransaction = async (chain, txDetails) => {
  const provider = window.vultisig?.[chain] || window[chain];
  if (provider) {
    try {
      const transactionHash = await provider.request({
        method: "send_transaction",
        params: [txDetails],
      });

      console.log(`${chain} Transaction Hash:`, transactionHash);
    } catch (error) {
      console.error(`${chain} transaction failed`, error);
    }
  }
};
```

#### THORChain

In addition to send transactions, THORChain supports deposit transactions for operations such as `bond`, `unbond`, etc.

```javascript
const THORChainDepositTransaction = async (txDetails) => {
  const provider = window.thorchain || window.vultisig.thorchain;
  if (provider) {
    try {
      const transactionHash = await provider.request({
        method: "deposit_transaction",
        params: [txDetails],
      });

      console.log(`THORChain Transaction Hash:`, transactionHash);
    } catch (error) {
      console.error(`THORChain transaction failed`, error);
    }
  }
};
```

Example of non-native tokens of THORChain and other Cosmos chains :

```javascript
// sending RUJI on THORChain

const txDetails = {
  from: "thor1249rpf9u2ulwuezxkh6uas4au7xnde8umdua5z",
  to: "thor1ch4rpf9u2ulwuezxkh6uas4au7xnde8umdua91",
  assset:{
    chain: "THORChain",
    ticker: "x/ruji"
  },
  amount:{
    amount: 100000,
    deciamls: 8
  }،
  data: "0x", // Optional memo data
};


// sending KUJI on Cosmos

const txDetails = {
  from: "cosmos1ditx650chvyn8vs70v8camcj3q7h7hxlsavo9z",
  to: "cosmos1ditx650chvyn8vs70v8camcj3q7h7hxlsavo9z",
  assset:{
    chain: "Cosmos",
    ticker: "ibc/4CC44260793F84006656DD868E017578F827A492978161DA31D7572BCB3F4289"
  },
  amount:{
    amount: 100000,
    deciamls: 6
  }،
  data: "0x", // Optional memo data
};

// sending ION on Osmosis

const txDetails = {
  from: "osmo5iosp650chvyn8vs70v8camcj3q7h7hyucxl0op",
  to: "osmo5iosp650chvyn8vs70v8camcj3q7h7hyucxl0op",
  assset:{
    chain: "Osmosis",
    ticker: "uion"
  },
  amount:{
    amount: 100000,
    deciamls: 6
  }،
  data: "0x", // Optional memo data
};

```

## 6. Custom Message Signing

### Ethereum

Vultisig Extension currently supports the `personal_sign` method.

```javascript
const signCustomMessage = async (hexMessage, walletAddress) => {
  if (window.vultisig?.ethereum) {
    try {
      const signature = await window.vultisig.ethereum.request({
        method: "personal_sign",
        params: [hexMessage, walletAddress],
      });

      console.log("Signature:", signature);
    } catch (error) {
      console.error("Failed to sign the message", error);
    }
  }
};
```

## 7. Querying Transactions

### Ethereum

Retrieve Ethereum transaction details with `eth_getTransactionByHash`.

```javascript
const getEthereumTransaction = async (txHash) => {
  if (window.vultisig?.ethereum) {
    try {
      const txDetails = await window.vultisig.ethereum.request({
        method: "eth_getTransactionByHash",
        params: [txHash],
      });

      console.log("Ethereum Transaction Details:", txDetails);
    } catch (error) {
      console.error("Failed to get Ethereum transaction details:", error);
    }
  }
};
```

### Other Supported Chains

Retrieve transaction details of other Vultisig Extension supported chains using `get_transaction_by_hash`.

```javascript
const getChainTransaction = async (chain, txHash) => {
  const provider = window.vultisig?.[chain] || window[chain];
  if (provider) {
    try {
      const txDetails = await provider.request({
        method: "get_transaction_by_hash",
        params: [txHash],
      });

      console.log("Transaction Details:", txDetails);
    } catch (error) {
      console.error("Failed to get transaction details:", error);
    }
  }
};
```

## 8. Event Handling

Vultisig Extension supports the CONNECT and DISCONNECT events for all supported chains.

```javascript
const provider = window.vultisig?.[chain] || window[chain];

if (provider) {
  provider.on("CONNECT", (info) => {
    console.log("Connected:", info);
  });

  provider.on("DISCONNECT", (error) => {
    console.log("Disconnected:", error);
  });
}
```

## 9. Get Vault

Vultisig Extension provides a function to get vault properties.

```javascript
const provider = window.vultisig;

if (provider) {
  provider
    .getVault()
    .then((vault) => {
      console.log("vault:", vault);
    })
    .catch((error) => {
      console.log("error:", error);
    });
}
```

## 10. Detailed Implementation Examples

### Transaction Object Structure

```typescript
interface Transaction {
  from: string;        // The user's active address
  to: string;          // Required except during contract publications
  value?: string;      // Only required to send ether, in wei, hex format
  gasLimit?: string;   // Customizable by the user, hex format
  maxPriorityFeePerGas?: string; // Customizable by the user, hex format
  maxFeePerGas?: string; // Customizable by the user, hex format
  data?: string;       // Optional data for contract interactions, hex format
}
```

### Ethereum Account Management Examples

```typescript
// Connect to Vultisig Extension
const connectToVultisig Extension = async () => {
  try {
    const accounts = await window.vultisig.ethereum.request({ 
      method: "eth_requestAccounts"
    });
    console.log('Connected accounts:', accounts);
    // Returns: ['0x14F6Ed6CBb27b607b0E2A48551A988F1a19c89B6']
    return accounts;
  } catch (error) {
    const { code, message } = error;
    console.error(`Connection failed - Code: ${code}, Message: ${message}`);
    throw error;
  }
};

// Get connected accounts
const getConnectedAccounts = async () => {
  try {
    const accounts = await window.vultisig.ethereum.request({ 
      method: "eth_accounts"
    });
    console.log('Connected accounts:', accounts);
    // Returns: ['0x14F6Ed6CBb27b607b0E2A48551A988F1a19c89B6']
    return accounts;
  } catch (error) {
    const { code, message } = error;
    console.error(`Failed to get accounts - Code: ${code}, Message: ${message}`);
    throw error;
  }
};

// Get account balance
const getAccountBalance = async (address: string, blockTag: string) => {
  try {
    const balance = await window.vultisig.ethereum.request({
      method: "eth_getBalance",
      params: [address, blockTag]
    });
    console.log('Account balance:', balance);
    return balance; // Returns balance as string digits
  } catch (error) {
    const { code, message } = error;
    console.error(`Failed to get balance - Code: ${code}, Message: ${message}`);
    throw error;
  }
};
```

### Ethereum Gas Management Examples

```typescript
// Estimate gas
const estimateGas = async (transaction: Transaction) => {
  try {
    const estimate = await window.vultisig.ethereum.request({
      method: "eth_estimateGas",
      params: [transaction]
    });
    console.log('Gas estimate:', estimate);
    return estimate; // Returns string digits
  } catch (error) {
    const { code, message } = error;
    console.error(`Failed to estimate gas - Code: ${code}, Message: ${message}`);
    throw error;
  }
};

// Get gas price
const getGasPrice = async () => {
  try {
    const gasPrice = await window.vultisig.ethereum.request({
      method: "eth_gasPrice"
    });
    console.log('Gas price:', gasPrice);
    return gasPrice; // Returns string digits
  } catch (error) {
    const { code, message } = error;
    console.error(`Failed to get gas price - Code: ${code}, Message: ${message}`);
    throw error;
  }
};

// Get max priority fee per gas
const getMaxPriorityFeePerGas = async () => {
  try {
    const maxFee = await window.vultisig.ethereum.request({
      method: "eth_maxPriorityFeePerGas"
    });
    console.log('Max priority fee:', maxFee);
    return maxFee; // Returns string digits
  } catch (error) {
    const { code, message } = error;
    console.error(`Failed to get max priority fee - Code: ${code}, Message: ${message}`);
    throw error;
  }
};
```

### Block Information Examples

```typescript
// Get latest block number
const getLatestBlockNumber = async () => {
  try {
    const blockNumber = await window.vultisig.ethereum.request({
      method: "eth_blockNumber"
    });
    console.log('Latest block number:', blockNumber);
    return blockNumber; // Returns string digits
  } catch (error) {
    const { code, message } = error;
    console.error(`Failed to get block number - Code: ${code}, Message: ${message}`);
    throw error;
  }
};

// Get block by number
const getBlockByNumber = async (blockTag: string, includeTxs: boolean) => {
  try {
    const block = await window.vultisig.ethereum.request({
      method: "eth_getBlockByNumber",
      params: [blockTag, includeTxs ? " " : ""]
    });
    console.log('Block details:', block);
    /* Returns full block object with transaction details if requested */
    return block;
  } catch (error) {
    const { code, message } = error;
    console.error(`Failed to get block - Code: ${code}, Message: ${message}`);
    throw error;
  }
};
```

### Contract Interaction Examples

```typescript
// Get contract code
const getContractCode = async (address: string, blockTag: string) => {
  try {
    const code = await window.vultisig.ethereum.request({
      method: "eth_getCode",
      params: [address, blockTag]
    });
    console.log('Contract code:', code);
    // Returns hex string of contract bytecode
    return code;
  } catch (error) {
    const { code, message } = error;
    console.error(`Failed to get contract code - Code: ${code}, Message: ${message}`);
    throw error;
  }
};

// Call contract method
const callContract = async (transaction: Transaction) => {
  try {
    const result = await window.vultisig.ethereum.request({
      method: "eth_call",
      params: [transaction]
    });
    console.log('Call result:', result);
    // Returns hex string
    return result;
  } catch (error) {
    const { code, message } = error;
    console.error(`Contract call failed - Code: ${code}, Message: ${message}`);
    throw error;
  }
};
```

## Error Handling

All methods can throw errors with the following structure:

```typescript
interface ProviderError {
  code: number;
  message: string;
}
```

Common error codes include:

* 4001: User rejected the request
* 4100: Unauthorized
* 4200: Unsupported method
* 4900: Disconnected
* 4901: Chain disconnected

## Summary

Vultisig Extension ensures secure and **multi-chain integration** with DeFi applications, providing seamless support across popular chains. Its adherence to [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) guarantees compatibility with existing applications while delivering a secure and user-friendly experience.


# 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

```bash
npm install @vultisig/sdk
```

## Quick Start

### 1. Initialize the SDK

```typescript
import { Vultisig } from '@vultisig/sdk'

// Storage is auto-configured for your platform:
// - Node.js/Electron: FileStorage (~/.vultisig)
// - Browser: BrowserStorage (IndexedDB)
const sdk = new Vultisig()

// Initialize WASM modules
await sdk.initialize()
```

> **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)

```typescript
// Create a new vault using VultiServer
const vaultId = await sdk.createFastVault({
  name: "My Secure Wallet",
  email: "user@example.com",
  password: "SecurePassword123!",
});

// User will receive a verification code via email
const code = "1234"; // Get from user input
const vault = await sdk.verifyVault(vaultId, code);
```

### 3. Derive Blockchain Addresses

```typescript
// Derive addresses for different blockchain networks
const btcAddress = await vault.address("Bitcoin");
const ethAddress = await vault.address("Ethereum");
const solAddress = await vault.address("Solana");

console.log("BTC:", btcAddress); // bc1q...
console.log("ETH:", ethAddress); // 0x...
console.log("SOL:", solAddress); // 9WzD...
```

### 4. Create a Secure Vault (Multi-Device)

```typescript
// Create a secure vault with 2-of-3 threshold
const { vault, vaultId, sessionId } = await sdk.createSecureVault({
  name: "Team Wallet",
  devices: 3,                    // Total number of devices
  threshold: 2,                  // Optional: defaults to ceil((devices+1)/2)
  password: "optional-password", // Optional: encrypt the vault
  onQRCodeReady: (qrPayload) => {
    // Display this QR code for other devices to scan with Vultisig app
    displayQRCode(qrPayload);
  },
  onDeviceJoined: (deviceId, totalJoined, required) => {
    console.log(`Device joined: ${totalJoined}/${required}`);
  },
  onProgress: (step) => {
    console.log(`${step.step}: ${step.message}`);
  }
});

console.log("Vault created:", vault.name);
```

### 5. Sign with Secure Vault

```typescript
// Signing requires coordination with other devices
await vault.sign(transactionPayload, {
  onQRCodeReady: (qrPayload) => {
    // Display QR for devices to join the signing session
    displayQRCode(qrPayload);
  },
  onDeviceJoined: (deviceId, total, required) => {
    console.log(`Signing: ${total}/${required} devices ready`);
  },
  onProgress: (step) => {
    console.log(`Signing progress: ${step.message}`);
  }
});
```

### 6. Import/Export Vaults

```typescript
// Check if a vault file is encrypted
const isEncrypted = await sdk.isVaultFileEncrypted(file);

// Import vault from file
const vault = await sdk.addVault(file, isEncrypted ? "password" : undefined);

// Export vault to backup format (as Blob)
const backupBlob = await vault.export("BackupPassword123!");

// Or export as base64 string
const backupBase64 = await vault.exportAsBase64("BackupPassword123!");
```

### 7. Create Vault from Seedphrase

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

```typescript
// Validate the seedphrase first (auto-detects language)
const validation = await sdk.validateSeedphrase(mnemonic)
if (!validation.valid) {
  console.error(validation.error)
  return
}
console.log(`Detected language: ${validation.detectedLanguage}`) // 'english', 'japanese', etc.

// Discover which chains have balances
const chains = await sdk.discoverChainsFromSeedphrase(
  mnemonic,
  [Chain.Bitcoin, Chain.Ethereum, Chain.THORChain],
  (progress) => console.log(`${progress.chain}: ${progress.phase}`)
)

for (const result of chains) {
  if (result.hasBalance) {
    console.log(`${result.chain}: ${result.balance} ${result.symbol}`)
  }
}

// Create FastVault from seedphrase (requires email verification)
const vaultId = await sdk.createFastVaultFromSeedphrase({
  mnemonic,
  name: 'Imported Wallet',
  email: 'user@example.com',
  password: 'SecurePassword123!',
  discoverChains: true, // Auto-enable chains with balances
  onProgress: (step) => console.log(step.message)
})

// Verify with email code
const vault = await sdk.verifyVault(vaultId, verificationCode)
```

### 8. Token Registry & Prices

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

// Look up known tokens (static, no vault needed)
const tokens = Vultisig.getKnownTokens(Chain.Ethereum)
const usdc = Vultisig.getKnownToken(Chain.Ethereum, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48')

// Get native fee coin info
const feeCoin = Vultisig.getFeeCoin(Chain.Bitcoin) // { ticker: 'BTC', decimals: 8, ... }

// Fetch prices
const prices = await Vultisig.getCoinPrices({ ids: ['bitcoin', 'ethereum'] })
console.log(`BTC: $${prices.bitcoin}`)

// Discover tokens at vault address
const discovered = await vault.discoverTokens(Chain.Ethereum)

// Resolve token metadata (known registry → chain API fallback)
const token = await vault.resolveToken(Chain.Ethereum, '0x...')

// Cosmos message type constants
const msgType = CosmosMsgType.MsgSend // 'cosmos-sdk/MsgSend'
```

### 9. Security Scanning

```typescript
// Scan a website for phishing (static, no vault needed)
const siteScan = await Vultisig.scanSite('https://suspicious-site.com')
if (siteScan.isMalicious) console.warn('Malicious site!')

// Validate a transaction before signing
const validation = await vault.validateTransaction(keysignPayload)
if (validation?.isRisky) {
  console.warn(`Risk: ${validation.riskLevel} - ${validation.description}`)
}

// Simulate a transaction to preview asset changes
const simulation = await vault.simulateTransaction(keysignPayload)
```

### 10. Fiat On-Ramp (Banxa)

```typescript
// Check supported chains
const chains = Vultisig.getBanxaSupportedChains() // 23+ chains

// Generate buy URL for vault address
const buyUrl = await vault.getBuyUrl(Chain.Bitcoin)
if (buyUrl) window.open(buyUrl)
```

### 11. Push Notifications

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

```typescript
// Step 1: Register device for vault notifications
// Token comes from your platform's push service (APNs, FCM, or Web Push)
await sdk.notifications.registerDevice({
  vaultId: vault.publicKeys.ecdsa,
  partyName: vault.localPartyId,
  token: myPlatformPushToken,
  deviceType: 'ios', // 'ios' | 'android' | 'web'
})

// Step 2: Notify other vault members when initiating a signing session
await sdk.notifications.notifyVaultMembers({
  vaultId: vault.publicKeys.ecdsa,
  vaultName: vault.name,
  localPartyId: vault.localPartyId,
  qrCodeData: keysignQrPayload, // session data for joining
})

// Step 3: Handle incoming push notifications
const unsubscribe = sdk.notifications.onSigningRequest((notification) => {
  console.log(`Signing request for vault: ${notification.vaultName}`)
  // Use notification.qrCodeData to join the signing session
})
```

#### 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:

```typescript
// In your AppDelegate / UNUserNotificationCenter handler:
sdk.notifications.handleIncomingPush(notification.userInfo)
```

**Android** — Use Firebase Cloud Messaging:

```typescript
// In your FirebaseMessagingService.onMessageReceived:
sdk.notifications.handleIncomingPush(remoteMessage.data)
```

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

```typescript
// Register device
await sdk.notifications.registerDevice({
  vaultId: vault.publicKeys.ecdsa,
  partyName: vault.localPartyId,
  token: myDeviceToken,
  deviceType: 'web',
})

// Connect WebSocket — notifications delivered via onSigningRequest()
sdk.notifications.connect({
  vaultId: vault.publicKeys.ecdsa,
  partyName: vault.localPartyId,
  token: myDeviceToken,
})

// Disconnect when done (also called by sdk.dispose())
sdk.notifications.disconnect()
```

Alternatively, use Web Push API with VAPID key:

```typescript
const vapidKey = await sdk.notifications.fetchVapidPublicKey()
const subscription = await registration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: vapidKey,
})
await sdk.notifications.registerDevice({
  vaultId: vault.publicKeys.ecdsa,
  partyName: vault.localPartyId,
  token: JSON.stringify(subscription.toJSON()),
  deviceType: 'web',
})

// In your service worker push event:
sdk.notifications.handleIncomingPush(event.data.json())
```

**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

```typescript
import { Vultisig } from '@vultisig/sdk'
import type { VaultBase } from '@vultisig/sdk'
import { useState, useEffect } from 'react'

function VaultApp() {
  // BrowserStorage (IndexedDB) is used automatically in browser environments
  const [sdk] = useState(() => new Vultisig())
  const [vault, setVault] = useState<VaultBase | null>(null)
  const [addresses, setAddresses] = useState<Record<string, string>>({})

  useEffect(() => {
    // Initialize SDK on component mount
    sdk.initialize().catch(console.error)
  }, [sdk])

  const createVault = async () => {
    try {
      const vaultId = await sdk.createFastVault({
        name: 'My Wallet',
        email: 'user@example.com',
        password: 'SecurePassword123!'
      })

      // User receives verification code via email
      const code = prompt('Enter verification code from email:')
      const vault = await sdk.verifyVault(vaultId, code!)
      setVault(vault)
    } catch (error) {
      console.error('Vault creation failed:', error)
    }
  }

  const deriveAddresses = async () => {
    if (!vault) return

    const chains = ['Bitcoin', 'Ethereum', 'Solana']
    const results: Record<string, string> = {}

    for (const chain of chains) {
      try {
        results[chain] = await vault.address(chain)
      } catch (error) {
        console.error(`Failed to derive ${chain} address:`, error)
      }
    }

    setAddresses(results)
  }

  return (
    <div>
      <h1>Vultisig SDK Demo</h1>

      {!vault && (
        <button onClick={createVault}>
          Create Fast Vault
        </button>
      )}

      {vault && (
        <div>
          <h2>Vault: {vault.name}</h2>
          <p>Local Party: {vault.localPartyId}</p>

          <button onClick={deriveAddresses}>
            Derive Addresses
          </button>

          {Object.keys(addresses).length > 0 && (
            <div>
              <h3>Addresses</h3>
              {Object.entries(addresses).map(([chain, address]) => (
                <div key={chain}>
                  <strong>{chain.toUpperCase()}:</strong> {address}
                </div>
              ))}
            </div>
          )}
        </div>
      )}
    </div>
  )
}

export default VaultApp
```

## Configuration

### SDK Configuration

```typescript
const sdk = new Vultisig({
  autoInit: true, // Automatically initialize WASM modules on creation
  serverUrl: "https://api.vultisig.com", // Custom VultiServer endpoint
  relayUrl: "https://relay.vultisig.com", // Custom relay endpoint
});
```

### 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:**

```typescript
const txHash = await vault.broadcastTx({ chain, keysignPayload, signature })

// Poll for confirmation
const result = await vault.getTxStatus({ chain: Chain.Ethereum, txHash })
if (result.status === 'success') {
  console.log(`Confirmed! Fee: ${result.receipt?.feeAmount} ${result.receipt?.feeTicker}`)
} else if (result.status === 'error') {
  console.log('Transaction failed')
}
```

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:

```typescript
try {
  const vault = await sdk.createFastVault({
    name: "Test Vault",
    email: "invalid-email",
    password: "123",
  });
} catch (error) {
  if (error.message.includes("email")) {
    console.error("Invalid email address");
  } else if (error.message.includes("password")) {
    console.error("Password too weak");
  } else {
    console.error("Vault creation failed:", error);
  }
}
```

## 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:**

```bash
# Clone the repository
git clone https://github.com/vultisig/vultisig-sdk.git
cd vultisig-sdk

# IMPORTANT: Install from root (sets up all workspace packages)
yarn install
```

### Building

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

```bash
# Build the SDK (from root directory)
yarn workspace @vultisig/sdk build
```

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

### Testing

```bash
# Run tests (from root directory)
yarn workspace @vultisig/sdk test
```

### 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

```
packages/sdk/
├── src/                # SDK source code
│   ├── chains/        # Address derivation and chain management
│   ├── mpc/           # Multi-party computation logic
│   ├── vault/         # Vault creation and management
│   ├── server/        # Fast vault server integration
│   └── wasm/          # WASM module management
├── tests/             # Test suite
└── package.json       # SDK package configuration

# Workspace packages (bundled into SDK)
packages/core/         # Core blockchain functionality
packages/lib/          # Shared libraries and utilities
```

## 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 the [SDK LICENSE](https://github.com/vultisig/vultisig-sdk/blob/main/packages/sdk/LICENSE) file for details.

## Support

* 📖 [Documentation](https://docs.vultisig.com)
* 💬 [Discord Community](https://discord.gg/Cugw9T2NrP)
* 🐛 [Report Issues](https://github.com/vultisig/vultisig-sdk/issues)
* 🌐 [Website](https://vultisig.com)

***

**Built with ❤️ by the Vultisig team**


# SDK Implementation Guide

## Table of Contents

* [Installation & Setup](#installation--setup)
* [Quick Start Tutorial](#quick-start-tutorial)
* [Core Concepts](#core-concepts)
* [Password Management](#password-management)
* [Vault Management](#vault-management)
* [Creating Vaults from Seedphrase](#creating-vaults-from-seedphrase)
* [Essential Operations](#essential-operations)
* [Token Swaps](#token-swaps)
* [Token Registry & Discovery](#token-registry--discovery)
* [Price Feeds](#price-feeds)
* [Security Scanning](#security-scanning)
* [Fiat On-Ramp (Banxa)](#fiat-on-ramp-banxa)
* [Push Notifications](#push-notifications)
* [Configuration](#configuration)
* [Caching System](#caching-system)
* [Event System](#event-system)
* [Quick Reference](#quick-reference)
* [Platform Notes](#platform-notes)

***

## Installation & Setup

### Install the Package

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

### Platform Requirements

* **Node.js**: Version 20 or higher
* **Browser**: Modern browsers with WebAssembly support (Chrome, Firefox, Safari, Edge)
* **Electron**: Version 20 or higher (for desktop applications)
* **TypeScript**: Optional but recommended

### Browser Setup: WASM Files

For browser environments, you need to serve the WASM files from your public directory:

1. Copy WASM files to your public directory:

   ```bash
   cp node_modules/@vultisig/sdk/dist/*.wasm public/
   ```
2. The SDK will automatically load these files from the root path (`/`)

### Basic Initialization

The SDK automatically uses the appropriate storage for your platform:

* **Node.js**: `FileStorage` (stores in `~/.vultisig` by default)
* **Browser**: `BrowserStorage` (uses IndexedDB with localStorage fallback)
* **Electron**: `FileStorage` (same as Node.js, shared with CLI)

```typescript
import { Vultisig } from '@vultisig/sdk'

const sdk = new Vultisig()  // Storage is auto-configured for your platform

await sdk.initialize()

// When done, clean up resources
sdk.dispose()
```

**Custom Storage (optional):**

> **WARNING: `MemoryStorage` is for testing only.** It is non-persistent — all data, including vault keyshares, is permanently lost when the process exits. If you create a vault with `MemoryStorage` and do not export/back up the vault, **you will permanently lose access to any funds** stored in that vault. For production, use the default platform storage shown above or implement your own persistent `Storage` interface.

```typescript
import { Vultisig, MemoryStorage } from '@vultisig/sdk'

const sdk = new Vultisig({
  storage: new MemoryStorage(),  // TESTING ONLY — not persistent, will lose vault data
})

await sdk.initialize()
sdk.dispose()
```

***

## Quick Start Tutorial

Here's a complete example showing vault creation, address derivation, and balance checking with password management:

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

// Step 1: Initialize SDK with configuration
const sdk = new Vultisig({
  // Password handling (recommended for production)
  onPasswordRequired: async (vaultId: string, vaultName: string) => {
    // Prompt user for password - implementation depends on platform
    return await promptUserForPassword(`Enter password for ${vaultName}`)
  },

  passwordCache: {
    defaultTTL: 300000  // Cache password for 5 minutes
  }
})

await sdk.initialize()

// Step 2: Create a fast vault (server-assisted, always encrypted)
// Returns the vaultId - vault is returned from verifyVault()
const vaultId = await sdk.createFastVault({
  name: "My Wallet",
  email: "user@example.com",
  password: "SecurePassword123!",
  onProgress: (step) => {
    console.log(`${step.message} (${step.progress}%)`)
  }
})

// Step 3: Verify with email code and get the vault
// The vault is saved to storage and returned after successful verification
const code = await getVerificationCode() // Get code from user
const vault = await sdk.verifyVault(vaultId, code)

// Step 4: Now use the vault
const btcAddress = await vault.address(Chain.Bitcoin)
console.log('Bitcoin address:', btcAddress)

// Step 5: Check balance
const balance = await vault.balance(Chain.Bitcoin)
console.log(`Balance: ${balance.amount} ${balance.symbol}`)

// Step 6: Get balances across multiple chains
const balances = await vault.balances([Chain.Bitcoin, Chain.Ethereum])
for (const [chain, balance] of Object.entries(balances)) {
  console.log(`${chain}: ${balance.amount} ${balance.symbol}`)
}

// Step 7: Clean up when done
sdk.dispose()
```

***

## Core Concepts

### Vault Types

The SDK supports two types of vaults:

* **FastVault**: 2-of-2 MPC with VultiServer assistance. Always encrypted with password. Best for quick setup and individual use.
* **SecureVault**: Multi-device N-of-M MPC with configurable thresholds. Optionally encrypted. Best for maximum security, teams, and multi-device scenarios.

| Feature       | FastVault                     | SecureVault                          |
| ------------- | ----------------------------- | ------------------------------------ |
| **Threshold** | 2-of-2 (fixed)                | N-of-M (configurable)                |
| **Setup**     | Server-assisted, instant      | Multi-device, requires QR pairing    |
| **Signing**   | Instant via VultiServer       | Requires device coordination         |
| **Password**  | Required                      | Optional                             |
| **Use Cases** | Personal wallets, development | Team wallets, high security, custody |

### Supported Chains

The SDK supports 36 blockchains across multiple ecosystems:

* **EVM (13)**: Ethereum, Polygon, BSC, Arbitrum, Optimism, Base, Avalanche, Blast, Cronos, ZkSync, Hyperliquid, Mantle, Sei
* **UTXO (6)**: Bitcoin, Litecoin, Dogecoin, Bitcoin Cash, Dash, Zcash
* **Cosmos (10)**: Cosmos Hub, THORChain, MayaChain, Osmosis, Dydx, Kujira, Terra, Terra Classic, Noble, Akash
* **Other (7)**: Solana, Polkadot, Sui, TON, Ripple, Tron, Cardano

See the [Quick Reference](#supported-chains) section for the complete list.

### Storage Layer

The SDK uses platform-appropriate storage by default:

* **Node.js**: `FileStorage` - Stores vaults in `~/.vultisig` directory
* **Browser**: `BrowserStorage` - Uses IndexedDB with localStorage fallback
* **Electron**: `FileStorage` - Same as Node.js (vaults shared with CLI)
* **Fallback**: `MemoryStorage` - In-memory only (data lost on restart)

For custom persistence, implement the `Storage` interface:

```typescript
type Storage = {
  get<T>(key: string): Promise<T | null>
  set<T>(key: string, value: T): Promise<void>
  remove(key: string): Promise<void>
  list(): Promise<string[]>
  clear(): Promise<void>
  getUsage?(): Promise<number>
  getQuota?(): Promise<number | undefined>
}
```

### Stateless Usage

For scenarios where you don't need persistent storage—such as one-off operations, testing, or serverless functions—use `MemoryStorage` to create ephemeral vault instances:

```typescript
import { Vultisig, MemoryStorage, Chain } from '@vultisig/sdk'
import * as fs from 'fs'

// Create SDK with in-memory storage (no persistence)
const sdk = new Vultisig({
  storage: new MemoryStorage()
})
await sdk.initialize()

// Load vault from file
const vultContent = fs.readFileSync('my-wallet.vult', 'utf-8')
const vault = await sdk.importVault(vultContent, 'password123')

// Use vault normally - all operations work
const address = await vault.address(Chain.Bitcoin)
const balance = await vault.balance(Chain.Ethereum)
const signature = await vault.sign(payload)

// When the process ends, all state is lost (by design)
sdk.dispose()
```

**Use cases for stateless usage:**

* **One-off signing**: Sign a transaction without persisting vault state
* **Address derivation**: Generate addresses without storing vault data
* **Testing**: Unit and integration tests without filesystem side effects
* **Serverless functions**: Lambda/Cloud Functions that load vault per-request
* **CLI tools**: Command-line utilities that operate on vault files

**What works in stateless mode:**

* ✅ Address derivation
* ✅ Balance checking
* ✅ Transaction signing (FastVault)
* ✅ Gas estimation
* ✅ Swap quotes and execution
* ✅ Token/chain management (in-memory only)

**What doesn't persist:**

* ❌ Vault preferences (chains, tokens, currency)
* ❌ Cached balances/addresses (recreated each session)
* ❌ Password cache (must provide password each time)

**Note**: The vault file (`.vult`) itself is never modified by the SDK—it's read-only. Persistence is about SDK metadata and cached data, not the vault file contents.

***

## Password Management

Password management is a critical aspect of the SDK. FastVaults are always encrypted, and proper password handling ensures both security and good user experience.

### When Passwords Are Required

* **FastVault**: Always encrypted, password required for all operations
* **SecureVault**: Optional encryption, password only required if encrypted
* **Import**: Password required if the vault file is encrypted
* **Export**: Password optional, encrypts the backup file

### Setting Up Password Callback

Configure a password callback when creating your SDK instance to automatically prompt users when needed:

#### Browser Example (with Modal)

```typescript
import { Vultisig, MemoryStorage } from '@vultisig/sdk'

const sdk = new Vultisig({
  storage: new MemoryStorage(),
  onPasswordRequired: async (vaultId: string, vaultName: string) => {
    return new Promise((resolve) => {
      // Show modal to user
      const modal = createPasswordModal({
        title: `Enter password for ${vaultName}`,
        onSubmit: (password) => {
          closeModal()
          resolve(password)
        }
      })
      modal.show()
    })
  }
})
```

#### Node.js Example (Command Line)

```typescript
import { Vultisig } from '@vultisig/sdk'
import * as readline from 'readline'

const sdk = new Vultisig({
  storage: new FileStorage(),
  onPasswordRequired: async (vaultId: string, vaultName: string) => {
    const rl = readline.createInterface({
      input: process.stdin,
      output: process.stdout
    })

    return new Promise((resolve) => {
      rl.question(`Enter password for ${vaultName}: `, (password) => {
        rl.close()
        resolve(password)
      })
    })
  }
})
```

#### Retrieve from Secure Storage

```typescript
const sdk = new Vultisig({
  storage: new FileStorage(),
  onPasswordRequired: async (vaultId: string, vaultName: string) => {
    // Retrieve from OS keychain, secure enclave, etc.
    return await secureStorage.getPassword(vaultId)
  }
})
```

### Password Caching

Cache passwords to avoid repeated prompts during a session:

```typescript
const sdk = new Vultisig({
  storage: new MemoryStorage(),
  passwordCache: {
    defaultTTL: 300000  // Cache for 5 minutes (in milliseconds)
  }
})
```

Common TTL configurations:

```typescript
// 5 minutes (recommended for balance of security and UX)
passwordCache: { defaultTTL: 300000 }

// 15 minutes
passwordCache: { defaultTTL: 900000 }

// 1 hour
passwordCache: { defaultTTL: 3600000 }

// Session only (no expiry, cleared on app close)
passwordCache: { defaultTTL: Infinity }
```

### Manual Lock/Unlock

Control password cache manually for sensitive operations:

```typescript
// Lock the vault (clear cached password)
await vault.lock()

// Check if vault is unlocked
if (!vault.isUnlocked()) {
  // Manually unlock with password
  await vault.unlock('SecurePassword123!')
}

// Perform sensitive operation
const signature = await vault.sign(keysignPayload)

// Lock again after sensitive operation
await vault.lock()
```

**Example: Auto-lock on Inactivity**

```typescript
let inactivityTimer: NodeJS.Timeout | null = null

function resetInactivityTimer(vault: VaultBase) {
  if (inactivityTimer) clearTimeout(inactivityTimer)

  // Lock after 10 minutes of inactivity
  inactivityTimer = setTimeout(async () => {
    await vault.lock()
    console.log('Vault locked due to inactivity')
  }, 600000)
}

// Call resetInactivityTimer() on user interactions
document.addEventListener('click', () => resetInactivityTimer(vault))
document.addEventListener('keypress', () => resetInactivityTimer(vault))
```

### Checking Encryption Status

Before importing a vault, check if it requires a password:

```typescript
import * as fs from 'fs'

const vultContent = fs.readFileSync('backup.vult', 'utf-8')
const isEncrypted = sdk.isVaultEncrypted(vultContent)

let vault
if (isEncrypted) {
  const password = await promptUserForPassword()
  vault = await sdk.importVault(vultContent, password)
} else {
  vault = await sdk.importVault(vultContent)
}
```

### Export with Password

Create encrypted backups with a password (can be different from vault password):

```typescript
// Export with encryption
const { filename, data } = await vault.export('BackupPassword123!')

// Save to file (Node.js)
fs.writeFileSync(filename, data, 'utf-8')
console.log(`Encrypted backup saved to ${filename}`)

// Export without encryption (not recommended for FastVault)
const { filename, data } = await vault.export()
```

### Password Security Best Practices

1. **Never store passwords in plain text**
2. **Use password caching with reasonable TTLs** (5-15 minutes recommended)
3. **Lock vaults after sensitive operations**
4. **Use different passwords for backups**
5. **Implement auto-lock on inactivity**
6. **Clear password cache on logout**
7. **Use secure password input** (type="password" in forms)

***

## Vault Management

### Creating Fast Vaults

Create a new vault with server assistance:

```typescript
// Step 1: Create vault - returns vaultId (vault not returned yet)
const vaultId = await sdk.createFastVault({
  name: "My Wallet",
  email: "user@example.com",
  password: "SecurePassword123!",
  onProgress: (step) => {
    console.log(`Progress: ${step.message} (${step.progress}%)`)
  }
})

// Step 2: Verify with email code - returns the vault
const code = await promptUserForVerificationCode()
const vault = await sdk.verifyVault(vaultId, code)

console.log('Vault created:', vault.name)
```

**Important: Verification Flow**

Fast vaults require email verification. The vault is only returned **after successful verification**:

1. `createFastVault()` generates keys and returns the `vaultId`
2. The vault exists in memory but is **not returned or persisted**
3. User calls `verifyVault(vaultId, code)` with the email verification code
4. On success, the vault is saved to storage, set as active, and **returned**

**If the process is killed before verification completes, the vault is lost.** This is intentional - unverified vaults cannot be used for signing anyway. The user simply needs to call `createFastVault()` again to restart the process.

### Creating Secure Vaults

Secure vaults use multi-device MPC with configurable N-of-M thresholds. Creation requires coordination with other devices running the Vultisig mobile app.

```typescript
// Create a 2-of-3 secure vault
const { vault, vaultId, sessionId } = await sdk.createSecureVault({
  name: "Team Wallet",
  devices: 3,                    // Total number of devices
  threshold: 2,                  // Signing threshold (defaults to ceil((devices+1)/2))
  password: "OptionalPassword",  // Optional encryption password

  // Called when QR code is ready for device pairing
  onQRCodeReady: (qrPayload) => {
    // Display this QR for other devices to scan with Vultisig app
    displayQRCode(qrPayload);
  },

  // Called each time a device joins
  onDeviceJoined: (deviceId, totalJoined, required) => {
    console.log(`Device joined: ${totalJoined}/${required}`);
  },

  // Called with creation progress updates
  onProgress: (step) => {
    console.log(`${step.step}: ${step.message} (${step.progress}%)`);
  }
});

console.log('Secure vault created:', vault.name);
console.log('Vault ID:', vaultId);
```

**Creation Flow:**

1. `createSecureVault()` generates session parameters and a QR payload
2. `onQRCodeReady` callback receives the QR data - display this for other devices
3. Other participants scan the QR with the Vultisig mobile app (iOS/Android)
4. `onDeviceJoined` fires as each device joins the session
5. Once all devices join, MPC keygen runs automatically (DKLS for ECDSA, Schnorr for EdDSA, ML-DSA for post-quantum signatures)
6. The vault is created and saved, then returned

**Threshold Configuration:**

The threshold determines how many devices must participate in signing:

| Devices | Default Threshold | Can Sign With |
| ------- | ----------------- | ------------- |
| 2       | 2                 | Both devices  |
| 3       | 2                 | Any 2 of 3    |
| 4       | 3                 | Any 3 of 4    |
| 5       | 4                 | Any 4 of 5    |

Formula: `threshold = Math.ceil((devices * 2) / 3)`

**Cancellation Support:**

```typescript
const controller = new AbortController();

// Allow user to cancel
cancelButton.onclick = () => controller.abort();

try {
  const { vault } = await sdk.createSecureVault({
    name: "Team Wallet",
    devices: 3,
    signal: controller.signal,
    onQRCodeReady: displayQRCode
  });
} catch (error) {
  if (error.name === 'AbortError') {
    console.log('Vault creation cancelled');
  }
}
```

### Signing with Secure Vault

Signing with a secure vault requires coordination with other devices. The threshold number of devices must participate.

```typescript
// Prepare the transaction as usual
const keysignPayload = await vault.prepareSendTx({
  coin,
  receiver: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
  amount: '100000000000000000'
});

// Sign with device coordination
const signature = await vault.sign(keysignPayload, {
  // Called when QR is ready for devices to join signing session
  onQRCodeReady: (qrPayload) => {
    displayQRCode(qrPayload);
    console.log('Scan with other devices to approve transaction');
  },

  // Called as devices join the signing session
  onDeviceJoined: (deviceId, total, required) => {
    console.log(`Signing: ${total}/${required} devices ready`);
  },

  // Called with signing progress updates
  onProgress: (step) => {
    console.log(`${step.step}: ${step.message}`);
  }
});

// Broadcast once signature is obtained
const txHash = await vault.broadcastTx({
  chain: Chain.Ethereum,
  keysignPayload,
  signature
});
```

**Signing Flow:**

1. Call `vault.sign()` with transaction payload and callbacks
2. `onQRCodeReady` fires with QR data - display for other participants
3. Other devices scan QR and approve the transaction in the Vultisig app
4. `onDeviceJoined` fires as devices join the signing session
5. Once threshold is reached, MPC signing runs automatically
6. Signature is returned and can be broadcast

**Signing Arbitrary Bytes with Secure Vault:**

```typescript
// Sign pre-hashed data (useful for custom transaction construction)
const signature = await vault.signBytes({
  chain: Chain.Ethereum,
  messages: [transactionHash]  // Uint8Array, Buffer, or hex string
}, {
  onQRCodeReady: displayQRCode,
  onDeviceJoined: (id, total, required) => {
    console.log(`${total}/${required} ready`);
  }
});
```

**Timeout Behavior:**

Device coordination has a 5-minute timeout by default. If threshold devices don't join within this window, the signing operation fails.

### Importing Vaults

Import an existing vault from a `.vult` backup file:

```typescript
import * as fs from 'fs'

// Read vault file
const vultContent = fs.readFileSync('MyWallet-local-party-1-share1of2.vult', 'utf-8')

// Check if encrypted
const isEncrypted = sdk.isVaultEncrypted(vultContent)

// Import with password if needed
const vault = await sdk.importVault(
  vultContent,
  isEncrypted ? 'VaultPassword123!' : undefined
)

console.log('Vault imported:', vault.name)
```

### Exporting Vaults

Create a backup of your vault:

```typescript
// Export with password encryption (recommended)
const { filename, data } = await vault.export('BackupPassword123!')

// Save to file (Node.js)
fs.writeFileSync(filename, data, 'utf-8')

// Save to file (Browser)
const blob = new Blob([data], { type: 'text/plain' })
const url = URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = filename
link.click()
URL.revokeObjectURL(url)
```

### Listing Vaults

Get all stored vaults:

```typescript
const vaults = await sdk.listVaults()

for (const vault of vaults) {
  console.log(`${vault.name} (${vault.type})`)
  console.log(`  ID: ${vault.id}`)
  console.log(`  Created: ${new Date(vault.createdAt).toLocaleString()}`)
  console.log(`  Encrypted: ${vault.isEncrypted}`)
}
```

### Switching Vaults

Set the active vault:

```typescript
// Set active vault
await sdk.setActiveVault(vault)

// Get active vault
const activeVault = sdk.getActiveVault()

// Get vault by ID
const vault = await sdk.getVaultById('vault-id-here')
```

### Deleting Vaults

Remove a vault from storage:

```typescript
// Delete specific vault
await sdk.deleteVault(vault)

// Or delete by ID
const vault = await sdk.getVaultById('vault-id')
await sdk.deleteVault(vault)
```

### Renaming Vaults

```typescript
await vault.rename('New Wallet Name')
console.log('Vault renamed to:', vault.name)
```

***

## Creating Vaults from Seedphrase

Import existing wallets from BIP39 mnemonic phrases (12 or 24 words). This allows migrating wallets from other applications into Vultisig.

### Validating a Seedphrase

Always validate the mnemonic before attempting import. The SDK supports all 10 BIP39 languages with automatic language detection:

* English, Japanese, Korean, Spanish, Chinese (Simplified/Traditional), French, Italian, Czech, Portuguese

```typescript
const result = await sdk.validateSeedphrase(mnemonic)

if (result.valid) {
  console.log(`Valid ${result.wordCount}-word mnemonic`)
  console.log(`Language: ${result.detectedLanguage}`) // e.g., 'english', 'japanese'
} else {
  console.error('Validation failed:', result.error)
  if (result.invalidWords?.length) {
    console.error('Invalid words:', result.invalidWords.join(', '))
  }
}
```

You can also specify a language explicitly for stricter validation:

```typescript
// Validate as Japanese mnemonic only
const result = await sdk.validateSeedphrase(mnemonic, { language: 'japanese' })
```

### Discovering Chains with Balances

Before importing, you can scan chains to find existing balances:

```typescript
const { results, usePhantomSolanaPath } = await sdk.discoverChainsFromSeedphrase(
  mnemonic,
  [Chain.Bitcoin, Chain.Ethereum, Chain.THORChain, Chain.Solana],
  (progress) => {
    console.log(`${progress.phase}: ${progress.chain}`)
    console.log(`Progress: ${progress.chainsProcessed}/${progress.chainsTotal}`)
    console.log(`Found balances on: ${progress.chainsWithBalance.join(', ')}`)
  }
)

console.log('\nDiscovery Results:')
for (const result of results) {
  const status = result.hasBalance ? 'Y' : 'N'
  console.log(`[${status}] ${result.chain}: ${result.address}`)
  if (result.hasBalance) {
    console.log(`    Balance: ${result.balance} ${result.symbol}`)
  }
}

// Phantom wallet detection (Solana only)
if (usePhantomSolanaPath) {
  console.log('\nDetected Phantom wallet derivation path for Solana')
}
```

**Progress Phases:**

* `validating` - Validating the mnemonic
* `deriving` - Deriving addresses for each chain
* `fetching` - Fetching balances from blockchain
* `complete` - Discovery finished

**Phantom Wallet Detection:**

When Solana is included in the discovery, the SDK automatically checks both the standard BIP44 path and Phantom wallet's non-standard derivation path (`m/44'/501'/0'/0'`). If the Phantom path has a balance but the standard path doesn't, `usePhantomSolanaPath` will be `true` and the Solana result will show the Phantom-derived address.

This detection follows the logic: `usePhantomSolanaPath = phantomBalance > 0 && standardBalance === 0`

### Creating a FastVault from Seedphrase

Import a seedphrase with VultiServer assistance (2-of-2 threshold):

```typescript
const vaultId = await sdk.createFastVaultFromSeedphrase({
  mnemonic: 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
  name: 'Imported Wallet',
  email: 'user@example.com',
  password: 'SecurePassword123!',

  // Auto-enable chains that have balances
  discoverChains: true,

  // Or specify exact chains to enable
  // chains: [Chain.Bitcoin, Chain.Ethereum],

  // Use Phantom wallet derivation path for Solana (auto-detected if discoverChains is true)
  // usePhantomSolanaPath: true,

  // Progress callbacks
  onProgress: (step) => {
    console.log(`${step.step}: ${step.message} (${step.progress}%)`)
  },
  onChainDiscovery: (progress) => {
    console.log(`Discovering ${progress.chain}: ${progress.phase}`)
  }
})

// Complete with email verification
const code = await getVerificationCodeFromUser()
const vault = await sdk.verifyVault(vaultId, code)

console.log('Import complete:', vault.name)
```

**Phantom Wallet Support:**

If your seedphrase was created in Phantom wallet, enable `usePhantomSolanaPath: true` to use Phantom's non-standard Solana derivation path. When `discoverChains: true` is set, this is automatically detected based on which path has funds.

### Creating a SecureVault from Seedphrase

Import a seedphrase with multi-device MPC (N-of-M threshold):

```typescript
const { vault, vaultId, sessionId } = await sdk.createSecureVaultFromSeedphrase({
  mnemonic: 'abandon abandon abandon...',
  name: 'Team Wallet',
  devices: 3,      // Total devices
  threshold: 2,    // Signing threshold
  password: 'OptionalPassword',
  discoverChains: true,

  // Use Phantom wallet derivation path for Solana (auto-detected if discoverChains is true)
  // usePhantomSolanaPath: true,

  onProgress: (step) => {
    console.log(`${step.step}: ${step.message}`)
  },
  onQRCodeReady: (qrPayload) => {
    // Display QR for other devices to scan
    displayQRCode(qrPayload)
  },
  onDeviceJoined: (deviceId, total, required) => {
    console.log(`Device joined: ${total}/${required}`)
  },
  onChainDiscovery: (progress) => {
    console.log(`Discovering: ${progress.message}`)
  }
})

console.log('SecureVault imported:', vault.name)
```

### Joining a SecureVault Session (Programmatic Multi-Device)

Use `joinSecureVault()` to programmatically join an existing vault creation session from another SDK instance. This enables multi-device coordination without QR code scanning.

#### Example 1: Joining a fresh keygen session

```typescript
// Device 1 initiates
let qrPayload: string
const promise1 = sdk1.createSecureVault({
  name: 'Shared Vault',
  devices: 3,
  password: 'optional',
  onQRCodeReady: (qr) => { qrPayload = qr }
})

// Device 2 joins (no mnemonic needed for keygen)
const promise2 = sdk2.joinSecureVault(qrPayload, {
  devices: 3
})

// Device 3 joins
const promise3 = sdk3.joinSecureVault(qrPayload, {
  devices: 3
})

// Wait for all to complete
const [result1, result2, result3] = await Promise.all([promise1, promise2, promise3])
// All have matching vaultId but unique localPartyId
```

#### Example 2: Joining a seedphrase-based session

```typescript
// Device 1 initiates with seedphrase
let qrPayload: string
const promise1 = sdk1.createSecureVaultFromSeedphrase({
  mnemonic: seedphrase,
  name: 'Shared Wallet',
  devices: 3,
  onQRCodeReady: (qr) => { qrPayload = qr }
})

// Device 2 joins (mnemonic required - must match!)
const promise2 = sdk2.joinSecureVault(qrPayload, {
  mnemonic: seedphrase,
  devices: 3
})

// Device 3 joins
const promise3 = sdk3.joinSecureVault(qrPayload, {
  mnemonic: seedphrase,
  devices: 3
})

const [result1, result2, result3] = await Promise.all([promise1, promise2, promise3])
```

**Auto-detection:** The `joinSecureVault()` method automatically detects whether the session is a fresh keygen or seedphrase-based from the QR payload's `libType` field. For seedphrase sessions, the `mnemonic` option is required and must match the initiator's mnemonic.

### Creation Flow Comparison

| Feature           | FastVault from Seedphrase         | SecureVault from Seedphrase                  |
| ----------------- | --------------------------------- | -------------------------------------------- |
| **Method**        | `createFastVaultFromSeedphrase()` | `createSecureVaultFromSeedphrase()`          |
| **Threshold**     | 2-of-2 (with VultiServer)         | N-of-M (configurable)                        |
| **Verification**  | Email code required               | Device pairing via QR or `joinSecureVault()` |
| **Password**      | Required                          | Optional                                     |
| **Signing**       | Instant                           | Requires device coordination                 |
| **Joiner Method** | N/A (server auto-joins)           | `joinSecureVault()`                          |

### Security Considerations

1. **Memory Safety**: The SDK clears mnemonic from memory after derivation
2. **No Logging**: Mnemonics are never logged or persisted
3. **HTTPS Only**: All server communication is encrypted
4. **Input Validation**: Always validate before import to catch typos
5. **Post-Quantum Readiness**: Vault keygen includes ML-DSA (FIPS 204) key generation alongside ECDSA (DKLS) and EdDSA (Schnorr), providing forward-looking protection against quantum threats

***

## Essential Operations

### Address Derivation

Get addresses for different blockchains:

```typescript
// Single address
const ethAddress = await vault.address(Chain.Ethereum)
console.log('Ethereum:', ethAddress) // "0x742d35Cc..."

const btcAddress = await vault.address(Chain.Bitcoin)
console.log('Bitcoin:', btcAddress) // "bc1q..."

// Multiple addresses
const addresses = await vault.addresses([
  Chain.Bitcoin,
  Chain.Ethereum,
  Chain.Solana
])

console.log(addresses)
// {
//   Bitcoin: "bc1q...",
//   Ethereum: "0x...",
//   Solana: "9Wz..."
// }
```

Addresses are cached automatically for performance.

### Balance Checking

Check balances for your assets:

```typescript
// Single chain balance
const balance = await vault.balance(Chain.Ethereum)
console.log(`${balance.amount} ${balance.symbol}`)
console.log(`Value: $${balance.fiatValue} ${balance.currency}`)

// Multiple chain balances
const balances = await vault.balances([Chain.Bitcoin, Chain.Ethereum])

for (const [chain, balance] of Object.entries(balances)) {
  console.log(`${chain}: ${balance.amount} ${balance.symbol} ($${balance.fiatValue})`)
}

// All configured chains (with tokens)
const allBalances = await vault.balances(undefined, true) // includeTokens=true

// Force refresh (bypass cache)
await vault.updateBalance(Chain.Ethereum)
await vault.updateBalances() // Refresh all chains
```

### Preparing & Sending Transactions

Send transactions on any supported chain:

```typescript
import { AccountCoin } from 'vultisig-sdk'

// Step 1: Get coin information
const coin = new AccountCoin({
  chain: Chain.Ethereum,
  ticker: 'ETH',
  address: await vault.address(Chain.Ethereum),
  decimals: 18,
  priceUSD: '3000.00',
  isNativeToken: true
})

// Step 2: Prepare transaction
const keysignPayload = await vault.prepareSendTx({
  coin,
  receiver: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
  amount: '100000000000000000', // 0.1 ETH in wei
  memo: 'Payment for services',
  feeSettings: {
    gasPrice: '50000000000', // 50 gwei (optional, uses estimate if not provided)
  }
})

// Step 3: Sign transaction (may trigger password prompt)
const signature = await vault.sign(keysignPayload)

// Step 4: Broadcast transaction
const txHash = await vault.broadcastTx({
  chain: Chain.Ethereum,
  keysignPayload,
  signature
})

console.log('Transaction broadcast:', txHash)
```

### Gas Estimation

Get gas information for transactions:

```typescript
const gasInfo = await vault.gas(Chain.Ethereum)

console.log('Gas Price:', gasInfo.gasPrice)
console.log('Max Priority Fee:', gasInfo.maxPriorityFeePerGas)
console.log('Max Fee:', gasInfo.maxFeePerGas)
```

### Max Send Amount

Calculate the maximum amount you can send for a coin in a single call. Returns balance, estimated network fee, and max sendable amount — all in base units:

```typescript
const { balance, fee, maxSendable } = await vault.getMaxSendAmount({
  coin: {
    chain: Chain.Ethereum,
    address: await vault.address(Chain.Ethereum),
    decimals: 18,
    ticker: 'ETH',
  },
  receiver: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
})

console.log('Balance:', balance)        // e.g., 5000000000000000000n (5 ETH)
console.log('Fee:', fee)                // e.g., 21000000000000n
console.log('Max sendable:', maxSendable) // e.g., 4999979000000000000n

// Use maxSendable as the amount for a "send max" transaction
const keysignPayload = await vault.prepareSendTx({
  coin,
  receiver: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
  amount: maxSendable,
})
```

### Signing Arbitrary Bytes

The `signBytes()` method allows you to sign pre-hashed data directly, giving you full control over transaction construction. This is useful when you need to:

* Sign transactions built with external libraries (ethers.js, viem, bitcoinjs-lib, etc.)
* Implement custom signing flows not covered by `prepareSendTx()`
* Sign arbitrary messages for authentication or verification

**Input Formats:**

```typescript
// Uint8Array
const hash = new Uint8Array(32).fill(0xab)
const sig = await vault.signBytes({ data: hash, chain: Chain.Ethereum })

// Buffer
const hash = Buffer.from('...', 'hex')
const sig = await vault.signBytes({ data: hash, chain: Chain.Ethereum })

// Hex string (with or without 0x prefix)
const sig = await vault.signBytes({ data: '0xabc123...', chain: Chain.Ethereum })
const sig = await vault.signBytes({ data: 'abc123...', chain: Chain.Ethereum })
```

**Chain Parameter:**

The `chain` parameter determines the signing algorithm and derivation path:

* **ECDSA chains** (Ethereum, Bitcoin, Polygon, etc.): Uses secp256k1, returns `{ signature, recovery }`
* **EdDSA chains** (Solana, Sui): Uses Ed25519, returns `{ signature }`

**Complete Example: Custom EVM Transaction**

```typescript
import { keccak256, Transaction, parseEther } from 'ethers'
import { Chain } from '@vultisig/sdk'

// Step 1: Build transaction externally
const tx = Transaction.from({
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
  value: parseEther('0.1'),
  gasLimit: 21000n,
  maxFeePerGas: 50000000000n,
  maxPriorityFeePerGas: 2000000000n,
  nonce: 42,
  chainId: 1,
  type: 2  // EIP-1559
})

// Step 2: Get the unsigned transaction hash
const unsignedHash = keccak256(tx.unsignedSerialized)

// Step 3: Sign the hash with signBytes
const signature = await vault.signBytes({
  data: unsignedHash,
  chain: Chain.Ethereum
})

// Step 4: Apply signature to transaction
const signedTx = tx.clone()
signedTx.signature = {
  r: '0x' + signature.signature.slice(0, 64),
  s: '0x' + signature.signature.slice(64, 128),
  v: signature.recovery! + 27
}

// Step 5: Broadcast using SDK
const txHash = await vault.broadcastRawTx({
  chain: Chain.Ethereum,
  rawTx: signedTx.serialized
})
console.log('Transaction hash:', txHash)
```

**Complete Example: Bitcoin Transaction with bitcoinjs-lib**

```typescript
import * as bitcoin from 'bitcoinjs-lib'
import { Chain } from '@vultisig/sdk'

// Step 1: Build PSBT externally
const psbt = new bitcoin.Psbt({ network: bitcoin.networks.bitcoin })
psbt.addInput({
  hash: 'previous-txid...',
  index: 0,
  witnessUtxo: { script: Buffer.from('...'), value: 100000 }
})
psbt.addOutput({
  address: 'bc1q...',
  value: 90000
})

// Step 2: Get sighash for each input
const sighash = psbt.getTxForSigning().hashForWitnessV0(
  0,  // input index
  Buffer.from('...'),  // scriptCode
  100000,  // value
  bitcoin.Transaction.SIGHASH_ALL
)

// Step 3: Sign with signBytes
const signature = await vault.signBytes({
  data: sighash,
  chain: Chain.Bitcoin
})

// Step 4: Apply signature to PSBT
// (Implementation depends on your PSBT setup)

// Step 5: Finalize and broadcast using SDK
psbt.finalizeAllInputs()
const rawTx = psbt.extractTransaction().toHex()
const txHash = await vault.broadcastRawTx({
  chain: Chain.Bitcoin,
  rawTx
})
console.log('Transaction hash:', txHash)
```

**Return Type:**

```typescript
type Signature = {
  signature: string   // Hex-encoded signature (r || s for ECDSA, full sig for EdDSA)
  recovery?: number   // Recovery byte for ECDSA (0 or 1), undefined for EdDSA
}
```

**Note:** `signBytes()` is available for both FastVault and SecureVault. For SecureVault, provide signing options with callbacks for device coordination.

### Broadcasting Raw Transactions

The `broadcastRawTx()` method broadcasts pre-signed raw transactions to the blockchain network. Use this with `signBytes()` for custom transaction workflows.

```typescript
const txHash = await vault.broadcastRawTx({
  chain: Chain.Ethereum,
  rawTx: '0x02f8...'  // hex-encoded signed transaction
})
```

**Supported Input Formats:**

| Chain Family                              | Input Format                             |
| ----------------------------------------- | ---------------------------------------- |
| EVM (Ethereum, Polygon, BSC, etc.)        | Hex-encoded signed tx (with/without 0x)  |
| UTXO (Bitcoin, Litecoin, etc.)            | Hex-encoded raw tx                       |
| Solana                                    | Base58 or Base64 encoded tx bytes        |
| Cosmos (Cosmos, Osmosis, THORChain, etc.) | JSON `{tx_bytes}` or raw base64 protobuf |
| TON                                       | BOC (Bag of Cells) as base64 string      |
| Polkadot                                  | Hex-encoded extrinsic                    |
| Ripple                                    | Hex-encoded tx blob                      |
| Sui                                       | JSON `{unsignedTx, signature}`           |
| Tron                                      | JSON tx object                           |

**Error Handling:**

The method throws `VaultError` with these codes:

* `BroadcastFailed` - Transaction failed to broadcast (may include "already submitted" errors)
* `UnsupportedChain` - Chain not yet supported for raw broadcast

```typescript
import { VaultError, VaultErrorCode } from '@vultisig/sdk'

try {
  const txHash = await vault.broadcastRawTx({ chain, rawTx })
} catch (error) {
  if (error instanceof VaultError) {
    if (error.code === VaultErrorCode.BroadcastFailed) {
      console.log('Broadcast failed:', error.message)
    }
  }
}
```

### Checking Transaction Status

After broadcasting, use `getTxStatus()` to check whether a transaction has been confirmed, is still pending, or has failed:

```typescript
const txHash = await vault.broadcastTx({ chain, keysignPayload, signature })

// Poll for confirmation
const checkStatus = async () => {
  const result = await vault.getTxStatus({ chain: Chain.Ethereum, txHash })

  switch (result.status) {
    case 'success':
      console.log(`Confirmed! Fee: ${result.receipt?.feeAmount} ${result.receipt?.feeTicker}`)
      return true
    case 'error':
      console.log('Transaction failed on-chain')
      return true
    case 'pending':
      console.log('Still pending...')
      return false
  }
}
```

**Supported chains:** All chain families (EVM, UTXO, Cosmos, Solana, Sui, Polkadot, Ripple, Tron, Cardano, TON).

**Return type (`TxStatusResult`):**

* `status: 'pending' | 'success' | 'error'` - Current on-chain status
* `receipt?: TxReceiptInfo` - Fee details when available:
  * `feeAmount: bigint` - Fee paid in base units
  * `feeDecimals: number` - Decimal places for the fee token
  * `feeTicker: string` - Fee token symbol (e.g., "ETH", "BTC")

**Error handling:**

```typescript
import { VaultError, VaultErrorCode } from '@vultisig/sdk'

try {
  const result = await vault.getTxStatus({ chain, txHash })
} catch (error) {
  if (error instanceof VaultError && error.code === VaultErrorCode.NetworkError) {
    console.log('RPC request failed:', error.message)
  }
}
```

### Cosmos Signing (SignAmino & SignDirect)

For Cosmos SDK chains (Cosmos, Osmosis, THORChain, MayaChain, Dydx, Kujira, etc.), the SDK provides two signing methods that give you full control over transaction construction:

* **SignAmino**: Legacy JSON/Amino format, widely supported
* **SignDirect**: Modern Protobuf format, more efficient

#### SignAmino Example (Governance Vote)

```typescript
import { Chain } from '@vultisig/sdk'

const cosmosAddress = await vault.address(Chain.Cosmos)

// Prepare a governance vote using SignAmino
const payload = await vault.prepareSignAminoTx({
  chain: 'Cosmos',
  coin: {
    chain: 'Cosmos',
    address: cosmosAddress,
    decimals: 6,
    ticker: 'ATOM',
  },
  msgs: [{
    type: 'cosmos-sdk/MsgVote',
    value: JSON.stringify({
      proposal_id: '123',
      voter: cosmosAddress,
      option: 'VOTE_OPTION_YES',
    }),
  }],
  fee: {
    amount: [{ denom: 'uatom', amount: '5000' }],
    gas: '200000',
  },
  memo: 'Vote via Vultisig SDK',
})

// Sign and broadcast
const signature = await vault.sign(payload)
const txHash = await vault.broadcastTx({
  chain: Chain.Cosmos,
  keysignPayload: payload,
  signature,
})
```

#### SignAmino with Multiple Messages

```typescript
// Send multiple transactions in a single batch
const payload = await vault.prepareSignAminoTx({
  chain: 'Cosmos',
  coin: {
    chain: 'Cosmos',
    address: cosmosAddress,
    decimals: 6,
    ticker: 'ATOM',
  },
  msgs: [
    {
      type: 'cosmos-sdk/MsgSend',
      value: JSON.stringify({
        from_address: cosmosAddress,
        to_address: 'cosmos1recipient1...',
        amount: [{ denom: 'uatom', amount: '1000000' }],
      }),
    },
    {
      type: 'cosmos-sdk/MsgSend',
      value: JSON.stringify({
        from_address: cosmosAddress,
        to_address: 'cosmos1recipient2...',
        amount: [{ denom: 'uatom', amount: '2000000' }],
      }),
    },
  ],
  fee: {
    amount: [{ denom: 'uatom', amount: '10000' }],
    gas: '300000',
  },
})
```

#### SignDirect Example (Pre-encoded Transaction)

Use SignDirect when you have pre-encoded Protobuf transaction bytes:

```typescript
// SignDirect with pre-encoded bytes (from cosmjs or similar)
const payload = await vault.prepareSignDirectTx({
  chain: 'Cosmos',
  coin: {
    chain: 'Cosmos',
    address: cosmosAddress,
    decimals: 6,
    ticker: 'ATOM',
  },
  bodyBytes: 'base64EncodedTxBodyBytes...',
  authInfoBytes: 'base64EncodedAuthInfoBytes...',
  chainId: 'cosmoshub-4',
  accountNumber: '12345',
})

const signature = await vault.sign(payload)
```

#### Supported Cosmos Chains

| Chain        | Chain ID       | Native Denom |
| ------------ | -------------- | ------------ |
| Cosmos       | cosmoshub-4    | uatom        |
| Osmosis      | osmosis-1      | uosmo        |
| THORChain    | thorchain-1    | rune         |
| MayaChain    | mayachain-1    | cacao        |
| Dydx         | dydx-mainnet-1 | adydx        |
| Kujira       | kaiyo-1        | ukuji        |
| Terra        | phoenix-1      | uluna        |
| TerraClassic | columbus-5     | uluna        |
| Noble        | noble-1        | uusdc        |
| Akash        | akashnet-2     | uakt         |

#### Common Message Types

```typescript
// MsgSend - Transfer tokens
{ type: 'cosmos-sdk/MsgSend', value: JSON.stringify({
  from_address: '...',
  to_address: '...',
  amount: [{ denom: 'uatom', amount: '1000000' }],
})}

// MsgVote - Governance vote
{ type: 'cosmos-sdk/MsgVote', value: JSON.stringify({
  proposal_id: '123',
  voter: '...',
  option: 'VOTE_OPTION_YES',  // YES, NO, ABSTAIN, NO_WITH_VETO
})}

// MsgDelegate - Stake tokens
{ type: 'cosmos-sdk/MsgDelegate', value: JSON.stringify({
  delegator_address: '...',
  validator_address: 'cosmosvaloper1...',
  amount: { denom: 'uatom', amount: '1000000' },
})}

// MsgUndelegate - Unstake tokens
{ type: 'cosmos-sdk/MsgUndelegate', value: JSON.stringify({
  delegator_address: '...',
  validator_address: 'cosmosvaloper1...',
  amount: { denom: 'uatom', amount: '1000000' },
})}

// MsgWithdrawDelegatorReward - Claim staking rewards
{ type: 'cosmos-sdk/MsgWithdrawDelegatorReward', value: JSON.stringify({
  delegator_address: '...',
  validator_address: 'cosmosvaloper1...',
})}
```

***

### Token Management

Add and manage custom tokens:

```typescript
// Add ERC-20 token
await vault.addToken(Chain.Ethereum, {
  id: 'usdt',
  symbol: 'USDT',
  name: 'Tether USD',
  decimals: 6,
  contractAddress: '0xdac17f958d2ee523a2206206994597c13d831ec7',
  chainId: 'ethereum'
})

// Get tokens for a chain
const tokens = vault.getTokens(Chain.Ethereum)

for (const token of tokens) {
  console.log(`${token.symbol}: ${token.contractAddress}`)
}

// Check token balance
const usdtBalance = await vault.balance(Chain.Ethereum, 'usdt')

// Remove token
await vault.removeToken(Chain.Ethereum, 'usdt')
```

### Chain Management

Manage which chains are active for the vault:

```typescript
// Add a chain
await vault.addChain(Chain.Polygon)

// Add multiple chains
await vault.setChains([
  Chain.Bitcoin,
  Chain.Ethereum,
  Chain.Polygon,
  Chain.Solana
])

// Remove a chain
await vault.removeChain(Chain.Litecoin)

// Reset to default chains
await vault.resetToDefaultChains()
```

### Portfolio Value

Get total portfolio value in fiat:

```typescript
// Get total value
const totalValue = await vault.getTotalValue('USD')
console.log(`Total portfolio value: $${totalValue}`)

// Get value for specific asset
const ethValue = await vault.getValue(Chain.Ethereum, null, 'USD')

// Force refresh portfolio value
await vault.updateTotalValue()

// Change preferred currency
await vault.setCurrency('EUR')
const totalEur = await vault.getTotalValue()
console.log(`Total portfolio value: €${totalEur}`)
```

***

## Token Swaps

The SDK supports token swaps across multiple chains and protocols, including cross-chain swaps via THORChain and same-chain DEX aggregation via 1inch.

### Supported Swap Routes

| Route Type                     | Provider  | Example                |
| ------------------------------ | --------- | ---------------------- |
| Cross-chain (BTC, ETH, Cosmos) | THORChain | BTC → ETH, ETH → ATOM  |
| Same-chain EVM                 | 1inch     | ETH → USDC on Ethereum |
| Cross-chain EVM                | LiFi      | Polygon → Arbitrum     |

### Checking Swap Support

```typescript
// Get list of chains that support swaps
const supportedChains = vault.getSupportedSwapChains()
console.log('Swap-enabled chains:', supportedChains)

// Check if specific swap route is available
const canSwap = vault.isSwapSupported(Chain.Ethereum, Chain.Bitcoin)
console.log('ETH → BTC supported:', canSwap) // true
```

### Getting a Swap Quote

Get a quote before executing a swap:

```typescript
// Simple format - just specify chains (native tokens)
const quote = await vault.getSwapQuote({
  fromCoin: { chain: Chain.Ethereum },
  toCoin: { chain: Chain.Bitcoin },
  amount: 0.1  // 0.1 ETH
})

console.log(`Provider: ${quote.provider}`)           // e.g., 'thorchain'
console.log(`Output: ${quote.estimatedOutput} BTC`)  // e.g., '0.00234 BTC'
console.log(`Expires: ${new Date(quote.expiresAt)}`)
console.log(`Fees: ${quote.fees.total}`)

// Balance + max swappable amount (included automatically)
console.log(`Balance: ${quote.balance}`)         // Source coin balance in base units
console.log(`Max swapable: ${quote.maxSwapable}`) // balance - network fee (native), or full balance (tokens)

// Check if approval is needed (ERC-20 tokens)
if (quote.requiresApproval) {
  console.log(`Approval needed for: ${quote.approvalInfo?.spender}`)
}
```

### Swapping with ERC-20 Tokens

For ERC-20 tokens, specify the token contract address:

```typescript
// Swap USDC to ETH
const quote = await vault.getSwapQuote({
  fromCoin: {
    chain: Chain.Ethereum,
    token: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'  // USDC
  },
  toCoin: { chain: Chain.Ethereum },  // Native ETH
  amount: 100  // 100 USDC
})

// Or use full AccountCoin format
const ethAddress = await vault.address(Chain.Ethereum)
const quote = await vault.getSwapQuote({
  fromCoin: {
    chain: Chain.Ethereum,
    address: ethAddress,
    id: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
    ticker: 'USDC',
    decimals: 6
  },
  toCoin: {
    chain: Chain.Ethereum,
    address: ethAddress,
    ticker: 'ETH',
    decimals: 18
  },
  amount: 100
})
```

### Executing a Swap

Complete swap flow with signing and broadcasting:

```typescript
// Step 1: Get quote
const quote = await vault.getSwapQuote({
  fromCoin: { chain: Chain.Ethereum },
  toCoin: { chain: Chain.Bitcoin },
  amount: 0.1
})

// Step 2: Prepare transaction
const { keysignPayload, approvalPayload } = await vault.prepareSwapTx({
  fromCoin: { chain: Chain.Ethereum },
  toCoin: { chain: Chain.Bitcoin },
  amount: 0.1,
  swapQuote: quote
})

// Step 3: Handle approval if needed (ERC-20 tokens only)
if (approvalPayload) {
  const approvalSignature = await vault.sign(approvalPayload)
  const approvalTxHash = await vault.broadcastTx({
    chain: Chain.Ethereum,
    keysignPayload: approvalPayload,
    signature: approvalSignature
  })
  console.log('Approval tx:', approvalTxHash)
  // Wait for approval confirmation before proceeding
}

// Step 4: Sign and broadcast swap
const signature = await vault.sign(keysignPayload)
const txHash = await vault.broadcastTx({
  chain: Chain.Ethereum,
  keysignPayload,
  signature
})

console.log('Swap tx:', txHash)
```

### Checking Token Allowance

Check if ERC-20 approval is needed before swapping:

```typescript
const ethAddress = await vault.address(Chain.Ethereum)

// Check current allowance for a DEX router
const allowance = await vault.getTokenAllowance(
  {
    chain: Chain.Ethereum,
    address: ethAddress,
    id: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',  // USDC
    ticker: 'USDC',
    decimals: 6
  },
  '0x1111111254fb6c44bAC0beD2854e76F90643097d'  // 1inch router
)

console.log(`Current USDC allowance: ${allowance}`)
```

### Swap Events

Subscribe to swap-related events:

```typescript
// Listen for swap quotes
vault.on('swapQuoteReceived', ({ quote }) => {
  console.log(`Quote received from ${quote.provider}`)
  console.log(`Output: ${quote.estimatedOutput}`)
})

// Get quote - event will fire automatically
const quote = await vault.getSwapQuote({
  fromCoin: { chain: Chain.Ethereum },
  toCoin: { chain: Chain.Bitcoin },
  amount: 0.1
})
```

### Error Handling

Handle common swap errors gracefully:

```typescript
try {
  const quote = await vault.getSwapQuote({
    fromCoin: { chain: Chain.Ethereum },
    toCoin: { chain: Chain.Bitcoin },
    amount: 0.001  // Very small amount
  })
} catch (error) {
  if (error.message.includes('No swap route')) {
    console.log('No swap route available for this pair/amount')
  } else if (error.message.includes('pool')) {
    console.log('Liquidity pool not available')
  } else {
    throw error
  }
}
```

### VULT Discount Tiers

The SDK automatically applies affiliate fee discounts based on your VULT token and Thorguard NFT holdings on Ethereum. No configuration is needed - discounts are applied automatically to all swap quotes.

#### Discount Tier Levels

| Tier     | Min VULT  | Affiliate Fee  |
| -------- | --------- | -------------- |
| None     | 0         | 0.50% (50 bps) |
| Bronze   | 1,500     | 0.45% (45 bps) |
| Silver   | 3,000     | 0.40% (40 bps) |
| Gold     | 7,500     | 0.30% (30 bps) |
| Platinum | 15,000    | 0.25% (25 bps) |
| Diamond  | 100,000   | 0.15% (15 bps) |
| Ultimate | 1,000,000 | 0.00% (0 bps)  |

**Thorguard NFT Bonus:** Holders of the Thorguard NFT receive a free tier upgrade (one level higher), except for platinum tier and above.

#### Checking Your Discount Tier

```typescript
// Get current discount tier based on VULT/Thorguard holdings
const tier = await vault.getDiscountTier()
console.log(`Current tier: ${tier ?? 'none'}`)
// 'bronze' | 'silver' | 'gold' | 'platinum' | 'diamond' | 'ultimate' | null

// Force refresh after acquiring more VULT tokens
const updatedTier = await vault.updateDiscountTier()
console.log(`Updated tier: ${updatedTier ?? 'none'}`)
```

#### How It Works

1. When you request a swap quote, the SDK automatically fetches your VULT token balance and Thorguard NFT balance on Ethereum
2. Your discount tier is calculated based on these holdings
3. The reduced affiliate fee is applied to the swap quote
4. Results are cached for 15 minutes to minimize RPC calls

**Note:** The discount tier is determined automatically from your Ethereum address - you cannot manually override or set a discount tier.

***

## Token Registry & Discovery

### Looking Up Known Tokens

The SDK includes a built-in registry of well-known tokens (ERC-20, SPL, etc.). These are static methods on `Vultisig` — no vault needed:

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

// Get all known tokens for a chain
const tokens = Vultisig.getKnownTokens(Chain.Ethereum)
for (const token of tokens) {
  console.log(`${token.ticker}: ${token.contractAddress}`)
}

// Look up a specific token by contract address (case-insensitive)
const usdc = Vultisig.getKnownToken(
  Chain.Ethereum,
  '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
)
if (usdc) {
  console.log(`${usdc.ticker} - ${usdc.decimals} decimals`)
}
```

### Getting Native Fee Coins

Every chain has a native fee coin (ETH for Ethereum, BTC for Bitcoin, etc.):

```typescript
const feeCoin = Vultisig.getFeeCoin(Chain.Bitcoin)
console.log(`${feeCoin.ticker} - ${feeCoin.decimals} decimals`)
// BTC - 8 decimals
```

### Discovering Tokens at a Vault Address

Discover tokens with non-zero balances at your vault's address:

```typescript
// Discover ERC-20 tokens on Ethereum (uses 1inch API)
const tokens = await vault.discoverTokens(Chain.Ethereum)
for (const token of tokens) {
  console.log(`${token.ticker}: balance ${token.balance}`)
}

// Also works for Solana (SPL via Jupiter) and Cosmos (IBC)
const solTokens = await vault.discoverTokens(Chain.Solana)
```

### Resolving Token Metadata

Resolve token metadata by contract address. Checks the built-in registry first (fast, no network), then falls back to chain APIs:

```typescript
// Known token → instant, no network call
const usdc = await vault.resolveToken(
  Chain.Ethereum,
  '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'
)

// Unknown token → fetches from chain API
const customToken = await vault.resolveToken(
  Chain.Ethereum,
  '0x6982508145454Ce325dDbE47a25d4ec3d2311933'
)
console.log(`${customToken.ticker} - ${customToken.decimals} decimals`)
```

### Cosmos Message Type Constants

The SDK exports `CosmosMsgType` constants for constructing Cosmos transactions:

```typescript
import { CosmosMsgType } from '@vultisig/sdk'

// Amino-style type strings
CosmosMsgType.MsgSend              // 'cosmos-sdk/MsgSend'
CosmosMsgType.ThorchainMsgSend     // 'thorchain/MsgSend'
CosmosMsgType.MsgExecuteContract   // 'wasm/MsgExecuteContract'
CosmosMsgType.ThorchainMsgDeposit  // 'thorchain/MsgDeposit'

// URL-style type strings (for SignDirect / protobuf)
CosmosMsgType.MsgSendUrl              // '/cosmos.bank.v1beta1.MsgSend'
CosmosMsgType.MsgTransferUrl          // '/ibc.applications.transfer.v1.MsgTransfer'
CosmosMsgType.MsgExecuteContractUrl   // '/cosmwasm.wasm.v1.MsgExecuteContract'
CosmosMsgType.ThorchainMsgDepositUrl  // '/types.MsgDeposit'
CosmosMsgType.ThorchainMsgSendUrl     // '/types.MsgSend'
```

***

## Price Feeds

Fetch current token prices by their CoinGecko price provider IDs:

```typescript
import { Vultisig } from '@vultisig/sdk'

// Fetch prices (static method, no vault needed)
const prices = await Vultisig.getCoinPrices({
  ids: ['bitcoin', 'ethereum', 'solana']
})
console.log(`BTC: $${prices.bitcoin}`)  // BTC: $50000
console.log(`ETH: $${prices.ethereum}`) // ETH: $3000

// Use a different fiat currency
const eurPrices = await Vultisig.getCoinPrices({
  ids: ['bitcoin'],
  fiatCurrency: 'eur'
})
```

**Tip:** Use `Vultisig.getFeeCoin(chain).priceProviderId` or `Vultisig.getKnownToken(chain, address)?.priceProviderId` to get the CoinGecko ID for a token.

***

## Security Scanning

### Site Scanning

Check if a website URL is malicious (phishing, scams) using Blockaid:

```typescript
import { Vultisig } from '@vultisig/sdk'

const result = await Vultisig.scanSite('https://suspicious-site.com')
if (result.isMalicious) {
  console.warn('WARNING: Malicious site detected!')
}
```

### Transaction Validation

Validate a transaction for security risks before signing. Detects malicious contracts, unlimited approvals, phishing, etc.:

```typescript
// After preparing a transaction
const keysignPayload = await vault.prepareSendTx({ coin, receiver, amount })

const validation = await vault.validateTransaction(keysignPayload)
if (validation) {
  console.log(`Description: ${validation.description}`)
  console.log(`Risky: ${validation.isRisky}`)
  if (validation.isRisky) {
    console.warn(`Risk level: ${validation.riskLevel}`) // 'medium' or 'high'
  }
  console.log('Features:', validation.features)
}
// Returns null for unsupported chains
```

**Supported chains for validation:** EVM chains, Solana, Sui, Bitcoin.

### Transaction Simulation

Preview asset changes before signing:

```typescript
const simulation = await vault.simulateTransaction(keysignPayload)
if (simulation) {
  console.log(`Chain kind: ${simulation.chainKind}`) // 'evm' or 'solana'
  console.log('Simulation data:', simulation.simulation)
}
// Returns null for unsupported chains
```

**Supported chains for simulation:** EVM chains, Solana.

***

## Fiat On-Ramp (Banxa)

Generate Banxa fiat on-ramp URLs to buy crypto directly to your vault address:

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

// Check which chains Banxa supports
const supportedChains = Vultisig.getBanxaSupportedChains()
console.log(`Banxa supports ${supportedChains.length} chains`)

// Generate a buy URL for the vault's address
const buyUrl = await vault.getBuyUrl(Chain.Bitcoin)
if (buyUrl) {
  // Open in browser / webview
  window.open(buyUrl)
}

// Specify a token ticker (e.g., buy USDC instead of ETH)
const usdcBuyUrl = await vault.getBuyUrl(Chain.Ethereum, 'USDC')

// Returns null if chain is not supported by Banxa
const unsupported = await vault.getBuyUrl(Chain.Cosmos)
// null — Cosmos is not in Banxa's supported chains
```

***

## Push Notifications

Coordinate multi-party signing sessions by sending push notifications to vault members. The SDK handles server communication; consumers are responsible for platform-specific push token acquisition and incoming push wiring.

### Register a Device

```typescript
// Obtain a push token from your platform (APNs, FCM, Web Push)
const token = await getMyPlatformPushToken()

await sdk.notifications.registerDevice({
  vaultId: vault.publicKeys.ecdsa,
  partyName: vault.localPartyId,
  token,
  deviceType: 'ios', // 'ios' | 'android' | 'web'
})
```

### Notify Vault Members

When initiating a signing session, notify other members so they can join:

```typescript
await sdk.notifications.notifyVaultMembers({
  vaultId: vault.publicKeys.ecdsa,
  vaultName: vault.name,
  localPartyId: vault.localPartyId,
  qrCodeData: keysignQrPayload, // session data for joining
})
```

### Handle Incoming Push Notifications

Register a callback, then forward raw push data from your platform's handler:

```typescript
// Register handler
const unsubscribe = sdk.notifications.onSigningRequest((notification) => {
  console.log(`Signing request for vault: ${notification.vaultName}`)
  // Use notification.qrCodeData to join the signing session
})

// In your platform's push handler (iOS delegate, FCM onMessage, service worker, etc.)
sdk.notifications.handleIncomingPush(rawPushData)

// Clean up when done
unsubscribe()
```

### Consumer Responsibilities

| Responsibility                                       | Owner        |
| ---------------------------------------------------- | ------------ |
| Obtain push token (APNs / FCM / Web Push)            | **Consumer** |
| Register token with notification server              | SDK          |
| Trigger notification to vault members                | SDK          |
| Wire platform push handler to `handleIncomingPush()` | **Consumer** |
| Parse incoming notification data                     | SDK          |
| Display notification to user                         | **Consumer** |
| Route to signing flow using `qrCodeData`             | **Consumer** |

### WebSocket Real-Time Delivery

For environments where platform push isn't available (browser extensions, Electron, Node.js), the SDK provides a built-in WebSocket transport. Messages are delivered through the same `onSigningRequest()` callbacks — no platform push handler wiring needed.

```typescript
// Step 1: Register device (same as platform push)
await sdk.notifications.registerDevice({
  vaultId: vault.publicKeys.ecdsa,
  partyName: vault.localPartyId,
  token: myDeviceToken,       // Any stable unique identifier
  deviceType: 'web',
})

// Step 2: Connect WebSocket
sdk.notifications.connect({
  vaultId: vault.publicKeys.ecdsa,
  partyName: vault.localPartyId,
  token: myDeviceToken,       // Same token used for registerDevice()
})

// Step 3: Handle notifications (same callback as platform push)
const unsubscribe = sdk.notifications.onSigningRequest((notification) => {
  console.log(`Signing request for vault: ${notification.vaultName}`)
  // Use notification.qrCodeData to join the signing session
})

// Step 4: Monitor connection state (optional)
const unsubState = sdk.notifications.onConnectionStateChange((state) => {
  // state: 'disconnected' | 'connecting' | 'connected' | 'reconnecting'
  console.log('WebSocket state:', state)
})

// Step 5: Disconnect when done
sdk.notifications.disconnect()
unsubscribe()
unsubState()
```

**Auto-reconnect:** If the connection drops, the SDK automatically reconnects with exponential backoff (1s → 2s → 4s → ... capped at 30s). The server retains unacknowledged messages for 60 seconds and re-delivers them on reconnect — no messages are lost during brief disconnections.

**ACK protocol:** The SDK automatically acknowledges each received notification so the server does not re-deliver it.

**Lifecycle tip:** For browser extensions, connect when the popup opens and disconnect on close. `sdk.dispose()` calls `disconnect()` automatically.

### Web Push (Browser / Extension)

For web platforms using the Web Push API with service workers, fetch the VAPID public key from the server to subscribe:

```typescript
const vapidKey = await sdk.notifications.fetchVapidPublicKey()
const subscription = await registration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: vapidKey,
})

await sdk.notifications.registerDevice({
  vaultId: vault.publicKeys.ecdsa,
  partyName: vault.localPartyId,
  token: JSON.stringify(subscription.toJSON()),
  deviceType: 'web',
})
```

> **Tip:** For browser extensions, prefer WebSocket delivery (see above) over Web Push since extensions can maintain a direct connection while the popup is open.

### Utility Methods

```typescript
// Check if a vault has local registration
const registered = await sdk.notifications.isVaultRegistered(vaultId)

// Check if any devices are registered on the server
const hasRemote = await sdk.notifications.hasRemoteRegistrations(vaultId)

// Remove local registration
await sdk.notifications.unregisterVault(vaultId)

// Parse notification payload manually (without invoking callbacks)
const parsed = sdk.notifications.parseNotificationPayload(rawData)

// Check WebSocket connection state
const state = sdk.notifications.connectionState
// 'disconnected' | 'connecting' | 'connected' | 'reconnecting'

// Health check
const healthy = await sdk.notifications.ping()
```

> **Note:** Node.js / CLI environments have no native push receive mechanism. Use WebSocket delivery (`connect()`) or `parseNotificationPayload()` manually if you implement your own transport.

***

## Configuration

### SDK Instance Configuration

All configuration is passed to the `Vultisig` constructor. The SDK uses instance-scoped configuration (no global state):

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

const sdk = new Vultisig({
  // Required: Storage implementation
  storage: new FileStorage(),  // Or MemoryStorage, or custom implementation

  // Optional: Default chains for new vaults
  defaultChains: [Chain.Bitcoin, Chain.Ethereum, Chain.Solana],

  // Optional: Default fiat currency
  defaultCurrency: 'USD',

  // Optional: Password management
  onPasswordRequired: async (vaultId, vaultName) => {
    return await promptUserForPassword(vaultName)
  },

  // Optional: Password cache settings
  passwordCache: {
    defaultTTL: 300000  // 5 minutes
  },

  // Optional: Cache configuration
  cacheConfig: {
    balanceTTL: 300000,  // 5 minutes (default)
    priceTTL: 300000,    // 5 minutes (default)
  },

  // Optional: Custom server endpoints (advanced)
  serverEndpoints: {
    fastVault: 'https://custom-api.example.com',
    messageRelay: 'https://custom-relay.example.com'
  }
})

await sdk.initialize()

// ... use the SDK ...

// Clean up when done (releases resources)
sdk.dispose()
```

### Multiple SDK Instances

You can create multiple isolated SDK instances, each with its own storage and configuration:

```typescript
// Instance for user 1
const sdk1 = new Vultisig({
  storage: new FileStorage('./user1/vaults'),
  defaultCurrency: 'USD',
})

// Instance for user 2
const sdk2 = new Vultisig({
  storage: new FileStorage('./user2/vaults'),
  defaultCurrency: 'EUR',
})

// Each instance is completely isolated
await sdk1.initialize()
await sdk2.initialize()

// Clean up both when done
sdk1.dispose()
sdk2.dispose()
```

### Custom Storage Implementation

Implement the `Storage` interface for custom persistence:

```typescript
import { Vultisig, type VaultStorage } from '@vultisig/sdk'
import * as fs from 'fs'
import * as path from 'path'

class CustomStorage implements Storage {
  constructor(private basePath: string) {}

  async get(key: string): Promise<string | null> {
    try {
      return fs.readFileSync(path.join(this.basePath, key), 'utf-8')
    } catch {
      return null
    }
  }

  async set(key: string, value: string): Promise<void> {
    fs.writeFileSync(path.join(this.basePath, key), value, 'utf-8')
  }

  async remove(key: string): Promise<void> {
    fs.unlinkSync(path.join(this.basePath, key))
  }

  async clear(): Promise<void> {
    const files = fs.readdirSync(this.basePath)
    files.forEach(file => fs.unlinkSync(path.join(this.basePath, file)))
  }

  async list(prefix?: string): Promise<string[]> {
    const files = fs.readdirSync(this.basePath)
    return prefix ? files.filter(f => f.startsWith(prefix)) : files
  }
}

// Use custom storage
const sdk = new Vultisig({
  storage: new CustomStorage('./vaults')
})

await sdk.initialize()
// ... use the SDK ...
sdk.dispose()
```

***

## Caching System

The SDK uses a multi-level caching system for optimal performance:

### Address Caching

Addresses are cached indefinitely by default (they never change):

```typescript
// First call - derives address from keys
const address = await vault.address(Chain.Ethereum) // ~100ms

// Subsequent calls - instant from cache
const cachedAddress = await vault.address(Chain.Ethereum) // <1ms
```

Addresses are cached permanently (they never change for a vault) and persisted to storage.

### Balance Caching

Balances are cached to avoid excessive API calls:

```typescript
// First call - fetches from blockchain
const balance = await vault.balance(Chain.Ethereum) // ~500ms

// Within TTL - returns cached value
const cachedBalance = await vault.balance(Chain.Ethereum) // <1ms

// Force refresh
await vault.updateBalance(Chain.Ethereum) // Bypasses cache

// Refresh all balances
await vault.updateBalances() // Bypasses cache for all chains
```

Configure cache TTLs:

```typescript
const sdk = new Vultisig({
  storage: new FileStorage(),
  cacheConfig: {
    balanceTTL: 300000,  // 5 minutes (default)
    priceTTL: 300000,    // 5 minutes (default)
  }
})
```

### Password Caching

Passwords are cached to avoid repeated prompts (see [Password Management](#password-management)):

```typescript
const sdk = new Vultisig({
  storage: new FileStorage(),
  passwordCache: {
    defaultTTL: 300000  // 5 minutes
  }
})

// Manually clear password cache
await vault.lock()

// Check if password is cached
if (vault.isUnlocked()) {
  console.log('Password is cached')
}
```

### Portfolio Value

Total portfolio value is calculated from cached balances and prices:

```typescript
// Calculates from all balances × prices (uses cached values)
const value = await vault.getTotalValue()

// Force refresh prices first, then get total
await vault.updateValues('all')
const freshValue = await vault.getTotalValue()
```

### Cache Invalidation

Caches are automatically invalidated when:

* Balance updated from transaction
* Token added/removed
* Chain added/removed
* Currency changed

Manual cache clearing:

```typescript
// Clear specific balance cache
await vault.updateBalance(Chain.Ethereum)

// Clear all balance caches
await vault.updateBalances()

// Password cache (lock vault)
await vault.lock()
```

***

## Event System

Subscribe to vault events for reactive UIs:

### Available Events

```typescript
// Vault Lifecycle Events
vault.on('saved', () => console.log('Vault saved'))
vault.on('loaded', () => console.log('Vault loaded'))
vault.on('deleted', () => console.log('Vault deleted'))
vault.on('unlocked', () => console.log('Vault unlocked'))
vault.on('locked', () => console.log('Vault locked'))

// Balance & Value Events
vault.on('balanceUpdated', ({ chain, tokenId }) => {
  console.log(`Balance updated: ${chain}${tokenId ? ':' + tokenId : ''}`)
})
vault.on('valuesUpdated', ({ chain }) => {
  console.log(`Fiat values updated for: ${chain}`)
})
vault.on('totalValueUpdated', ({ value }) => {
  console.log(`Total portfolio value: ${value.amount} ${value.currency}`)
})

// Transaction Events
vault.on('transactionSigned', ({ chain, txHash }) => {
  console.log(`Transaction signed on ${chain}: ${txHash}`)
})
vault.on('transactionBroadcast', ({ chain, txHash }) => {
  console.log(`Transaction broadcast on ${chain}: ${txHash}`)
})
vault.on('transactionConfirmed', ({ chain, txHash, receipt }) => {
  console.log(`Transaction confirmed on ${chain}: ${txHash}`)
  if (receipt) {
    console.log(`  Block: ${receipt.blockNumber}, Fee: ${receipt.fee}`)
  }
})
vault.on('transactionFailed', ({ chain, txHash }) => {
  console.log(`Transaction failed on ${chain}: ${txHash}`)
})
vault.on('signingProgress', ({ step, progress, message }) => {
  console.log(`Signing: ${message} (${progress}%)`)
})

// Chain & Token Events
vault.on('chainAdded', ({ chain }) => {
  console.log(`Chain added: ${chain}`)
})
vault.on('chainRemoved', ({ chain }) => {
  console.log(`Chain removed: ${chain}`)
})
vault.on('tokenAdded', ({ chain, token }) => {
  console.log(`Token added on ${chain}: ${token.symbol}`)
})
vault.on('tokenRemoved', ({ chain, tokenId }) => {
  console.log(`Token removed from ${chain}: ${tokenId}`)
})

// Vault Management Events
vault.on('renamed', ({ oldName, newName }) => {
  console.log(`Vault renamed: ${oldName} -> ${newName}`)
})

// Swap Events
vault.on('swapQuoteReceived', ({ quote }) => {
  console.log(`Swap quote: ${quote.estimatedOutput} via ${quote.provider}`)
})
vault.on('swapApprovalRequired', ({ token, spender }) => {
  console.log(`ERC-20 approval required for ${token}`)
})
vault.on('swapApprovalGranted', ({ token, txHash }) => {
  console.log(`Approval granted: ${txHash}`)
})
vault.on('swapPrepared', ({ keysignPayload }) => {
  console.log('Swap transaction prepared')
})

// SecureVault Device Coordination Events
vault.on('qrCodeReady', ({ qrPayload, action, sessionId }) => {
  console.log(`QR ready for ${action}`)
  displayQRCode(qrPayload)
})
vault.on('deviceJoined', ({ deviceId, totalJoined, required }) => {
  console.log(`Device joined: ${totalJoined}/${required}`)
})
vault.on('allDevicesReady', ({ devices, sessionId }) => {
  console.log(`All ${devices.length} devices ready`)
})
vault.on('keygenProgress', ({ phase, message }) => {
  console.log(`Keygen ${phase}: ${message}`)
})

// Error Events
vault.on('error', (error) => {
  console.error('Vault error:', error.message)
})
```

### Event Patterns

**React Example:**

```typescript
import { useEffect, useState } from 'react'

function BalanceDisplay({ vault, chain }) {
  const [balance, setBalance] = useState(null)

  useEffect(() => {
    // Initial load
    vault.balance(chain).then(setBalance)

    // Subscribe to updates
    const handler = ({ chain: updatedChain }) => {
      if (updatedChain === chain) {
        vault.balance(chain).then(setBalance)
      }
    }

    vault.on('balanceUpdated', handler)

    // Cleanup
    return () => vault.off('balanceUpdated', handler)
  }, [vault, chain])

  return <div>{balance?.amount} {balance?.symbol}</div>
}
```

**Unsubscribe from Events:**

```typescript
const handler = (data) => console.log(data)

vault.on('balanceUpdated', handler)

// Later...
vault.off('balanceUpdated', handler)
```

***

## Quick Reference

### Vultisig Class Methods

```typescript
class Vultisig {
  // Constructor - storage uses platform default if not provided
  constructor(config?: {
    storage?: Storage              // Optional - uses FileStorage (Node) or BrowserStorage (browser)
    defaultChains?: Chain[]
    defaultCurrency?: string
    onPasswordRequired?: (vaultId: string, vaultName: string) => Promise<string>
    passwordCache?: { defaultTTL: number }
    cacheConfig?: { balanceTTL?: number, priceTTL?: number, maxMemoryCacheSize?: number }
    serverEndpoints?: { fastVault?: string, messageRelay?: string }
  })

  // Initialization
  initialize(): Promise<void>

  // Cleanup (releases all resources)
  dispose(): void

  // Vault creation (returns vaultId - call verifyVault to get the vault)
  createFastVault(options: {
    name: string
    password: string
    email: string
    signal?: AbortSignal
    onProgress?: (step: VaultCreationStep) => void
  }): Promise<string>

  // Create multi-device secure vault with N-of-M threshold
  createSecureVault(options: {
    name: string
    password?: string              // Optional encryption
    devices: number                // Number of participating devices
    threshold?: number             // Signing threshold (defaults to ceil(devices*2/3))
    signal?: AbortSignal
    onProgress?: (step: VaultCreationStep) => void
    onQRCodeReady?: (qrPayload: string) => void
    onDeviceJoined?: (deviceId: string, total: number, required: number) => void
  }): Promise<{ vault: SecureVault, vaultId: string, sessionId: string }>

  // Vault management
  importVault(vultContent: string, password?: string): Promise<VaultBase>
  listVaults(): Promise<VaultBase[]>
  getVaultById(id: string): Promise<VaultBase | null>
  getActiveVault(): Promise<VaultBase | null>
  hasActiveVault(): Promise<boolean>
  setActiveVault(vault: VaultBase | null): Promise<void>
  deleteVault(vault: VaultBase): Promise<void>
  clearVaults(): Promise<void>

  // Utilities
  isVaultEncrypted(vultContent: string): boolean
  isVaultContentEncrypted(vultContent: string): Promise<boolean>
  getServerStatus(): Promise<ServerStatus>

  // Static utilities
  static getTxExplorerUrl(chain: Chain, txHash: string): string
  static getAddressExplorerUrl(chain: Chain, address: string): string
  static isFastVault(vault: VaultBase): vault is FastVault
  static isSecureVault(vault: VaultBase): vault is SecureVault

  // Token registry (static, no vault needed)
  static getKnownTokens(chain: Chain): TokenInfo[]
  static getKnownToken(chain: Chain, contractAddress: string): TokenInfo | null
  static getFeeCoin(chain: Chain): FeeCoinInfo
  static getBanxaSupportedChains(): Chain[]

  // Price feeds (static)
  static getCoinPrices(params: { ids: string[], fiatCurrency?: string }): Promise<Record<string, number>>

  // Security (static)
  static scanSite(url: string): Promise<SiteScanResult>

  // Seedphrase-based vault creation
  validateSeedphrase(mnemonic: string): Promise<SeedphraseValidation>
  discoverChainsFromSeedphrase(
    mnemonic: string,
    chains?: Chain[],
    onProgress?: (progress: ChainDiscoveryProgress) => void
  ): Promise<ChainDiscoveryAggregate>  // Returns { results, usePhantomSolanaPath }
  createFastVaultFromSeedphrase(options: CreateFastVaultFromSeedphraseOptions): Promise<string>
  createSecureVaultFromSeedphrase(options: CreateSecureVaultFromSeedphraseOptions): Promise<{
    vault: SecureVault
    vaultId: string
    sessionId: string
    discoveredChains?: ChainDiscoveryResult[]
  }>
  joinSecureVault(qrPayload: string, options: JoinSecureVaultOptions): Promise<{
    vault: SecureVault
    vaultId: string
  }>

  // Address book
  getAddressBook(chain?: Chain): Promise<AddressBook>
  addAddressBookEntry(entries: AddressBookEntry[]): Promise<void>
  removeAddressBookEntry(addresses: Array<{ chain: Chain, address: string }>): Promise<void>
  updateAddressBookEntry(chain: Chain, address: string, name: string): Promise<void>

  // Vault verification (returns the vault on success)
  verifyVault(vaultId: string, code: string): Promise<FastVault>
  resendVaultVerification(options: { vaultId: string, email: string, password: string }): Promise<void>
}
```

### VaultBase Methods

```typescript
class VaultBase {
  // Properties
  id: string
  name: string
  type: 'fast' | 'secure'
  isEncrypted: boolean
  threshold: number
  chains: Chain[]
  tokens: Record<string, Token[]>
  currency: string

  // Vault management
  save(): Promise<void>
  load(): Promise<void>
  exists(): Promise<boolean>
  loadPreferences(): Promise<void>
  rename(newName: string): Promise<void>
  export(password?: string): Promise<{ filename: string, data: string }>
  delete(): Promise<void>
  lock(): void
  unlock(password: string): Promise<void>
  isUnlocked(): boolean
  getUnlockTimeRemaining(): number | undefined

  // Addresses
  address(chain: Chain): Promise<string>
  addresses(chains?: Chain[]): Promise<Record<string, string>>

  // Balances
  balance(chain: Chain, tokenId?: string): Promise<Balance>
  balances(chains?: Chain[], includeTokens?: boolean): Promise<Record<string, Balance>>
  updateBalance(chain: Chain, tokenId?: string): Promise<Balance>
  updateBalances(chains?: Chain[], includeTokens?: boolean): Promise<Record<string, Balance>>

  // Transactions
  prepareSendTx(params: SendTxParams): Promise<KeysignPayload>
  getMaxSendAmount(params: { coin: AccountCoin, receiver: string, memo?: string, feeSettings?: FeeSettings }): Promise<MaxSendAmount>
  extractMessageHashes(keysignPayload: KeysignPayload): Promise<string[]>
  sign(payload: SigningPayload, options?: SigningOptions): Promise<Signature>
  signBytes(options: SignBytesOptions, signingOptions?: SigningOptions): Promise<Signature>
  broadcastTx(params: BroadcastParams): Promise<string>
  broadcastRawTx(params: { chain: Chain, rawTx: string }): Promise<string>
  getTxStatus(params: { chain: Chain, txHash: string }): Promise<TxStatusResult>
  gas<C extends Chain>(chain: C): Promise<GasInfoForChain<C>>

  // Cosmos Signing (SignAmino & SignDirect)
  prepareSignAminoTx(input: SignAminoInput, options?: CosmosSigningOptions): Promise<KeysignPayload>
  prepareSignDirectTx(input: SignDirectInput, options?: CosmosSigningOptions): Promise<KeysignPayload>

  // SigningOptions (for SecureVault device coordination)
  // {
  //   signal?: AbortSignal
  //   onQRCodeReady?: (qrPayload: string) => void
  //   onDeviceJoined?: (deviceId: string, total: number, required: number) => void
  //   onProgress?: (step: SigningStep) => void
  // }

  // Swaps
  getSwapQuote(params: SwapQuoteParams): Promise<SwapQuoteResult>
  prepareSwapTx(params: SwapTxParams): Promise<SwapPrepareResult>
  getTokenAllowance(coin: AccountCoin, spender: string): Promise<bigint>
  getSupportedSwapChains(): readonly Chain[]
  isSwapSupported(fromChain: Chain, toChain: Chain): boolean

  // Discount Tiers (automatic VULT-based fee discounts)
  getDiscountTier(): Promise<string | null>
  updateDiscountTier(): Promise<string | null>

  // Token Discovery & Metadata
  discoverTokens(chain: Chain): Promise<DiscoveredToken[]>
  resolveToken(chain: Chain, contractAddress: string): Promise<TokenInfo>

  // Fiat On-Ramp
  getBuyUrl(chain: Chain, ticker?: string): Promise<string | null>

  // Security Scanning
  validateTransaction(payload: KeysignPayload): Promise<TransactionValidationResult | null>
  simulateTransaction(payload: KeysignPayload): Promise<TransactionSimulationResult | null>

  // Chains & Tokens
  setChains(chains: Chain[]): Promise<void>
  addChain(chain: Chain): Promise<void>
  removeChain(chain: Chain): Promise<void>
  resetToDefaultChains(): Promise<void>
  getTokens(chain: Chain): Token[]
  setTokens(chain: Chain, tokens: Token[]): Promise<void>
  addToken(chain: Chain, token: Token): Promise<void>
  removeToken(chain: Chain, tokenId: string): Promise<void>

  // Portfolio
  getValue(chain: Chain, tokenId?: string, fiatCurrency?: FiatCurrency): Promise<Value>
  getValues(chain: Chain, fiatCurrency?: FiatCurrency): Promise<Record<string, Value>>
  getTotalValue(fiatCurrency?: FiatCurrency): Promise<Value>
  updateValues(chain: Chain | 'all'): Promise<void>
  updateTotalValue(fiatCurrency?: FiatCurrency): Promise<Value>
  setCurrency(currency: string): Promise<void>

  // Events
  on(event: string, handler: Function): void
  off(event: string, handler: Function): void
}
```

### Vault Creation Methods

Fast vaults and secure vaults are created through the Vultisig class:

```typescript
// Create fast vault (2-of-2 with server)
// Returns vaultId - call verifyVault to get the vault
const vaultId = await sdk.createFastVault({
  name: string
  email: string
  password: string
  onProgress?: (step: VaultCreationStep) => void
})

// Verify with email code to get the vault (saves and returns it)
const vault = await sdk.verifyVault(vaultId, code)

// Create secure vault (multi-device MPC with N-of-M threshold)
const { vault, vaultId, sessionId } = await sdk.createSecureVault({
  name: string
  password?: string               // Optional encryption
  devices: number                 // Total participating devices
  threshold?: number              // Signing threshold (defaults to ceil(devices*2/3))
  signal?: AbortSignal            // Optional cancellation
  onProgress?: (step: VaultCreationStep) => void
  onQRCodeReady?: (qrPayload: string) => void
  onDeviceJoined?: (deviceId: string, total: number, required: number) => void
})
```

### Supported Chains

```typescript
enum Chain {
  // EVM Chains (13)
  Ethereum = 'Ethereum',
  Polygon = 'Polygon',
  BinanceSmartChain = 'BSC',
  Arbitrum = 'Arbitrum',
  Optimism = 'Optimism',
  Base = 'Base',
  Avalanche = 'Avalanche',
  Blast = 'Blast',
  CronosChain = 'CronosChain',
  ZkSync = 'ZkSync',
  Hyperliquid = 'Hyperliquid',
  Mantle = 'Mantle',
  Sei = 'Sei',

  // UTXO Chains (6)
  Bitcoin = 'Bitcoin',
  BitcoinCash = 'BitcoinCash',
  Litecoin = 'Litecoin',
  Dogecoin = 'Dogecoin',
  Dash = 'Dash',
  Zcash = 'Zcash',

  // Cosmos Chains (10)
  THORChain = 'THORChain',
  MayaChain = 'MayaChain',
  Cosmos = 'Cosmos',
  Osmosis = 'Osmosis',
  Dydx = 'Dydx',
  Kujira = 'Kujira',
  TerraClassic = 'TerraClassic',
  Terra = 'Terra',
  Noble = 'Noble',
  Akash = 'Akash',

  // Other Chains (7)
  Solana = 'Solana',
  Polkadot = 'Polkadot',
  Sui = 'Sui',
  Ton = 'Ton',
  Ripple = 'Ripple',
  Tron = 'Tron',
  Cardano = 'Cardano'
}
```

### Common Configuration Options

```typescript
// Vultisig constructor options (all optional)
new Vultisig({
  // Storage - uses platform default if not provided
  storage?: Storage,               // FileStorage (Node.js) or BrowserStorage (browser) by default

  // Vault defaults
  defaultChains?: Chain[],         // Default chains for new vaults
  defaultCurrency?: string,        // Default fiat currency ('USD', 'EUR', etc.)

  // Cache configuration
  cacheConfig?: {
    balanceTTL?: number,           // Balance cache TTL in ms (default: 300000 = 5min)
    priceTTL?: number,             // Price cache TTL in ms (default: 300000 = 5min)
    maxMemoryCacheSize?: number    // Max cache entries (default: 1000)
  },

  // Password management
  passwordCache?: {
    defaultTTL: number             // Password cache TTL in milliseconds
  },
  onPasswordRequired?: (vaultId: string, vaultName: string) => Promise<string>,

  // Server endpoints (advanced)
  serverEndpoints?: {
    fastVault?: string,            // Custom VultiServer URL
    messageRelay?: string          // Custom relay server URL
  }
})
```

### Cosmos Signing Types

```typescript
// SignAmino input for Cosmos SDK chains
interface SignAminoInput {
  chain: CosmosChain           // 'Cosmos', 'Osmosis', 'THORChain', etc.
  coin: AccountCoin
  msgs: CosmosMsgInput[]       // Array of messages to sign
  fee: CosmosFeeInput
  memo?: string
}

// SignDirect input for pre-encoded Protobuf transactions
interface SignDirectInput {
  chain: CosmosChain
  coin: AccountCoin
  bodyBytes: string            // Base64-encoded TxBody
  authInfoBytes: string        // Base64-encoded AuthInfo
  chainId: string              // e.g., 'cosmoshub-4'
  accountNumber: string
  memo?: string
}

// Cosmos message format
interface CosmosMsgInput {
  type: string                 // e.g., 'cosmos-sdk/MsgSend'
  value: string                // JSON-stringified message value
}

// Cosmos fee format
interface CosmosFeeInput {
  amount: CosmosCoinAmount[]
  gas: string
  payer?: string
  granter?: string
}

// Cosmos coin amount
interface CosmosCoinAmount {
  denom: string                // e.g., 'uatom'
  amount: string               // e.g., '1000000'
}

// Options for Cosmos signing
interface CosmosSigningOptions {
  skipChainSpecificFetch?: boolean  // Skip account/sequence fetch
}
```

### Seedphrase & Vault Creation Types

```typescript
type SeedphraseValidation = {
  valid: boolean
  wordCount: number
  invalidWords?: string[]
  error?: string
}

type ChainDiscoveryPhase = 'validating' | 'deriving' | 'fetching' | 'complete'

type ChainDiscoveryProgress = {
  phase: ChainDiscoveryPhase
  chain?: Chain
  chainsProcessed: number
  chainsTotal: number
  chainsWithBalance: Chain[]
  message: string
}

type ChainDiscoveryResult = {
  chain: Chain
  address: string
  balance: string
  decimals: number
  symbol: string
  hasBalance: boolean
}

// Aggregate result from discoverChainsFromSeedphrase()
type ChainDiscoveryAggregate = {
  results: ChainDiscoveryResult[]
  usePhantomSolanaPath: boolean  // True if Phantom's Solana derivation path should be used
}

type CreateFastVaultFromSeedphraseOptions = {
  mnemonic: string
  name: string
  email: string
  password: string
  chains?: Chain[]
  discoverChains?: boolean
  chainsToScan?: Chain[]
  /** Use Phantom wallet derivation path for Solana (auto-detected if discoverChains is true) */
  usePhantomSolanaPath?: boolean
  onProgress?: (step: VaultCreationStep) => void
  onChainDiscovery?: (progress: ChainDiscoveryProgress) => void
}

type CreateSecureVaultFromSeedphraseOptions = {
  mnemonic: string
  name: string
  password?: string
  devices: number
  threshold?: number
  chains?: Chain[]
  discoverChains?: boolean
  /** Use Phantom wallet derivation path for Solana (auto-detected if discoverChains is true) */
  usePhantomSolanaPath?: boolean
  onProgress?: (step: VaultCreationStep) => void
  onQRCodeReady?: (qrPayload: string) => void
  onDeviceJoined?: (deviceId: string, total: number, required: number) => void
  onChainDiscovery?: (progress: ChainDiscoveryProgress) => void
}

type JoinSecureVaultOptions = {
  /** Mnemonic (required for seedphrase vaults, ignored for keygen) */
  mnemonic?: string
  /** Vault encryption password */
  password?: string
  /** Number of devices */
  devices?: number
  /** Use Phantom wallet derivation path for Solana */
  usePhantomSolanaPath?: boolean
  /** Cancellation signal */
  signal?: AbortSignal
  /** Progress callback */
  onProgress?: (step: VaultCreationStep) => void
  /** Device join callback */
  onDeviceJoined?: (deviceId: string, total: number, required: number) => void
}
```

***

## Platform Notes

### Browser

**WASM Files**: Must be served from the root path:

```bash
# Copy to public directory
cp node_modules/@vultisig/sdk/dist/*.wasm public/

# Ensure your dev server serves these files from /
# Vite: automatically serves from public/
# Create React App: automatically serves from public/
# Next.js: place in public/ directory
```

**IndexedDB Storage**: For persistent storage, use IndexedDB (see [examples/browser](https://github.com/vultisig/vultisig-sdk/tree/main/examples/browser) for implementation).

**Import**:

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

const sdk = new Vultisig()  // Uses BrowserStorage (IndexedDB) by default
await sdk.initialize()
```

**Security Considerations**:

* Use `type="password"` for password inputs
* Consider using Web Crypto API for sensitive data
* Implement Content Security Policy (CSP)

### Node.js

**Import**:

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

const sdk = new Vultisig()  // Uses FileStorage (~/.vultisig) by default
await sdk.initialize()
// ... use the SDK ...
sdk.dispose()
```

**Custom Storage**: For custom persistence needs, implement the `Storage` interface (see [Custom Storage Implementation](#custom-storage-implementation) for a full example).

**Password Input**: Use libraries like `inquirer` or `prompts` for CLI password input.

### React Native

**Status**: Coming soon

### Electron

The SDK supports Electron desktop applications. The SDK runs in the **main process** and uses `FileStorage` (`~/.vultisig`), which means vaults are shared with the CLI tool.

**Architecture**:

```
┌─────────────────────────────────────────────┐
│              Electron App                    │
├─────────────────┬───────────────────────────┤
│  Main Process   │    Renderer Process       │
│  (SDK runs here)│    (UI only)              │
├─────────────────┼───────────────────────────┤
│ • Vultisig SDK  │ • React/Vue/etc UI        │
│ • FileStorage   │ • Calls main via IPC      │
│ • WASM modules  │ • No SDK import needed    │
└─────────────────┴───────────────────────────┘
         ↑                    ↑
         └──── IPC Bridge ────┘
```

**Main Process Setup**:

```typescript
// main.ts - SDK runs here
import { app, BrowserWindow, ipcMain } from 'electron'
import { Vultisig, Chain } from '@vultisig/sdk'

let sdk: Vultisig

app.whenReady().then(async () => {
  // Initialize SDK in main process
  sdk = new Vultisig()  // Uses FileStorage (~/.vultisig)
  await sdk.initialize()

  // Expose SDK operations via IPC
  ipcMain.handle('sdk:listVaults', () => sdk.listVaults())
  ipcMain.handle('sdk:getAddress', async (_, chain) => {
    const vault = await sdk.getActiveVault()
    return vault?.address(chain)
  })
  ipcMain.handle('sdk:getBalance', async (_, chain) => {
    const vault = await sdk.getActiveVault()
    return vault?.balance(chain)
  })

  // Create window...
})
```

**Preload Script**:

```typescript
// preload.ts - Bridge between main and renderer
import { contextBridge, ipcRenderer } from 'electron'

contextBridge.exposeInMainWorld('vultisig', {
  listVaults: () => ipcRenderer.invoke('sdk:listVaults'),
  getAddress: (chain: string) => ipcRenderer.invoke('sdk:getAddress', chain),
  getBalance: (chain: string) => ipcRenderer.invoke('sdk:getBalance', chain),
})
```

**Renderer (UI)**:

```typescript
// renderer.ts - Your React/Vue/etc app
// No SDK import needed - use the IPC bridge

const vaults = await window.vultisig.listVaults()
const address = await window.vultisig.getAddress('Bitcoin')
const balance = await window.vultisig.getBalance('Ethereum')
```

**Shared Vaults with CLI**:

Because both Electron and CLI use `FileStorage` with `~/.vultisig`:

```bash
# Create vault with CLI
vsig vault create --name "My Wallet"

# Open Electron app → same vault is available!
```

**WASM Files**:

Include WASM files in your Electron build:

```json
// electron-builder.json
{
  "files": [
    "dist/**/*",
    "node_modules/@vultisig/sdk/dist/**/*.wasm"
  ]
}
```

**Security Best Practices**:

* Always use `contextIsolation: true` (Electron default)
* Never use `nodeIntegration: true` in renderer
* Keep all vault operations in main process
* Only expose necessary operations via IPC

***

## Additional Resources

* **Examples**:
  * [Browser Example](https://github.com/vultisig/vultisig-sdk/tree/main/examples/browser) - Full React app with UI
  * [CLI](https://github.com/vultisig/vultisig-sdk/tree/main/clients/cli) - Command-line wallet with interactive shell mode
* **GitHub**: [vultisig-sdk](https://github.com/vultisig/vultisig-sdk)
* **Issues**: Report bugs and request features on GitHub

***

**Questions or feedback?** Open an issue on GitHub or check the example projects for more detailed implementations.


# SDK CLI

Command-line wallet for Vultisig - secure multi-party computation (MPC) wallet management across 40+ blockchains.

> **Tip:** Use `vsig` as a shorthand alias for `vultisig` - all commands work with both!

## Installation

### npm (recommended)

```bash
# Install globally
npm install -g @vultisig/cli

# Verify installation
vultisig --version
```

### npx (no installation)

```bash
# Run directly without installing
npx @vultisig/cli balance ethereum
```

### From source

```bash
# Clone the repository
git clone https://github.com/vultisig/vultisig-sdk.git
cd vultisig-sdk

# Install dependencies
yarn install

# Run CLI
yarn cli --help
```

## Shell Completion

Enable tab completion for commands, chains, and vault names (works for both `vultisig` and `vsig`):

```bash
# Install completion for your shell
vultisig completion --install

# Or manually add to your shell config
vultisig completion bash >> ~/.bashrc
vultisig completion zsh >> ~/.zshrc
vultisig completion fish >> ~/.config/fish/completions/vultisig.fish
```

## Quick Start

### Create a Fast Vault

```bash
vultisig create fast --name "My Wallet" --password "mypassword" --email user@example.com
```

You'll be prompted to:

1. Enter the verification code sent to your email

### Create a Secure Vault (Multi-Device)

```bash
vultisig create secure --name "Team Wallet" --shares 3
```

This creates a secure vault with configurable N-of-M threshold:

1. A QR code displays in your terminal
2. Other participants scan with Vultisig mobile app (iOS/Android)
3. Once all devices join, keygen runs automatically
4. Vault is created and ready to use

**Secure vault options:**

* `--shares <n>` - Number of participating devices (default: 3)
* `--threshold <n>` - Signing threshold (default: 2)

**Example session:**

```bash
$ vultisig create secure --name "Team Wallet" --shares 3

Creating secure vault: Team Wallet (2-of-3)

Scan this QR code with Vultisig mobile app:
████████████████████████████
█ ▄▄▄▄▄ █▀ ▄█▄█▀█ ▄▄▄▄▄ █
█ █   █ █▀▄▄▄ ▄██ █   █ █
...

Waiting for devices to join...
⠋ Device joined: iPhone-abc123 (2/3)
⠋ Device joined: Android-def456 (3/3)

All devices joined. Running keygen...
✓ ECDSA keygen complete
✓ EdDSA keygen complete

✓ Secure vault created: Team Wallet
  Vault ID: vault_abc123def456
```

### Import from Seedphrase

Import an existing wallet from a BIP39 recovery phrase (12 or 24 words):

```bash
# FastVault import (server-assisted 2-of-2)
vultisig create-from-seedphrase fast --name "Imported Wallet" --email user@example.com

# SecureVault import (multi-device MPC)
vultisig create-from-seedphrase secure --name "Team Wallet" --shares 3
```

**Import options:**

* `--mnemonic <words>` - Recovery phrase (space-separated words)
* `--discover-chains` - Scan chains for existing balances before import
* `--chains <chains>` - Specific chains to enable (comma-separated)
* `--use-phantom-solana-path` - Use Phantom wallet derivation path for Solana

When `--mnemonic` is not provided, you'll be prompted to enter it securely (masked input).

> **Note:** Phantom wallet uses a non-standard derivation path for Solana. If your seedphrase was originally created in Phantom and you're importing Solana funds, use `--use-phantom-solana-path`. When using `--discover-chains`, this is auto-detected.

**Example session:**

```bash
$ vultisig create-from-seedphrase fast --name "My Wallet" --email user@example.com --password "mypassword" --discover-chains

Enter your 12 or 24-word recovery phrase.
Words will be hidden as you type.

Seedphrase: ************************
✓ Valid 12-word seedphrase

Discovering chains with balances...
  Bitcoin:     bc1q...xyz     0.05 BTC
  Ethereum:    0x1234...      1.2 ETH
✓ Found 2 chains with balances

Importing seedphrase... (35%)
✓ Keys generated, awaiting email verification

Enter verification code: 123456
✓ Vault verified successfully!

Vault imported: My Wallet
  Bitcoin:  bc1q...xyz
  Ethereum: 0x1234...abc
```

### Check Balances

```bash
# All chains
vultisig balance

# Specific chain
vultisig balance ethereum

# Include token balances
vultisig balance ethereum --tokens
```

### Send Transaction

```bash
# Send native token
vultisig send ethereum 0xRecipient... 0.1

# Send ERC-20 token
vultisig send ethereum 0xRecipient... 100 --token 0xTokenAddress...

# Provide password via flag (for scripts/automation)
vultisig send ethereum 0xRecipient... 0.1 --password mypassword
```

**Secure vault transactions:**

When using a secure vault, a QR code displays for device coordination:

```bash
$ vultisig send ethereum 0x742d35Cc... 0.1

Preparing transaction...

Scan this QR code to approve transaction:
████████████████████████████
...

Waiting for devices to join signing session...
⠋ Device joined: iPhone-abc123 (2/2)

Signing transaction...
✓ Transaction signed
✓ Broadcast: 0x9f8e7d6c...
```

You can cancel with Ctrl+C while waiting for devices.

### Interactive Shell

Start an interactive session with tab completion and password caching:

```bash
vultisig --interactive
# or
vultisig -i
```

## AI Agent Integration

The CLI has first-class support for AI agents — both coding agents (Claude Code, Cursor, Opencode) that drive it through shell commands, and agent-to-agent orchestration through a natural-language interface.

### Non-interactive by default

When the CLI runs in a non-TTY environment (pipes, scripts, agents), it auto-detects this and skips interactive prompts that would hang an agent. Vault creation falls back to two-step mode automatically:

```bash
# Auto-detects non-TTY, skips the interactive OTP prompt, returns immediately
vultisig create fast --name "Agent Wallet" --password "$VAULT_PASSWORD" --email agent@example.com -o json

# Verify later, once you have the email code
vultisig verify <vaultId> --code 123456
```

Use `--ci` for full automation mode (equivalent to `--output json --non-interactive --quiet`). Provide the password through the `--password` flag or the `VAULT_PASSWORD` environment variable so no command blocks on input.

### Agent ask (one-shot)

Send a single natural-language message and get a structured response. This mode is designed for AI-to-AI communication and routes through the Vultisig agent backend.

```bash
# Query
vultisig agent ask "What is my ETH balance?" --password "$VAULT_PASSWORD"

# Execute a transaction
vultisig agent ask "Send 0.01 ETH to 0x742d..." --password "$VAULT_PASSWORD"

# Continue a conversation
vultisig agent ask "Now swap it to USDC" --session abc123 --password "$VAULT_PASSWORD"

# Structured JSON for parsing
vultisig agent ask "Check my portfolio" --password "$VAULT_PASSWORD" --json
```

JSON output:

```json
{
  "session_id": "abc123-def456",
  "response": "Your ETH balance is 1.5 ETH ($3,750.00 USD).",
  "tool_calls": [
    { "action": "get_balances", "success": true, "data": { "balances": [{ "chain": "Ethereum", "symbol": "ETH", "amount": "1.5" }] } }
  ],
  "transactions": [
    { "hash": "0x9f8e7d6c...", "chain": "ethereum", "explorerUrl": "https://etherscan.io/tx/0x9f8e7d6c..." }
  ]
}
```

On failure, stdout is a single JSON object with a human-readable `error` and a stable `code`:

```json
{ "error": "Agent backend unreachable", "code": "BACKEND_UNREACHABLE" }
```

**Options:**

* `--session <id>` — continue an existing conversation
* `--backend-url <url>` — agent backend URL (default: `https://abe.vultisig.com`)
* `--password <password>` — vault password for signing
* `--json` — output structured JSON
* `--verbose` — show tool calls and debug info on stderr

### Agent chat and pipe mode

For an interactive chat TUI, or NDJSON agent-to-agent piping:

```bash
# Interactive chat interface
vultisig agent

# NDJSON pipe mode for agent-to-agent control (one JSON object per line on stdin/stdout)
vultisig agent --via-agent --password "$VAULT_PASSWORD"
```

### Error codes

Orchestrators should branch on `code`, not on the `error` message (which may change between releases). Codes are stable across `agent ask --json`, `--via-agent`, and the executor:

| Code                      | Typical meaning                                           |
| ------------------------- | --------------------------------------------------------- |
| `BACKEND_UNREACHABLE`     | Agent health check failed or backend not responding       |
| `AUTH_FAILED`             | Auth/token failure, HTTP 401/403, or wrong vault password |
| `VAULT_LOCKED`            | Encrypted vault needs unlock                              |
| `PASSWORD_REQUIRED`       | Password not supplied when required                       |
| `CONFIRMATION_REQUIRED`   | User confirmation needed                                  |
| `ACTION_NOT_IMPLEMENTED`  | Local executor does not implement this action             |
| `INVALID_INPUT`           | Bad parameters, unknown chain, malformed input            |
| `NETWORK_ERROR`           | RPC/fetch connectivity failure                            |
| `TIMEOUT`                 | Deadline exceeded                                         |
| `TRANSACTION_FAILED`      | Build/broadcast/gas error                                 |
| `SIGNING_FAILED`          | MPC/signing failed                                        |
| `SESSION_NOT_INITIALIZED` | Internal session state error                              |
| `UNKNOWN_ERROR`           | Unclassified failure                                      |

## Commands

### Vault Management

| Command                         | Description                                      |
| ------------------------------- | ------------------------------------------------ |
| `create fast`                   | Create a new fast vault (server-assisted 2-of-2) |
| `create secure`                 | Create a secure vault (multi-device MPC)         |
| `import <file>`                 | Import vault from .vult file                     |
| `delete [vault]`                | Delete a vault from local storage                |
| `create-from-seedphrase fast`   | Import seedphrase as FastVault (2-of-2)          |
| `create-from-seedphrase secure` | Import seedphrase as SecureVault (N-of-M)        |
| `join secure`                   | Join an existing SecureVault creation session    |
| `export [path]`                 | Export vault to file                             |
| `verify <vaultId>`              | Verify vault with email code                     |
| `vaults`                        | List all stored vaults                           |
| `switch <vaultId>`              | Switch to a different vault                      |
| `rename <newName>`              | Rename the active vault                          |
| `info`                          | Show detailed vault information                  |

**Create fast options:**

* `--name <name>` - Vault name (required)
* `--password <password>` - Vault password (required)
* `--email <email>` - Email for verification (required)

**Create secure options:**

* `--name <name>` - Vault name (required)
* `--password <password>` - Vault password (optional)
* `--shares <n>` - Number of devices (default: 3)
* `--threshold <n>` - Signing threshold (default: 2)

**Delete options:**

* `[vault]` - Vault name or ID to delete (defaults to active vault)
* `-y, --yes` - Skip confirmation prompt

```bash
# Delete by vault name
vultisig delete "My Wallet"

# Delete by vault ID (or prefix)
vultisig delete abc123

# Delete active vault
vultisig delete

# Skip confirmation (for scripts)
vultisig delete "Test Vault" --yes
```

**Join secure options:**

* `--qr <payload>` - QR code payload from initiator (vultisig://...)
* `--qr-file <path>` - Read QR payload from file
* `--mnemonic <words>` - Seedphrase (required for seedphrase-based sessions)
* `--password <password>` - Vault password (optional)
* `--devices <n>` - Total devices in session (default: 2)

**Create-from-seedphrase fast options:**

* `--name <name>` - Vault name (required)
* `--email <email>` - Email for verification (required)
* `--password <password>` - Vault password (required)
* `--mnemonic <words>` - Recovery phrase (prompted securely if not provided)
* `--discover-chains` - Auto-enable chains with existing balances
* `--chains <chains>` - Specific chains to enable (comma-separated)
* `--use-phantom-solana-path` - Use Phantom wallet derivation path for Solana

**Create-from-seedphrase secure options:**

* `--name <name>` - Vault name (required)
* `--shares <n>` - Number of devices (default: 3)
* `--threshold <n>` - Signing threshold (default: ceil((shares+1)/2))
* `--password <password>` - Vault password (optional)
* `--mnemonic <words>` - Recovery phrase (prompted securely if not provided)
* `--discover-chains` - Auto-enable chains with existing balances
* `--chains <chains>` - Specific chains to enable (comma-separated)
* `--use-phantom-solana-path` - Use Phantom wallet derivation path for Solana

**Export options:**

* `[path]` - Output file or directory (defaults to SDK-generated filename in current directory)
* `--password <password>` - Password to unlock encrypted vaults
* `--exportPassword <password>` - Password to encrypt the export file (defaults to `--password` if provided)

```bash
# Export to current directory (prompts for export password)
vultisig export

# Export to specific directory
vultisig export /path/to/backups/

# Export with encryption (same password for unlock and export)
vultisig export --password mypassword

# Export with different passwords for unlock vs export
vultisig export --password unlockPass --exportPassword exportPass

# Export without encryption (leave password prompt empty)
vultisig export
# > Enter password for export encryption (leave empty for no encryption): [enter]
```

### Wallet Operations

| Command                      | Description                            |
| ---------------------------- | -------------------------------------- |
| `balance [chain]`            | Show balance for a chain or all chains |
| `send <chain> <to> <amount>` | Send tokens to an address              |
| `addresses`                  | Show all vault addresses               |
| `portfolio`                  | Show total portfolio value             |

### Chain & Token Management

| Command          | Description                              |
| ---------------- | ---------------------------------------- |
| `chains`         | List and manage chains (--add, --remove) |
| `tokens <chain>` | List and manage tokens for a chain       |

### Swap Operations

| Command                           | Description                    |
| --------------------------------- | ------------------------------ |
| `swap-chains`                     | List chains that support swaps |
| `swap-quote <from> <to> <amount>` | Get a swap quote               |
| `swap <from> <to> <amount>`       | Execute a swap                 |

```bash
# Get a swap quote
vultisig swap-quote ethereum bitcoin 0.1

# Execute a swap
vultisig swap ethereum bitcoin 0.1

# With password for automation
vultisig swap ethereum bitcoin 0.1 --password mypassword

# Skip confirmation prompt
vultisig swap ethereum bitcoin 0.1 -y --password mypassword
```

Swap quotes and previews show your VULT discount tier when affiliate fees are applied. See `vultisig discount` for tier details.

### Advanced Operations

| Command                      | Description                                   |
| ---------------------------- | --------------------------------------------- |
| `sign`                       | Sign pre-hashed bytes for custom transactions |
| `broadcast`                  | Broadcast a pre-signed raw transaction        |
| `tx-status <chain> <txHash>` | Check transaction confirmation status         |

#### Transaction Status

Check whether a transaction has confirmed on-chain. By default, polls every 5 seconds until the transaction reaches a final state (success or error):

```bash
# Poll until confirmed (default)
vultisig tx-status ethereum 0x9f8e7d6c...

# Check current status without polling
vultisig tx-status ethereum 0x9f8e7d6c... --no-wait

# JSON output
vultisig tx-status ethereum 0x9f8e7d6c... -o json
```

**Output:**

```
✓ Transaction status: success
Status: success
Fee: 0.00042 ETH
Explorer: https://etherscan.io/tx/0x9f8e7d6c...
```

**JSON output:**

```json
{
  "chain": "ethereum",
  "txHash": "0x9f8e7d6c...",
  "status": "success",
  "receipt": {
    "feeAmount": "420000000000000",
    "feeDecimals": 18,
    "feeTicker": "ETH"
  },
  "explorerUrl": "https://etherscan.io/tx/0x9f8e7d6c..."
}
```

#### Signing Arbitrary Bytes

Sign pre-hashed data for externally constructed transactions:

```bash
# Sign a pre-hashed message (base64 encoded)
vultisig sign --chain ethereum --bytes "aGVsbG8gd29ybGQ="

# With password
vultisig sign --chain bitcoin --bytes "..." --password mypassword

# JSON output
vultisig sign --chain ethereum --bytes "..." -o json
```

**Output:**

```
Signature: <base64-encoded signature>
Recovery: 0
Format: ecdsa
```

**JSON output:**

```json
{
  "signature": "<base64>",
  "recovery": 0,
  "format": "ecdsa"
}
```

#### Broadcasting Raw Transactions

Broadcast pre-signed transactions to the network:

```bash
# EVM transaction (hex)
vultisig broadcast --chain ethereum --raw-tx "0x02f8..."

# Bitcoin transaction (hex)
vultisig broadcast --chain bitcoin --raw-tx "0200000001..."

# Solana transaction (base64)
vultisig broadcast --chain solana --raw-tx "AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQABAwIAAA..."

# Sui transaction (JSON)
vultisig broadcast --chain sui --raw-tx '{"unsignedTx":"...","signature":"..."}'
```

**Output:**

```
TX Hash: 0x9f8e7d6c...
Explorer: https://etherscan.io/tx/0x9f8e7d6c...
```

**Supported broadcast formats by chain:**

| Chain                          | `--raw-tx` Format                              |
| ------------------------------ | ---------------------------------------------- |
| EVM (Ethereum, Polygon, etc.)  | Hex-encoded signed tx                          |
| UTXO (Bitcoin, Litecoin, etc.) | Hex-encoded raw tx                             |
| Solana                         | Base64-encoded tx bytes                        |
| Sui                            | JSON: `{"unsignedTx":"...","signature":"..."}` |
| Cosmos                         | JSON: `{"tx_bytes":"..."}` or base64           |
| TON                            | Base64 BOC                                     |
| Polkadot                       | Hex-encoded extrinsic                          |
| Ripple                         | Hex-encoded tx blob                            |
| Tron                           | JSON tx object                                 |

#### Example: Custom EVM Transaction

Build and sign a transaction with ethers.js, broadcast with CLI:

```bash
# 1. Build transaction externally (save as build-evm-tx.js)
cat > build-evm-tx.js << 'EOF'
const { keccak256, Transaction, parseEther } = require('ethers');
const tx = Transaction.from({
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0',
  value: parseEther('0.01'),
  gasLimit: 21000n,
  maxFeePerGas: 50000000000n,
  maxPriorityFeePerGas: 2000000000n,
  nonce: 0,
  chainId: 1,
  type: 2
});
const hash = keccak256(tx.unsignedSerialized);
console.log('HASH:', Buffer.from(hash.slice(2), 'hex').toString('base64'));
console.log('UNSIGNED:', tx.unsignedSerialized);
EOF
node build-evm-tx.js

# 2. Sign the hash with Vultisig
vultisig sign --chain ethereum --bytes "<base64-hash-from-step-1>" -o json > sig.json

# 3. Assemble signed transaction (use r,s,v from sig.json)
# The signature field contains r||s (64 bytes hex), recovery is v

# 4. Broadcast the assembled signed transaction
vultisig broadcast --chain ethereum --raw-tx "0x02f8..."
```

#### Example: Custom Bitcoin Transaction

Build a PSBT with bitcoinjs-lib, sign with CLI:

```bash
# 1. Build PSBT and get sighash (save as build-btc-tx.js)
cat > build-btc-tx.js << 'EOF'
const bitcoin = require('bitcoinjs-lib');
const psbt = new bitcoin.Psbt({ network: bitcoin.networks.bitcoin });
// Add your inputs and outputs
psbt.addInput({
  hash: '<previous-txid>',
  index: 0,
  witnessUtxo: { script: Buffer.from('...'), value: 100000 }
});
psbt.addOutput({ address: 'bc1q...', value: 90000 });
// Get sighash for signing
const sighash = psbt.getTxForSigning().hashForWitnessV0(0, scriptCode, 100000, 0x01);
console.log('SIGHASH:', sighash.toString('base64'));
EOF
node build-btc-tx.js

# 2. Sign with Vultisig
vultisig sign --chain bitcoin --bytes "<base64-sighash>" -o json > sig.json

# 3. Apply signature to PSBT and finalize (use signature from sig.json)

# 4. Broadcast
vultisig broadcast --chain bitcoin --raw-tx "0200000001..."
```

#### Example: Custom Solana Transaction

Build with @solana/web3.js, sign with CLI:

```bash
# 1. Build transaction (save as build-sol-tx.js)
cat > build-sol-tx.js << 'EOF'
const { Transaction, SystemProgram, PublicKey, Connection } = require('@solana/web3.js');
const connection = new Connection('https://api.mainnet-beta.solana.com');
const fromPubkey = new PublicKey('<your-pubkey>');
const toPubkey = new PublicKey('<recipient-pubkey>');

const tx = new Transaction().add(
  SystemProgram.transfer({ fromPubkey, toPubkey, lamports: 1000000 })
);
tx.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
tx.feePayer = fromPubkey;

const message = tx.serializeMessage();
console.log('MESSAGE:', message.toString('base64'));
EOF
node build-sol-tx.js

# 2. Sign the message with Vultisig (EdDSA)
vultisig sign --chain solana --bytes "<base64-message>" -o json > sig.json

# 3. Assemble signed transaction (attach signature to message)

# 4. Broadcast (base64 encoded signed transaction)
vultisig broadcast --chain solana --raw-tx "<base64-signed-tx>"
```

#### Example: Custom Sui Transaction

Build with @mysten/sui, sign with CLI:

```bash
# 1. Build transaction (save as build-sui-tx.js)
cat > build-sui-tx.js << 'EOF'
const { SuiClient, getFullnodeUrl } = require('@mysten/sui/client');
const { Transaction } = require('@mysten/sui/transactions');

const client = new SuiClient({ url: getFullnodeUrl('mainnet') });
const tx = new Transaction();
tx.transferObjects([tx.gas], '<recipient-address>');
const bytes = await tx.build({ client });
console.log('TX_BYTES:', Buffer.from(bytes).toString('base64'));
EOF
node build-sui-tx.js

# 2. Sign the transaction bytes with Vultisig (EdDSA)
vultisig sign --chain sui --bytes "<base64-tx-bytes>" -o json > sig.json

# 3. Broadcast (requires JSON with both unsigned tx and signature)
vultisig broadcast --chain sui --raw-tx '{"unsignedTx":"<base64-tx-bytes>","signature":"<base64-signature-from-sig.json>"}'
```

### Settings

| Command           | Description                                |
| ----------------- | ------------------------------------------ |
| `currency [code]` | View or set currency preference            |
| `server`          | Check server connectivity                  |
| `discount`        | Show your VULT discount tier for swap fees |
| `address-book`    | Manage saved addresses                     |

#### Discount Tiers

View your VULT token holdings discount tier for reduced swap fees:

```bash
# Show current discount tier
vultisig discount

# Force refresh from blockchain
vultisig discount --refresh
```

**Output:**

```
+----------------------------------------+
|          VULT Discount Tier            |
+----------------------------------------+

  Current Tier:   Gold
  Swap Fee:       30 bps (0.30%)
  Discount:       20 bps saved

  Next Tier:
    Platinum - requires 15,000 VULT

  Tip: Thorguard NFT holders get +1 tier upgrade (up to gold)
```

**Tier levels:**

| Tier     | VULT Required | Swap Fee | Discount |
| -------- | ------------- | -------- | -------- |
| None     | 0             | 50 bps   | -        |
| Bronze   | 1,500         | 45 bps   | 5 bps    |
| Silver   | 3,000         | 40 bps   | 10 bps   |
| Gold     | 7,500         | 30 bps   | 20 bps   |
| Platinum | 15,000        | 25 bps   | 25 bps   |
| Diamond  | 100,000       | 15 bps   | 35 bps   |
| Ultimate | 1,000,000     | 0 bps    | 50 bps   |

Thorguard NFT holders receive a free tier upgrade (up to gold tier).

### CLI Management

| Command      | Description                |
| ------------ | -------------------------- |
| `version`    | Show detailed version info |
| `update`     | Check for updates          |
| `completion` | Generate shell completion  |

### Interactive Shell Commands

| Command         | Description                        |
| --------------- | ---------------------------------- |
| `vault <name>`  | Switch to a different vault        |
| `vaults`        | List all vaults                    |
| `create`        | Create a new vault                 |
| `import <file>` | Import vault from file             |
| `delete [name]` | Delete a vault                     |
| `lock`          | Lock vault (clear cached password) |
| `unlock`        | Unlock vault (cache password)      |
| `status`        | Show vault status                  |
| `help`          | Show available commands            |
| `.clear`        | Clear the screen                   |
| `.exit`         | Exit the shell                     |

## Global Options

```
-v, --version            Show version
-i, --interactive        Start interactive shell mode
-o, --output <format>    Output format: table, json (default: table)
--vault <nameOrId>       Specify vault by name or ID
--silent                 Suppress informational output, show only results
--debug                  Enable debug output
-h, --help               Show help
```

### Silent Mode

Use `--silent` to suppress spinners, progress messages, and informational output. Only results and errors are shown:

```bash
# Normal output shows spinners and status messages
vultisig balance ethereum
# ✓ Loading vault...
# ✓ Fetching balance...
# ETH: 1.5

# Silent mode shows only the result
vultisig balance ethereum --silent
# ETH: 1.5
```

Silent mode is useful for scripts where you only want the final output.

### JSON Output

Use `-o json` or `--output json` to get structured JSON output. JSON mode automatically enables silent mode:

```bash
# Get balance as JSON
vultisig balance ethereum -o json
```

```json
{
  "chain": "ethereum",
  "balance": {
    "native": "1.5",
    "symbol": "ETH",
    "usdValue": "3750.00"
  }
}
```

```bash
# Get all balances as JSON
vultisig balance -o json
```

```json
{
  "balances": [
    { "chain": "ethereum", "native": "1.5", "symbol": "ETH", "usdValue": "3750.00" },
    { "chain": "bitcoin", "native": "0.1", "symbol": "BTC", "usdValue": "6500.00" }
  ]
}
```

```bash
# Get portfolio as JSON
vultisig portfolio -o json
```

```json
{
  "portfolio": {
    "totalUsdValue": "10250.00",
    "chains": [...]
  },
  "currency": "USD"
}
```

```bash
# List vaults as JSON
vultisig vaults -o json
```

```json
{
  "vaults": [
    { "id": "abc123", "name": "Main Wallet", "isActive": true }
  ],
  "activeVaultId": "abc123"
}
```

```bash
# Get swap quote as JSON
vultisig swap-quote ethereum thorchain 0.1 -o json
```

```json
{
  "quote": {
    "fromChain": "ethereum",
    "toChain": "thorchain",
    "fromAmount": "0.1",
    "expectedOutput": "125.5",
    "route": "..."
  }
}
```

JSON output is ideal for:

* Scripting and automation
* Parsing output programmatically
* Integration with other tools (e.g., `jq`):

```bash
# Extract just the ETH balance using jq
vultisig balance ethereum -o json | jq -r '.balance.native'

# Get total portfolio value
vultisig portfolio -o json | jq -r '.portfolio.totalUsdValue'
```

## Configuration

### Environment Variables

```bash
# Pre-select vault by name or ID
VULTISIG_VAULT=MyWallet

# Override config directory
VULTISIG_CONFIG_DIR=/custom/path

# Disable colored output
VULTISIG_NO_COLOR=1

# Enable silent mode (suppress spinners and info messages)
VULTISIG_SILENT=1

# Enable debug output
VULTISIG_DEBUG=1

# Disable update checking
VULTISIG_NO_UPDATE_CHECK=1

# Vault password (for automation - use with caution!)
VAULT_PASSWORD=mypassword

# Multiple vault passwords
VAULT_PASSWORDS="Vault1:pass1 Vault2:pass2"
```

### Config Directory

Configuration is stored in `~/.vultisig/`:

```
~/.vultisig/
├── config.json      # User preferences
├── vaults/          # Vault data
├── cache/           # Version checks, etc.
└── address-book.json
```

## Security Best Practices

* Never store passwords in plain text for production use
* Always verify transaction details before confirming
* Use testnets for development and testing
* Keep vault backup files in a secure location
* Never commit .vult files or .env with passwords to git

## Supported Chains

40+ blockchains including:

* **EVM**: Ethereum, Polygon, Arbitrum, Optimism, BSC, Base, Avalanche
* **UTXO**: Bitcoin, Litecoin, Dogecoin, Dash, Zcash
* **Cosmos**: Cosmos Hub, THORChain, Maya, Dydx, Kujira
* **Others**: Solana, Sui, Polkadot, Ripple

## Exit Codes

| Code | Meaning              |
| ---- | -------------------- |
| 0    | Success              |
| 1    | General error        |
| 2    | Invalid usage        |
| 3    | Configuration error  |
| 4    | Authentication error |
| 5    | Network error        |
| 6    | Vault error          |
| 7    | Transaction error    |

## Troubleshooting

### "No active vault" error

Create or import a vault first:

```bash
vultisig create fast --name "My Wallet" --password "mypassword" --email user@example.com
# or
vultisig import /path/to/vault.vult
```

### Network errors

1. Check your internet connection
2. Run `vultisig server` to check connectivity
3. Try again in a few moments

### Update issues

```bash
# Check for updates
vultisig update --check

# Update manually
npm update -g @vultisig/cli
```

## Documentation

* [SDK Documentation](https://github.com/vultisig/vultisig-sdk/blob/main/packages/sdk/README.md)
* [API Reference](https://docs.vultisig.com)

## Support

* [GitHub Issues](https://github.com/vultisig/vultisig-sdk/issues)
* [Discord](https://discord.gg/Cugw9T2NrP)
* [Documentation](https://docs.vultisig.com)

## License

MIT


# FAQ

Frequently asked questions about Vultisig. Common questions about vaults, backups, transactions, and troubleshooting.

## General

### What is Vultisig?

Vultisig is a multi-chain, multi-platform crypto vault that uses threshold signatures (TSS) to secure digital assets. Unlike traditional wallets with single private keys, Vultisig distributes security across multiple devices—no single point of failure.

### Which platforms support Vultisig?

Vultisig is available on:

* iOS (iPhone, iPad)
* Android
* macOS
* Windows
* Linux
* Browser Extension (Chrome, Brave, Edge)

### Which blockchains does Vultisig support?

Vultisig supports 30+ chains including Bitcoin, Ethereum, THORChain, Solana, Cosmos ecosystem chains, and many EVM-compatible networks. See [Supported Chains](/app-guide/wallet) for the complete list.

***

## Vaults

### What is the difference between Fast Vault and Secure Vault?

**Fast Vault**: Uses your device plus Vultisig's server as the second signer. Quick setup, instant transactions, single-device convenience. Best for everyday use.

**Secure Vault**: Requires multiple physical devices you control. Higher security with no server dependency. Best for significant holdings.

### Can I convert a Fast Vault to a Secure Vault?

Not directly. You would need to create a new Secure Vault and transfer your assets. Both vault types use the same underlying TSS technology.

### What happens if I lose a device?

For **Fast Vault**: Restore from your device backup using the Vultiserver as the second share.

For **Secure Vault**: With a 2-of-3 configuration, you can still sign transactions with the remaining two devices and reshare to add a replacement device.

***

## Backup & Recovery

### How do I backup my vault?

Export vault shares from each device in your vault configuration. Store backups securely—anyone with threshold shares can access your funds.

For Fast Vault, device backup is the priority since server backup can be re-requested with your password.

See [Backup & Recovery](/getting-started/backup-recovery) for detailed instructions.

### What if I lose my backup?

If you still have access to threshold devices, you can re-export backups. If you've lost access to threshold devices AND backups, funds cannot be recovered—this is the security tradeoff of true self-custody.

### Can Vultisig recover my funds?

No. Vultisig has no access to your vault shares. This is a feature, not a limitation—it ensures true self-custody.

***

## Transactions

### Why is my transaction taking so long?

Transaction times depend on:

* Blockchain network congestion
* Gas/fee settings
* Number of confirmations required

For TSS signing delays, ensure all participating devices have stable network connections.

### What fees does Vultisig charge?

Vultisig charges no fees for basic operations. You only pay standard blockchain network fees for transactions.

Swap operations through integrated DEXs (THORChain, Maya) include their standard protocol fees.

### Can I cancel a pending transaction?

Once broadcast to the blockchain, transactions cannot be cancelled. Some networks support "replace-by-fee" to override pending transactions with higher fees.

***

## Security

### Is Vultisig open source?

Yes. All Vultisig code is open source and available on [GitHub](https://github.com/vultisig).

### Has Vultisig been audited?

Yes. See [Security](/help-and-legal/security) for audit reports and security practices.

### What if Vultisig company disappears?

Your funds remain accessible. Vultisig provides [emergency recovery tools](/security-and-technology/emergency-recovery) to reconstruct private keys from vault shares if the software becomes unavailable.

***

## Troubleshooting

### Devices not connecting for signing

1. Ensure all devices are on the same network (or using relay server)
2. Check that vault names match exactly
3. Verify devices have the latest app version
4. Try restarting the signing process

### QR code not scanning

1. Ensure adequate lighting
2. Clean camera lens
3. Hold device steady at appropriate distance
4. Try adjusting screen brightness on displaying device

### App crashes or freezes

1. Force close and restart the app
2. Check for app updates
3. Restart device if issue persists
4. Report persistent issues on [GitHub](https://github.com/vultisig/vultisig-ios/issues) or [Discord](https://discord.gg/Cugw9T2NrP)

***

## Related

* [Getting Started](/getting-started/overview)
* [Backup & Recovery](/getting-started/backup-recovery)
* [Security](/help-and-legal/security)


# Vultisig Bot

Vultisig Telegram bot for airdrop registration. Track vault balances, join the VULT token airdrop, and monitor your position.

The Vultisig Telegram bot enables users to register vaults for the VULT token airdrop and track their positions.

**Bot**: [@VultisigBot](https://t.me/VultisigBot)

***

## Features

### Airdrop Registration

Register your Vultisig vault addresses to participate in the VULT token airdrop. The bot tracks:

* Vault balance over time
* Position in airdrop rankings
* Estimated airdrop allocation

### Balance Tracking

Monitor your registered vault balances without opening the app. The bot provides periodic updates on:

* Total vault value (USD)
* Individual chain balances
* Balance changes over time

***

## Getting Started

1. Open Telegram and search for [@VultisigBot](https://t.me/VultisigBot)
2. Start the bot with `/start`
3. Follow prompts to register your vault addresses
4. Verify ownership by signing a message in Vultisig

***

## Commands

| Command     | Description                       |
| ----------- | --------------------------------- |
| `/start`    | Initialize bot and see options    |
| `/register` | Register a new vault address      |
| `/status`   | Check your current airdrop status |
| `/balance`  | View registered vault balances    |
| `/help`     | Display available commands        |

***

## Privacy

The bot only tracks publicly visible on-chain data. No private keys, vault shares, or sensitive information is collected or stored.

***

## Related

* [FAQ](/help-and-legal/faq) — Common questions
* [Security](/help-and-legal/security) — Security practices


# Security

Vultisig security practices, audits, and bug bounty program. Independent security assessments and responsible disclosure.

Vultisig prioritizes security through open-source transparency, professional audits, and responsible disclosure practices.

***

## Security Model

Vultisig's security is built on threshold signature schemes (TSS), eliminating single points of failure:

* **No single private key**: Keys are never constructed; vault shares create signatures collaboratively
* **Distributed trust**: Compromising one device does not compromise funds
* **Open source**: All code publicly auditable on [GitHub](https://github.com/vultisig)

For technical details, see [Security & Technology](/security-and-technology/overview).

***

## Audits

### DKLS23 Implementation

The upgraded DKLS23 protocol (via Silence Laboratories):

| Auditor       | Date | Scope           | Report                                                                                          |
| ------------- | ---- | --------------- | ----------------------------------------------------------------------------------------------- |
| Trail of Bits | 2024 | DKLS23 protocol | [View Report](https://github.com/silence-laboratories/dkls23?tab=readme-ov-file#security-audit) |

### Application Audits

Mobile and desktop application security assessments are conducted regularly. Reports are published upon completion.

***

## Security Best Practices

### For Users

1. **Backup vault shares** to secure, offline storage
2. **Verify addresses** before signing transactions
3. **Keep apps updated** for latest security patches
4. **Use Secure Vault** for significant holdings
5. **Never share vault shares** or backup files

### What Vultisig Cannot Do

* Access your funds
* Recover lost vault shares
* Reverse blockchain transactions
* View your private keys (they never exist)

***

## Related

* [Security & Technology](/security-and-technology/overview) — Technical documentation
* [Emergency Recovery](/security-and-technology/emergency-recovery) — Fund recovery if software unavailable
* [Privacy Policy](/help-and-legal/privacy) — Data handling practices


# Privacy

Vultisig privacy policy. How user data is collected, used, and protected. Commitment to user privacy and data minimization.

**Last Updated**: January 2025

This privacy policy describes how Vultisig ("we", "us", "our") collects, uses, and protects information when you use our applications and services.

***

## Our Commitment

Vultisig is designed with privacy as a core principle:

* **No account required**: Use Vultisig without registration
* **No KYC**: No identity verification required
* **Local-first**: Vault data stored on your devices
* **Open source**: Verify our privacy claims in the code

***

## Information We Collect

### Information We Do NOT Collect

* Private keys or vault shares
* Wallet addresses (unless voluntarily registered for airdrop)
* Transaction history
* Personal identification information
* Location data

### Information We May Collect

**Analytics Data** (optional, can be disabled):

* App version and platform
* Feature usage patterns (anonymized)
* Crash reports and error logs

**Relay Server Data** (when used for device communication):

* Temporary session data for transaction signing
* Automatically deleted after signing completion

**Airdrop Registration** (voluntary):

* Wallet addresses you choose to register
* Publicly visible on-chain balance data

***

## How We Use Information

Collected information is used to:

* Improve app performance and stability
* Fix bugs and errors
* Develop new features
* Facilitate device-to-device communication during signing

We do NOT:

* Sell user data
* Share data with third parties for marketing
* Track individual user behavior
* Create user profiles

***

## Data Storage

### On Your Device

* Vault shares
* Transaction history
* App settings
* Backup files

### On Our Servers

* Anonymized analytics (if enabled)
* Temporary relay session data
* Airdrop registration data (if registered)

***

## Third-Party Services

Vultisig integrates with third-party blockchain services:

* **Block explorers**: For balance and transaction data
* **Price feeds**: For USD valuations
* **DEX protocols**: For swap functionality (THORChain, Maya)

These services have their own privacy policies. Vultisig does not control data you share directly with blockchains.

***

## Your Rights

You can:

* **Disable analytics**: In app settings
* **Delete local data**: Uninstall the app
* **Request data deletion**: Contact <privacy@vultisig.com>
* **Export your data**: Via vault backup feature

***

## Data Security

We implement security measures including:

* Encryption in transit (TLS)
* Encryption at rest for server data
* Regular security audits
* Access controls and monitoring

***

## Children's Privacy

Vultisig is not intended for users under 18. We do not knowingly collect information from minors.

***

## Changes to This Policy

We may update this policy periodically. Significant changes will be communicated through the app or our official channels.

***

## Contact

For privacy-related inquiries:

* **Email**: <privacy@vultisig.com>
* **Discord**: [discord.gg/Cugw9T2NrP](https://discord.gg/Cugw9T2NrP)

***

## Related

* [Terms of Use](/help-and-legal/terms)
* [Security](/help-and-legal/security)


# Terms of Use

Vultisig terms of use. Legal agreement governing use of Vultisig applications and services.

**Last Updated**: January 2025

These Terms of Use ("Terms") govern your use of Vultisig applications and services. By using Vultisig, you agree to these Terms.

***

## 1. Acceptance of Terms

By downloading, installing, or using Vultisig software, you agree to be bound by these Terms. If you do not agree, do not use Vultisig.

***

## 2. Description of Service

Vultisig provides:

* Multi-chain cryptocurrency vault software
* Threshold signature scheme (TSS) technology
* Integration with decentralized exchanges
* Related tools and documentation

Vultisig is **non-custodial**. We do not hold, control, or have access to your digital assets.

***

## 3. User Responsibilities

You are responsible for:

* **Securing your vault shares**: Loss of threshold shares means permanent loss of funds
* **Backing up your vault**: We cannot recover lost vaults
* **Verifying transactions**: Review all details before signing
* **Compliance**: Following applicable laws in your jurisdiction
* **Device security**: Protecting devices used with Vultisig

***

## 4. Prohibited Uses

You may not use Vultisig to:

* Violate any applicable laws or regulations
* Engage in money laundering or terrorist financing
* Circumvent economic sanctions
* Infringe intellectual property rights
* Attempt to compromise the software or other users

***

## 5. No Financial Advice

Vultisig does not provide financial, investment, legal, or tax advice. Digital asset values are volatile. You are solely responsible for your financial decisions.

***

## 6. Third-Party Services

Vultisig integrates with third-party services including:

* Blockchain networks
* Decentralized exchanges (THORChain, Maya)
* Price data providers

These services are governed by their own terms. Vultisig is not responsible for third-party service availability, accuracy, or actions.

***

## 7. Intellectual Property

Vultisig software is released under the [STMF License](/help-and-legal/license). You may use, modify, and distribute the software in accordance with license terms.

Documentation and other materials may be subject to different licenses as indicated.

***

## 8. Disclaimer of Warranties

VULTISIG IS PROVIDED "AS IS" WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO:

* Merchantability
* Fitness for a particular purpose
* Non-infringement
* Security or error-free operation

We do not warrant that Vultisig will meet your requirements or operate uninterrupted.

***

## 9. Limitation of Liability

TO THE MAXIMUM EXTENT PERMITTED BY LAW, VULTISIG AND ITS CONTRIBUTORS SHALL NOT BE LIABLE FOR:

* Loss of funds or digital assets
* Indirect, incidental, or consequential damages
* Lost profits or data
* Service interruptions

This limitation applies regardless of the legal theory (contract, tort, or otherwise).

***

## 10. Indemnification

You agree to indemnify and hold harmless Vultisig, its contributors, and affiliates from any claims, damages, or expenses arising from:

* Your use of Vultisig
* Your violation of these Terms
* Your violation of any third-party rights

***

## 11. Modifications

We may modify these Terms at any time. Continued use after modifications constitutes acceptance of updated Terms. Material changes will be communicated through official channels.

***

## 12. Termination

You may stop using Vultisig at any time. We reserve the right to discontinue the service with reasonable notice.

Your vault shares and digital assets remain yours regardless of service status.

***

## 13. Governing Law

These Terms are governed by the laws of \[Jurisdiction]. Any disputes shall be resolved in the courts of \[Jurisdiction].

***

## 14. Severability

If any provision of these Terms is found unenforceable, the remaining provisions continue in effect.

***

## 15. Contact

For questions about these Terms:

* **Email**: <legal@vultisig.com>
* **Discord**: [discord.gg/Cugw9T2NrP](https://discord.gg/Cugw9T2NrP)

***

## Related

* [Privacy Policy](/help-and-legal/privacy)
* [License](/help-and-legal/license)
* [Security](/help-and-legal/security)


# License

STMF License for Vultisig software. Open source license terms governing use, modification, and distribution.

Vultisig software is released under the **Software Terms and Modification Freedom (STMF) License**.

***

## STMF License Summary

The STMF License grants you the freedom to:

* **Use** the software for any purpose
* **Study** how the software works
* **Modify** the software to suit your needs
* **Distribute** copies of the original or modified software

### Conditions

* Include the original license and copyright notice
* State changes made to the software
* Derivative works must use the same license

### No Warranty

The software is provided "as is" without warranty of any kind.

***

## Full License Text

The complete STMF License text is available at:

* **Repository**: [github.com/vultisig](https://github.com/vultisig)
* **License file**: `LICENSE` in each repository

***

## Component Licenses

Vultisig incorporates open-source components with their own licenses:

| Component             | License    | Repository                                                                               |
| --------------------- | ---------- | ---------------------------------------------------------------------------------------- |
| mobile-tss-lib        | STMF       | [github.com/vultisig/mobile-tss-lib](https://github.com/vultisig/mobile-tss-lib)         |
| tss-lib (Binance)     | Apache 2.0 | [github.com/bnb-chain/tss-lib](https://github.com/bnb-chain/tss-lib)                     |
| dkls23 (Silence Labs) | MIT        | [github.com/silence-laboratories/dkls23](https://github.com/silence-laboratories/dkls23) |

***

## Contributing

By contributing to Vultisig repositories, you agree that your contributions will be licensed under the STMF License.

See contribution guidelines in each repository for details.

***

## Questions

For licensing questions:

* **Email**: <legal@vultisig.com>
* **GitHub**: Open an issue in the relevant repository

***

## Related

* [Terms of Use](/help-and-legal/terms)
* [Security](/help-and-legal/security)


# MiCAR White Paper

MiCAR regulatory compliance white paper. EU Markets in Crypto-Assets Regulation compliance documentation for Vultisig.

This document addresses Vultisig's compliance considerations under the European Union's Markets in Crypto-Assets Regulation (MiCAR).

***

## Overview

The Markets in Crypto-Assets Regulation (MiCAR) establishes a comprehensive regulatory framework for crypto-assets in the European Union. This white paper outlines how Vultisig's architecture and operations relate to MiCAR requirements.

***

## Vultisig Classification

### Non-Custodial Software

Vultisig is **non-custodial wallet software**—it provides tools for users to manage their own digital assets without Vultisig taking custody or control.

Key characteristics:

* **No custody**: Vultisig never holds user funds
* **No private key access**: Keys are never constructed; vault shares remain with users
* **User sovereignty**: Users maintain complete control over their assets

### Software Provider vs. CASP

Under MiCAR, Crypto-Asset Service Providers (CASPs) require authorization. Vultisig's role as a non-custodial software provider differs from regulated custody services:

| Aspect            | CASP (Custodial)      | Vultisig (Non-Custodial)  |
| ----------------- | --------------------- | ------------------------- |
| Asset Control     | Provider holds assets | User holds assets         |
| Key Management    | Provider manages keys | User manages vault shares |
| Recovery          | Provider can recover  | Only user can recover     |
| Regulatory Status | Requires CASP license | Software tool             |

***

## Technical Architecture

### Threshold Signatures

Vultisig uses threshold signature schemes (TSS) where:

1. No single private key is ever created
2. Vault shares are distributed across user devices
3. Signatures require threshold collaboration
4. Vultisig has no access to signing capability

### Data Handling

Vultisig minimizes data collection:

* No user registration required
* No KYC/identity verification
* No transaction data storage
* Vault data stored locally on user devices

***

## User Protections

### Transparency

* **Open source**: All code publicly auditable
* **Documentation**: Comprehensive user guides
* **Risk disclosure**: Clear communication of self-custody responsibilities

### Security

* **Audited code**: Independent security assessments
* **No single point of failure**: TSS architecture
* **User education**: Best practices documentation

***

## Regulatory Engagement

Vultisig is committed to:

* Monitoring regulatory developments
* Engaging with regulators constructively
* Adapting to evolving requirements
* Maintaining transparency with users

***

## Whitepaper

[Vultisig MiCAR Whitepaper v1.1](https://drive.google.com/file/d/1Pmg8MmoH_yupXfVfMZKwoxRBdX0C7v5I/view?usp=drive_link)

***

## Disclaimers

This white paper is for informational purposes only and does not constitute legal advice. Regulatory interpretations may vary by jurisdiction and may change over time.

Users are responsible for:

* Understanding applicable regulations in their jurisdiction
* Complying with local laws regarding digital assets
* Seeking professional legal and tax advice as needed

***

## Contact

For regulatory inquiries:

* **Email**: <support@vultisig.com>

***

## Related

* [Terms of Use](/help-and-legal/terms)
* [Privacy Policy](/help-and-legal/privacy)
* [Security](/help-and-legal/security)


