...
authoralex <[email protected]>
Thu, 23 Jun 2022 21:12:13 +0000 (14:12 -0700)
committeralex <[email protected]>
Thu, 23 Jun 2022 21:12:13 +0000 (14:12 -0700)
cold-setup

index ec45d85c788fbb93ec11604cd32b103fd6f843ca..25a3a1076fee3e827d099e011ae552f02f3c4b69 100755 (executable)
@@ -5,6 +5,7 @@ set -euo pipefail
 DATA_DIRECTORY=".data"
 M=3
 N=7
+MODE=
 
 BITCOIN_CLI="bitcoin-cli -datadir=$DATA_DIRECTORY -chain=regtest"
 
@@ -47,15 +48,15 @@ detect() {
 }
 
 log_error() {
-       echo "$@" >&2
+       echo -e "$@" >&2
 }
 
 log_info() {
-       echo "$@"
+       echo -e "$@"
 }
 
 log_msg() {
-       echo "$@"
+       echo -e "$@"
 }
 
 multisig_create() {
@@ -101,13 +102,144 @@ network_off() {
        exit 1
 }
 
+parse_arguments() {
+       # transform long options into short opts
+       for arg in "$@"; do
+               shift
+               case "$arg" in
+                       "--help") set -- "$@" "-h" ;;
+                       "--interactive") set -- "$@" "-i" ;;
+                       "--threshold") set -- "$@" "-m" ;;
+                       "--wallets") set -- "$@" "-n" ;;
+                       *) set -- "$@" "$arg" ;;
+               esac
+       done
+
+       # parse short options
+       OPTIND=1
+       while getopts "hm:n:i" opt
+       do
+               case "$opt" in
+                       "h") usage ;;
+                       "i") set_mode "interactive" ;;
+                       "m") set_threshold "$OPTARG" ;;
+                       "n") set_wallets "$OPTARG" ;;
+                       "?") usage ;;
+               esac
+       done
+}
+
+set_mode() {
+       case "$1" in
+               "interactive") MODE="interactive" ;;
+               *)
+                       log_error "ERROR: unknown mode \"$1\""
+                       usage
+                       ;;
+       esac
+}
+
+set_threshold() {
+       if [[ "$1" -lt 1 ]]; then
+               log_error "ERROR: invalid threshold ($1)"
+               exit 1
+       fi
+       M="$1"
+}
+
+set_wallets() {
+       if [[ "$1" -lt 1 ]]; then
+               log_error "ERROR: invalid wallet count ($1)"
+               exit 1
+       fi
+       N="$1"
+}
+
 usage() {
-       cat << EOF
-usage...?
-EOF
+       log_error "Usage:"
+       log_error ""
+       log_error "\tcold-setup [options]"
+       log_error ""
+       log_error "Options:"
+       log_error "\t--help, -h\tshow this help"
+       log_error "\t--interactive, -i\tuse interactive mode"
+       log_error "\t--threshold, -m\tset spend threshold"
+       log_error "\t--wallets, -n\tset wallet count"
+       exit 1
+}
+
+usb_detect() {
+       local DEVNAME
+       log_msg "plug in usb drive now.\ndetecting..."
+
+       coproc udevadm monitor -s block/disk -u -p
+
+       while true; do
+               read -u ${COPROC[0]} LINE
+               if [[ "$LINE" =~ "add" ]]; then
+                       break;
+               fi
+       done
+
+       while true; do
+               read -u ${COPROC[0]} PROPERTY
+               if [[ "$PROPERTY" =~ "DEVNAME" ]]; then
+                       DEVNAME="${PROPERTY##DEVNAME=}"
+                       break;
+               fi
+       done
+
+       kill $COPROC_PID
+
+       log_msg "found usb drive: $DEVNAME"
+       echo "$DEVNAME"
+}
+
+usb_eject() {
+       exit 1
+}
+
+usb_load() {
+       exit 1
+}
+
+usb_mount() {
+       exit 1
+}
+
+usb_setup() {
+       exit 1
+}
+
+usb_unmount() {
        exit 1
 }
 
+usbs() {
+       local PATH
+       local MOUNTPOINT
+       for((i = 1; i <= $N; i++)); do
+               PATH="`usb_detect`"
+               MOUNTPOINT="`usb_setup "$PATH"`"
+               usb_load "$MOUNTPOINT" "$i"
+               usb_unmount "$MOUNTPOINT"
+               usb_eject "$PATH"
+       done
+}
+
+validate_parameters() {
+       if [[ "$M" -gt "$N" ]]; then
+               log_error "ERROR: threshold>wallets ($M>$N)"
+               exit 1
+       fi
+
+       if [[ "$N" -eq 1 ]]; then
+               log_error "ERROR: no multisignature to be created ($M of $N)"
+               log_error "exitting..."
+               exit 1
+       fi
+}
+
 wallet_change_descriptors() {
        local CMD="$BITCOIN_CLI -rpcwallet=wallet$1 listdescriptors | jq -j '.descriptors | map(select(.desc | startswith(\"wpkh(\"))) | map(select(.internal == true)) | map(.desc | ltrimstr(\"wpkh(\")) | .[] | split(\")\") | .[0]'"
        local DESCRIPTORS=$(eval "$CMD")
@@ -153,7 +285,7 @@ wallet_load() {
 }
 
 wallets() {
-       for((i = 1; i <= $1; i++)); do
+       for((i = 1; i <= $N; i++)); do
                wallet_create "$i"
        done
 }
@@ -164,15 +296,31 @@ wallets_clean() {
 
 main() {
        depends
-       bitcoin_core_start
 
-       wallets "$N"
+       parse_arguments "$@"
+
+       validate_parameters
 
+       if [[ "$MODE" == "interactive" ]]; then
+               main_interactive
+               exit
+       fi
+
+       bitcoin_core_start
+
+       wallets
        multisig_create
+       usbs
 
        wallets_clean
 
        bitcoin_core_stop
 }
 
+main_interactive() {
+       log_msg "interactive mode started..."
+       log_error "ERROR: interactive mode not implemented"
+       exit 1
+}
+
 main "$@"