Skip to content

Instantly share code, notes, and snippets.

@remyers
Last active September 1, 2023 11:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save remyers/1a7312c52e1706137ede5469843107d7 to your computer and use it in GitHub Desktop.
Save remyers/1a7312c52e1706137ede5469843107d7 to your computer and use it in GitHub Desktop.
Script to import recently used addresses from a legacy wallet into a new descriptor wallet
#!/bin/bash
shopt -s expand_aliases
alias btc-cli='bitcoin-cli -datadir=.bitcoin'
if [[ $# -lt 3 ]]; then echo "usage: $0 <rpcwallet-from> <rpcwallet-to> <maximum confirmations>" ; exit 1 ; fi
FROM=$1
TO=$2
CONFIRMATIONS=$3
# create new descriptor wallet
# disable_private_keys=false
# blank=false,
# passphrase="foo"
# avoid_reuse=false
# descriptor=true
btc-cli createwallet $2 false false "foo"
btc-cli -rpcwallet=$1 walletpassphrase "foo" 1000000
btc-cli -rpcwallet=$2 walletpassphrase "foo" 1000000
# get maximum confirmations cutoff of 2000 most recently used addresses:
# btc-cli -rpcwallet=perf-legacy listreceivedbyaddress | jq -r '.[] | .confirmations' | sort -g | head -n 2000
echo "finding addresses in wallet '$1' that received payments less than $CONFIRMATIONS blocks ago"
RECENT_ADDRS=$(btc-cli -rpcwallet=$1 listreceivedbyaddress | jq -r --arg C "$CONFIRMATIONS" '.[] | select(.confirmations <= ($C | tonumber))' | jq -r '.address')
echo "$(echo $RECENT_ADDRS | wc -w) addresses exported from '$1' will be imported into '$2'"
echo "checking if any addresses are already solvable by wallet '$2'"
if [ -f $2_already_solvable.log ]; then rm $2_already_solvable.log; fi
for ADDR in $RECENT_ADDRS
do
SOVLABLE=$(btc-cli -rpcwallet=$2 getaddressinfo $ADDR | jq -r '.solvable')
if [ $SOVLABLE != "false" ]; then echo $ADDR >> $2_already_solvable.log; fi
done
echo "generating requests"
REQUESTS=()
for ADDR in $RECENT_ADDRS
do
ADDR_INFO=$(btc-cli -rpcwallet=$1 getaddressinfo $ADDR)
DESC=$(echo $ADDR_INFO | jq '.desc')
TIMESTAMP=$(echo $ADDR_INFO | jq '.timestamp')
PUBKEY=$(echo $ADDR_INFO | jq '.pubkey')
KEY=$(btc-cli -rpcwallet=$1 dumpprivkey $ADDR)
INTERNAL=$(echo $ADDR_INFO | jq '.ischange')
LABEL=$(echo $ADDR_INFO | jq '.labels[0]')
DESC_INFO=$(btc-cli -rpcwallet=$1 getdescriptorinfo wpkh\($KEY\))
CHECKSUM=$(echo $DESC_INFO | jq -r '.checksum')
REQUESTS+=("{\"desc\":\"wpkh($KEY)#$CHECKSUM\",\"timestamp\":$TIMESTAMP,\"internal\":$INTERNAL,\"label\":$LABEL}")
done
echo "importing descriptors in to wallet '$2'"
echo $(IFS=,;echo "[${REQUESTS[*]}]") | btc-cli -rpcwallet=$2 -stdin importdescriptors > /dev/null
echo "checking addresses are solvable in wallet '$2' after rescan"
if [ -f $2_not_solvable.log ]; then rm $2_not_solvable.log; fi
for ADDR in $RECENT_ADDRS
do
SOVLABLE=$(btc-cli -rpcwallet=$2 getaddressinfo $ADDR | jq -r '.solvable')
if [ $SOVLABLE != "true" ]; then echo $ADDR >> $2_not_solvable.log; fi
done
if [ -f $2_already_solvable.log ]; then echo "$(cat $2_already_solvable.log | wc -l) already solvable by wallet '$2', see: $2_already_solvable.log"; fi
if [ -f $2_not_solvable.log ]; then echo "$(cat $2_not_solvable.log | wc -l) not solvable by wallet '$2', see: $2_not_solvable.log"; fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment