A pass CLI extension for Bitcoin Core wallet backup and restore. Provides proper wallet descriptor backup/restore functionality using JSON descriptor export for secure storage in your password store. Security-hardened for production use with Bitcoin wallets containing funds.
Version: 0.2.2
- π Security-Hardened: Secure temporary file handling (including RAM-disk preference), proper cleanup, and restrictive permissions.
 - π Remote Server Compatible: Works with remote Bitcoin Core servers via RPC calls.
 - π Descriptor-Based: Uses Bitcoin Core's modern descriptor wallet format.
 - π Encrypted Storage: JSON descriptor files encrypted with GPG via 
pass. - π Full Integration: Complete Bitcoin Core descriptor wallet management.
 - π Import/Export: Handle descriptor JSON files with secure permissions.
 - β Safe Operations: Wallet validation, backup verification, and confirmation prompts.
 - π οΈ Complete Workflow: Create, backup, restore, import, export, destroy, and list operations.
 
pass-bitcoind (v0.2.0+) uses Bitcoin Core's modern descriptor-based approach which works with remote servers:
- RPC-based: Works with remote Bitcoin Core servers (no local file access needed).
 - Descriptor wallets: Uses Bitcoin Core's modern descriptor wallet format (default in recent versions).
 - Complete backup: Exports all wallet descriptors (including private keys) as JSON.
 - Native compatibility: Uses Bitcoin Core's built-in RPC commands (
listdescriptors,importdescriptors). - Production ready: Secure descriptor export/import via 
bitcoin-cli. 
- Ensure your pass extensions directory exists:
mkdir -p ~/.password-store/.extensions - Copy the extension to your pass extensions directory:
cp bitcoind.bash ~/.password-store/.extensions/bitcoind.bash # Assuming the script is named bitcoind.bash chmod +x ~/.password-store/.extensions/bitcoind.bash
 - Enable pass extensions (if not already enabled):
Add these lines to your shell profile (e.g., 
~/.zshrc,~/.bashrc, or~/.profile):Then source your profile or open a new terminal.export PASSWORD_STORE_ENABLE_EXTENSIONS=true # The PASSWORD_STORE_EXTENSIONS_DIR defaults to ~/.password-store/.extensions, # so explicitly setting it is often not necessary if using the default. # export PASSWORD_STORE_EXTENSIONS_DIR=~/.password-store/.extensions
 
Required:
pass- The standard Unix password manager (must be initialized).bitcoin-cli- Bitcoin Core command-line interface (configured for your server).jq- Command-line JSON processor.
Optional (for enhanced functionality):
bc- Basic calculator (for wallet balance warnings).shred- Securely overwrite files (for enhanced temporary file cleanup).
Install on macOS:
brew install pass bitcoin jq bc coreutils # coreutils for shredInstall on Ubuntu/Debian:
sudo apt update
sudo apt install pass bitcoin-utils jq bc secure-delete # bitcoin-utils provides bitcoin-cli, secure-delete provides shred(Note: Package names for bitcoin-cli and shred might vary slightly across distributions or Bitcoin Core installation methods.)
Setup Bitcoin Core:
Make sure Bitcoin Core (bitcoind) is running and accessible via bitcoin-cli:
# For local server (example)
bitcoind -daemon
# For remote server, ensure your ~/.bitcoin/bitcoin.conf (or equivalent)
# is configured correctly for RPC access, e.g.:
# rpcuser=your_rpc_user
# rpcpassword=your_rpc_password
# rpcconnect=remote_server_ip
# rpcallowip=your_client_ip (if needed)
# Verify bitcoin-cli connectivity
bitcoin-cli getblockchaininfopass bitcoind create mywalletThis creates a new Bitcoin Core descriptor wallet and immediately backs up all its descriptors to pass.
pass bitcoind backup existingwallet# Restore with the same name as in pass
pass bitcoind restore mywallet
# Restore with a new name in Bitcoin Core
pass bitcoind restore mywallet newwalletnamepass bitcoind import mywalletfromfile ~/path/to/wallet_backup.jsonThis imports a pre-existing JSON backup (conforming to the script's expected format) into pass.
pass bitcoind export mysecretwallet ~/backups/mysecretwallet_export.jsonThe exported file will have 600 permissions.
pass bitcoind listShows wallets stored in pass (under the configured prefix) and wallets currently loaded in Bitcoin Core.
pass bitcoind destroy oldwalletNote on destroy:
The destroy command:
- Removes the wallet backup from 
passstorage. - Unloads the wallet from Bitcoin Core using 
bitcoin-cli unloadwallet. It does not delete the actual wallet files from the Bitcoin Core server's filesystem (e.g., files in.bitcoin/wallets/directory or your custom wallet directory). To completely remove wallet files from the server, you must manually delete them from the Bitcoin Core data directory after running thedestroycommand and ensuring the wallet is no longer in use. 
pass bitcoind help- Create/Backup Command:
- For 
create:bitcoin-cli createwallet(creates a new descriptor wallet). bitcoin-cli -rpcwallet=<wallet-name> listdescriptors trueexports all wallet descriptors, including private keys.- A JSON object containing these descriptors and metadata (version, timestamp, wallet info) is constructed.
 
 - For 
 - Storage: The JSON data is piped to 
pass insert -m <prefix>/<wallet-name>, encrypting it with GPG and storing it. - Verification: The stored backup is immediately read back from 
passand validated. 
- Restore Command: 
pass show <prefix>/<wallet-name>retrieves the encrypted JSON data. - The JSON is parsed to extract the necessary descriptor information.
 bitcoin-cli createwallet <new-wallet-name> ... truecreates a new, empty, descriptor-enabled, blank wallet.bitcoin-cli -rpcwallet=<new-wallet-name> importdescriptors '[{...}]'imports all descriptors with private keys into the new wallet.- Result: A full descriptor wallet with all addresses and private keys is restored and active in Bitcoin Core. A rescan will occur in the background.
 
PASS_BITCOIND_PREFIX: Changes the subdirectory withinpasswhere wallet backups are stored. Default:bitcoindTMPDIR: Can be set to influence wheremktempcreates temporary files if/dev/shmis not available/writable. The script prioritizes/dev/shm.
# Store wallets in a custom folder within pass
PASS_BITCOIND_PREFIX=bitcoin_wallets pass bitcoind create mymainwallet
# Organize by purpose
PASS_BITCOIND_PREFIX=cold_storage pass bitcoind create offline_backup
PASS_BITCOIND_PREFIX=hot_wallets pass bitcoind create daily_spenderWallets are stored in pass as GPG-encrypted JSON files. The path structure within your password store will be:
<your-password-store-dir>/
βββ <PASS_BITCOIND_PREFIX>/
    βββ mywallet.gpg
    βββ testnet-wallet.gpg
    βββ cold-storage-backup.gpg
{
  "version": "0.2.2",
  "wallet_name": "mywallet",
  "timestamp": 1748448121,
  "wallet_info": {
    "walletname": "mywallet",
    "walletversion": 180000,
    "format": "sqlite",
    "descriptors": true,
    "avoid_reuse": false,
    "keypoolsize": 1000,
    "keypoolsize_hd_internal": 1000,
    "paytxfee": 0.0,
    "private_keys_enabled": true,
    "external_signer": false
  },
  "descriptors": {
    "wallet_name": "mywallet",
    "descriptors": [
      {
        "desc": "wpkh([abcdef12/84h/0h/0h]xpub.../0/*)#checksum",
        "timestamp": "now",
        "active": true,
        "internal": false,
        "range": [0, 999],
        "next": 0
      },
      {
        "desc": "wpkh([abcdef12/84h/0h/0h]xpub.../1/*)#checksum",
        "timestamp": "now",
        "active": true,
        "internal": true,
        "range": [0, 999],
        "next": 0
      }
      // ... other descriptors if any (e.g. for miniscript, taproot)
    ]
  }
}(Actual content, especially wallet_info and descriptors, will vary based on your Bitcoin Core version and wallet type.)
- Master GPG Key: The security of these backups relies entirely on the security of your 
passGPG key. Protect it well! - RPC Security: Ensure your Bitcoin Core RPC interface is properly secured (strong 
rpcauthorrpcpassword,rpcallowip, firewall rules, consider Tor or VPN for remote access). Private keys are transmitted over this connection. - Temporary Files: The script uses 
mktempto create temporary files, preferably in/dev/shm(RAM disk). These files arechmod 0600and are securely cleaned up usingshred(if available) thenrm. Atrapensures cleanup on script exit/interruption. - Verification: Backups are verified after being written to 
pass, and imported/exported files are checked for basic integrity. - Wallet Unloading: The 
destroycommand only unloads the wallet. For complete deletion from the server disk, manual intervention is required. set -euo pipefail: The script uses strict error checking.
- Remote Server Native: Designed for RPC, doesn't require direct filesystem access to the Bitcoin Core server, unlike 
backupwallet.dat. - Descriptor Focused: Aligns with modern Bitcoin Core descriptor wallets, ensuring all necessary information for address derivation and key management is backed up.
dumpwalletis for legacy non-HD wallets or individual keys and is not a complete backup for descriptor wallets. - Selective Restore: Descriptors can be imported into a new wallet without affecting other wallets on the server.
 - Human-Readable (ish) Backup: The JSON format (when decrypted) is more inspectable than a binary 
.datfile. - Platform Independent Backup: JSON descriptors are portable across systems.
 
MIT License
