#!/bin/bash # # Export the mining wallet (custom_signet) in a re-importable format. # Contains: PRIVKEY, SIGNETCHALLENGE, wallet name, descriptors with private keys, # and chain info — everything needed to recover funds on this Signet chain. # # Output: backups/mining-wallet-export-YYYYMMDD-HHMMSS.json # Symlink: backups/mining-wallet-export-latest.json (ready to download) # # Re-import: ./import-mining-wallet.sh backups/mining-wallet-export-latest.json # # Author: 4NK Team # Date: 2026-02-02 set -e CONTAINER_NAME="bitcoin-signet-instance" WALLET_NAME="custom_signet" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" cd "$SCRIPT_DIR" BACKUP_DIR="${1:-$SCRIPT_DIR/backups}" mkdir -p "$BACKUP_DIR" TIMESTAMP=$(date +%Y%m%d-%H%M%S) OUTPUT_FILE="$BACKUP_DIR/mining-wallet-export-$TIMESTAMP.json" if ! docker ps --format "{{.Names}}" | grep -q "^${CONTAINER_NAME}$"; then echo "Error: Container ${CONTAINER_NAME} is not running" exit 1 fi DATADIR=$(docker exec "$CONTAINER_NAME" printenv BITCOIN_DIR 2>/dev/null || echo "/root/.bitcoin") echo "=== Export mining wallet (re-importable) ===" echo "Container: $CONTAINER_NAME" echo "Wallet: $WALLET_NAME" echo "Output: $OUTPUT_FILE" echo "" PRIVKEY=$(sudo docker exec "$CONTAINER_NAME" cat "$DATADIR/PRIVKEY.txt" 2>/dev/null || echo "") SIGNETCHALLENGE=$(sudo docker exec "$CONTAINER_NAME" cat "$DATADIR/SIGNETCHALLENGE.txt" 2>/dev/null || echo "") BLOCKCHAIN_INFO=$(sudo docker exec "$CONTAINER_NAME" bitcoin-cli -datadir="$DATADIR" getblockchaininfo 2>/dev/null || echo "{}") DESCRIPTORS_RAW=$(sudo docker exec "$CONTAINER_NAME" bitcoin-cli -datadir="$DATADIR" -rpcwallet="$WALLET_NAME" listdescriptors true 2>/dev/null || echo "{\"descriptors\":[]}") # Build importdescriptors-compatible array: each item {desc, timestamp, internal} DESCRIPTORS_IMPORT=$(echo "$DESCRIPTORS_RAW" | jq -c ' .descriptors | map(select(.desc != null)) | map({ desc: .desc, timestamp: (if .timestamp != null then .timestamp else 0 end), internal: (if .internal == true then true elif .internal == false then false else false end) }) ') # Single JSON document for re-import and recovery on this chain jq -n \ --arg chain "signet" \ --arg signet_challenge "${SIGNETCHALLENGE}" \ --arg privkey "${PRIVKEY}" \ --arg wallet_name "${WALLET_NAME}" \ --argjson descriptors "${DESCRIPTORS_IMPORT}" \ --argjson blockchain_info "${BLOCKCHAIN_INFO}" \ '{ export_version: "1.0", export_date: (now | strftime("%Y-%m-%dT%H:%M:%SZ")), chain: $chain, signet_challenge: $signet_challenge, privkey: $privkey, wallet_name: $wallet_name, descriptors: $descriptors, blockchain_at_export: $blockchain_info, reimport: "Run: ./import-mining-wallet.sh on a node with the same SIGNETCHALLENGE" }' > "$OUTPUT_FILE" ln -sf "$(basename "$OUTPUT_FILE")" "$BACKUP_DIR/mining-wallet-export-latest.json" echo "Export saved: $OUTPUT_FILE" echo "Latest symlink: $BACKUP_DIR/mining-wallet-export-latest.json" echo "Size: $(du -h "$OUTPUT_FILE" | cut -f1)" echo "" echo "To re-import and recover funds on this chain:" echo " ./import-mining-wallet.sh $OUTPUT_FILE" echo " # or: ./import-mining-wallet.sh $BACKUP_DIR/mining-wallet-export-latest.json" echo "" echo "WARNING: This file contains private keys. Keep it secure and encrypted." echo ""