Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/satsigner/satsigner/llms.txt

Use this file to discover all available pages before exploring further.

SatSigner provides flexible wallet management supporting single-signature, multi-signature, and watch-only accounts across multiple Bitcoin networks.

Account Types

SatSigner supports three policy types for Bitcoin accounts:

Single-Signature (Singlesig)

Standard Bitcoin wallets controlled by a single private key. Ideal for personal use and quick access to funds. Supported Script Types:
  • P2PKH - Legacy Pay-to-Public-Key-Hash
  • P2SH-P2WPKH - Nested SegWit (wrapped)
  • P2WPKH - Native SegWit (bech32)
  • P2TR - Taproot (bech32m)

Multi-Signature (Multisig)

Requires multiple signatures from different keys to authorize transactions. Enhanced security through distributed key custody. Supported Configurations:
  • M-of-N signature schemes (e.g., 2-of-3, 3-of-5)
  • Script types: P2WSH, P2SH-P2WSH, P2SH
  • Sortedmulti descriptors for wallet interoperability

Watch-Only

Monitor addresses and balances without signing capabilities. Perfect for:
  • Cold storage monitoring
  • Treasury oversight
  • Portfolio tracking
Import Methods:
  • Output descriptors (external/internal)
  • Extended public keys (xpub/ypub/zpub)
  • Individual addresses

Creating Accounts

Account Builder Flow

SatSigner uses a comprehensive account builder that guides users through wallet creation:
// Account builder state structure
type AccountBuilderState = {
  name: string
  network: 'bitcoin' | 'testnet' | 'signet' | 'regtest'
  policyType: 'singlesig' | 'multisig' | 'watchonly'
  
  // Key configuration
  keyName: string
  creationType: 'generateMnemonic' | 'importMnemonic' | 
                'importDescriptor' | 'importExtendedPub' | 'importAddress'
  mnemonicWordCount: 12 | 15 | 18 | 21 | 24
  scriptVersion: 'P2WPKH' | 'P2TR' | 'P2PKH' | ...
  
  // Multisig specific
  keys: Key[]
  keyCount: number
  keysRequired: number
}

Single-Signature Setup

Generate New Wallet:
  1. Select “Generate New” from account creation
  2. Choose mnemonic length (12 or 24 words recommended)
  3. Select script version (P2WPKH for most users)
  4. Securely backup seed phrase
  5. Verify seed phrase
  6. Set account name
Import Existing Wallet:
  1. Select “Import Mnemonic”
  2. Enter your BIP39 seed phrase
  3. Optional: Add BIP39 passphrase for advanced users
  4. Choose appropriate script version
  5. Set account name

Multi-Signature Setup

Creating a Multisig Wallet:
// Example: Creating a 2-of-3 multisig wallet
const multisigConfig = {
  name: "Treasury Vault",
  network: "bitcoin",
  policyType: "multisig",
  keyCount: 3,
  keysRequired: 2,
  scriptVersion: "P2WSH",
  keys: [
    {
      index: 0,
      name: "Key 1 - Hardware Wallet",
      creationType: "importExtendedPub",
      extendedPublicKey: "xpub...",
      fingerprint: "a1b2c3d4"
    },
    {
      index: 1,
      name: "Key 2 - Mobile Signer",
      creationType: "generateMnemonic",
      mnemonicWordCount: 24
    },
    {
      index: 2,
      name: "Key 3 - Backup Key",
      creationType: "importExtendedPub",
      extendedPublicKey: "xpub...",
      fingerprint: "e5f6g7h8"
    }
  ]
}
Key Requirements:
  • Each key must have a unique fingerprint
  • Keys are sorted by extended public key for consistency
  • Derivation paths follow BIP48 for multisig
  • Uses sortedmulti for cross-wallet compatibility

Watch-Only Setup

Import via Descriptor:
// Import output descriptor for watch-only
const descriptor = {
  externalDescriptor: "wpkh([fingerprint/84h/0h/0h]xpub.../0/*)",
  internalDescriptor: "wpkh([fingerprint/84h/0h/0h]xpub.../1/*)"
}
Import via Extended Public Key:
const watchOnlyConfig = {
  creationType: "importExtendedPub",
  extendedPublicKey: "zpub...", // Use zpub for P2WPKH
  fingerprint: "12345678",
  scriptVersion: "P2WPKH"
}

Account Storage

Encrypted Key Management

SatSigner encrypts sensitive key material using AES encryption with your PIN:
// Key encryption structure
type Key = {
  index: number
  name?: string
  creationType: CreationType
  secret: Secret | string // Encrypted with PIN
  iv: string // Initialization vector for AES
  fingerprint?: string
  scriptVersion?: ScriptVersionType
  derivationPath?: string
}

type Secret = {
  mnemonic?: string
  passphrase?: string
  externalDescriptor?: string
  internalDescriptor?: string
  extendedPublicKey?: string
  fingerprint?: string
}

Account Persistence

Accounts are persisted using Zustand with MMKV storage:
  • Location: Secure device storage
  • Encryption: PIN-protected AES-256
  • Format: JSON with encrypted secrets
  • Sync: Local only, no cloud backup

Network Support

SatSigner supports all major Bitcoin networks:
NetworkPurposeRecommended For
Bitcoin (Mainnet)Production use with real BTCAll users
TestnetTesting with testnet coinsDevelopers
SignetStable testing environmentApp testing
RegtestLocal developmentAdvanced developers

Account Operations

Syncing Accounts

// Sync process
1. Connect to backend (Electrum/Esplora)
2. Sync wallet with BDK
3. Fetch transactions and UTXOs
4. Update address discovery (BIP44 gap limit)
5. Calculate balances
6. Update account state
Sync Status Types:
  • unsynced - Never synced
  • syncing - Currently syncing
  • synced - Successfully synced
  • error - Sync failed
  • timeout - Sync timed out

Updating Accounts

// Update account name
updateAccountName(accountId, "New Name")

// Update key names
updateKeyName(accountId, keyIndex, "Hardware Wallet")

// Set last synced timestamp
setLastSyncedAt(accountId, new Date())

Deleting Accounts

// Delete single account
deleteAccount(accountId)

// Delete all accounts (use with caution)
deleteAccounts()
Important: Deleting an account removes all associated data. Ensure you have backed up your seed phrase before deletion.

Security Best Practices

Seed Phrase Management

  1. Never share your seed phrase - Anyone with your seed controls your funds
  2. Write it down on paper - Don’t store digitally or take photos
  3. Verify during setup - Confirm you wrote it correctly
  4. Store in multiple locations - Safe deposit box, fireproof safe
  5. Consider metal backup - For long-term storage

BIP39 Passphrases

Advanced users can add an optional passphrase (25th word): Benefits:
  • Additional security layer
  • Plausible deniability
  • Creates completely different wallets
Risks:
  • Lost passphrase = lost funds
  • No recovery mechanism
  • Must remember exact passphrase

Dropping Seeds

For enhanced security, drop the seed after initial setup:
// Remove mnemonic while keeping xpub
await dropSeedFromKey(accountId, keyIndex)

// Key is transformed from:
{
  mnemonic: "word1 word2...",
  extendedPublicKey: "xpub...",
  fingerprint: "..."
}

// To:
{
  extendedPublicKey: "xpub...",
  fingerprint: "..."
}
This creates a watch-only mode while retaining transaction history and addresses.

Multi-Device Coordination

For multisig wallets across devices:

Coordinator Flow

  1. Primary device creates multisig configuration
  2. Export wallet configuration via QR code
  3. Secondary devices import configuration
  4. Each device manages their assigned key
  5. Transactions coordinated via PSBT sharing

Configuration Sharing

// Export multisig configuration
const config = {
  name: account.name,
  policyType: "multisig",
  network: account.network,
  scriptVersion: "P2WSH",
  keysRequired: 2,
  keyCount: 3,
  externalDescriptor: "wsh(sortedmulti(2,[fp1/48h/0h/0h/2h]xpub.../0/*,[fp2/48h/0h/0h/2h]xpub.../0/*,[fp3/48h/0h/0h/2h]xpub.../0/*))"
}

// Share via QR code, file, or secure channel

Advanced Features

Fingerprint Management

Fingerprints uniquely identify keys in multisig setups:
// Extract fingerprint from extended public key
const fingerprint = getFingerprintFromExtendedPublicKey(xpub)

// Fingerprint format: 8 hex characters
// Example: "a1b2c3d4"

Derivation Paths

SatSigner follows BIP44/49/84/86 standards:
Script TypeBIPPath
P2PKHBIP44m/44’/0’/0’
P2SH-P2WPKHBIP49m/49’/0’/0’
P2WPKHBIP84m/84’/0’/0’
P2TRBIP86m/86’/0’/0’
MultisigBIP48m/48’/0’/0’/2’

Gap Limit

Address discovery uses BIP44 gap limit:
  • Default gap limit: 20 addresses
  • Continues scanning until 20 consecutive unused addresses
  • Balances scanning efficiency with thorough discovery

Troubleshooting

Sync Issues

Problem: Account won’t sync Solutions:
  • Check network connectivity
  • Verify backend server is accessible
  • Try alternative backend (Electrum vs Esplora)
  • Check network selection matches account

Missing Transactions

Problem: Transactions not appearing Solutions:
  • Increase gap limit in settings
  • Force resync from settings
  • Verify correct derivation path
  • Check if using BIP39 passphrase

Multisig Setup Errors

Problem: Cannot create multisig wallet Solutions:
  • Ensure all fingerprints are unique
  • Verify extended public keys are valid
  • Check same network for all keys
  • Confirm script version compatibility

Integration with BDK

SatSigner uses Bitcoin Dev Kit (BDK) for wallet operations:
// Create BDK wallet from descriptor
const wallet = await new Wallet().create(
  externalDescriptor,
  internalDescriptor,
  network,
  databaseConfig
)

// Sync wallet
await wallet.sync(blockchain)

// Get balance
const balance = await wallet.getBalance()

// List transactions
const transactions = await wallet.listTransactions(true)

// List UTXOs
const utxos = await wallet.listUnspent()
This provides robust, Bitcoin Core-compatible wallet functionality.