Project Summary:
+This project is meant to replace and provide additional tooling for a cold storage setup created in an ad-hoc manner using a few small utilities and Bitcoin Core.
+
+#########################################################################################
+Run Through of Initial Setup:
+The initial setup consisted of a bunch of shell commands and requires the following Debian packages:
+
+`apt-get install -y cryptsetup eject jq nmcli shred`
+
+Bitcoin Core's code was downloaded and compiled. Bitcoin Core was started with:
+
+`bitcoind --daemon`
+
+Networking was shut off:
+
+`nmcli networking off`
+
+Seven different wallets with descriptors ENABLED were created using bitcoin-cli (utility included with Bitcoin Core; see `bitcoin-cli help createwallet` for more information). These descriptors, which included private keys, were dumped into separate files (see `bitcoin-cli help listdescriptors`):
+
+`bitcoin-cli -rpcwallet=wallet1 listdescriptors true > wallet1.descriptors`
+
+A 3 of 7 multisignature setup was created using jq and bitcoin-cli using the following commands:
+
+`echo -n "wsh(sortedmulti(3," > 3of7multi.descriptors`
+
+`bitcoin-cli -rpcwallet=wallet1 listdescriptors | jq -j '.descriptors | map(select(.desc | startswith("wpkh"))) | map(select(.internal == false)) | map(.desc | ltrimstr("wpkh(")) | .[] | split(")") | .[0]' >> 3of7multi.descriptors`
+`bitcoin-cli -rpcwallet=wallet2 listdescriptors | jq -j '.descriptors | map(select(.desc | startswith("wpkh"))) | map(select(.internal == false)) | map(.desc | ltrimstr("wpkh(")) | .[] | split(")") | .[0]' >> 3of7multi.descriptors`
+... 3 to 6 skipped ...
+`bitcoin-cli -rpcwallet=wallet7 listdescriptors | jq -j '.descriptors | map(select(.desc | startswith("wpkh"))) | map(select(.internal == false)) | map(.desc | ltrimstr("wpkh(")) | .[] | split(")") | .[0]' >> 3of7multi.descriptors`
+
+echo "))" >> 3of7multi.descriptors
+cat 3of7multi.descriptors | bitcoin-cli -stdin getdescriptorinfo | jq -j '.descriptor' >> descriptors.txt
+echo -n '", "active": true, "timestamp": "now"}' >> descriptors.txt
+
+Change descriptors were created using the same wallets.
+
+`echo -n "wsh(sortedmulti(3," > 3of7multi.change.descriptors`
+
+`bitcoin-cli -rpcwallet=wallet1 listdescriptors | jq -j '.descriptors | map(select(.desc | startswith("wpkh"))) | map(select(.internal == true)) | map(.desc | ltrimstr("wpkh(")) | .[] | split(")") | .[0]' >> 3of7multi.change.descriptors`
+`bitcoin-cli -rpcwallet=wallet2 listdescriptors | jq -j '.descriptors | map(select(.desc | startswith("wpkh"))) | map(select(.internal == true)) | map(.desc | ltrimstr("wpkh(")) | .[] | split(")") | .[0]' >> 3of7multi.change.descriptors`
+... 3 to 6 skipped
+`bitcoin-cli -rpcwallet=wallet7 listdescriptors | jq -j '.descriptors | map(select(.desc | startswith("wpkh"))) | map(select(.internal == true)) | map(.desc | ltrimstr("wpkh(")) | .[] | split(")") | .[0]' >> 3of7multi.change.descriptors`
+
+`echo "))" >> 3of7multi.change.descriptors`
+
+`echo -n ',{"desc": "' >> descriptors.txt`
+`cat 3of7multi.change.descriptors | bitcoin-cli -stdin getdescriptorinfo | jq -j '.descriptor' >> descriptors.txt`
+`echo '", "active": true, "timestamp": "now", "internal": true}]' >> descriptors.txt`
+
+Manual checking of generated descriptors and addresses (verify addresses are solvable) using bitcoin-cli STRONGLY ENCOURAGED.
+
+Each of the 7 wallets' descriptors (wallet[n].descriptors) were copied to 2 separate usb keys along with the multi-signature descriptors (descriptors.txt). The 14 usb keys were first wiped and setup with encrypted filesystems using the cryptsetup utility. The usb keys were first wiped:
+
+`wipefs -a [DEVICE]`
+
+The device was then encrypted using cryptsetup:
+
+`crypsetup luksFormat --type luks2 [DEVICE]`
+
+The device was decrypted, zero'd, and loaded with an ext4 filesystem:
+
+`cryptsetup luksOpen [DEVICE] [DEVICE NAME]`
+`dd if=/dev/zero of=/dev/mapper/[DEVICE NAME]`
+`mkfs.ext4 /dev/mapper/[DEVICE NAME]`
+
+Devices could then be opened and mounted in the normal way:
+
+`cryptsetup luksOpen [DEVICE] [DEVICE NAME]`
+`mount /dev/mapper/[DEVICE NAME] [MOUNT POINT]`
+
+and unmounted in the normal way:
+
+`umount [MOUNT POINT]`
+`cryptsetup luksClose [DEVICE NAME]`
+`eject [DEVICE]`
+
+Validation that correct files got copied to each usb key was done manually by comparing hashes. Once each wallet was verified copied to 2 separate usb keys, the wallets were securely deleted using the `shred` utility.
+
+`find ~/.bitcoin -name "wallet.dat" -exec shred {} \;`
+
+The computer/storage device that was used to generate the wallets was then wiped using the dd utility:
+
+`dd if=/dev/zero of=/dev/[DEVICE] bs=1m`
+
+On another computer, a "live" wallet was created using descriptors.txt:
+
+`cat descriptors.txt | bitcoin-cli -stdin importdescriptors`
+
+This "live" wallet was then encrypted with a passphrase. Small amounts of bitcoin were sent to this wallet and then a restore and spend was done by creating a unsigned partially signed bitcoin transaction (psbt). An unsigned psbt was created and saved as unsigned.psbt using Bitcoin Core's qt GUI application. Verification and validation of inputs and outputs were done with the following commands:
+
+`bitcoin-cli decodepsbt`
+`bitcoin-cli analyzepsbt`
+
+A new "clean" OS was installed on another computer (again installing Bitcoin Core and required packages as above). Networking was shutoff again like above. Wallets 1-3 were restored by creating blank, descriptor wallets like above and then importing descriptors from mounted usb sticks (unlocking using cryptsetup) with the following commands:
+
+`cat [USB_MOUNT_PATH]/WALLET/[WALLET].descriptor | jq -r '.descriptors' | tr -d '\n' | bitcoin-cli -stdin -rpcwallet=[WALLET] importdescriptors
+
+Signing of the unsigned psbt was done by each wallet:
+
+`bitcoin-cli -rpcwallet=wallet1 walletprocesspsbt "$(cat unsigned.psbt | base64 | tr -d '\n')" true | jq -r '.psbt' > signedbywallet1.psbt`
+`bitcoin-cli -rpcwallet=wallet2 walletprocesspsbt "$(cat signedbywallet1.psbt)" true | jq -r '.psbt' > signedbywallet2.psbt`
+`bitcoin-cli -rpcwallet=wallet3 walletprocesspsbt "$(cat signedbywallet2.psbt)" true | jq -r '.psbt' > completed.psbt`
+
+Completed psbt was transformed back into binary form and saved as signed.psbt:
+
+`cat completed.psbt | base64 -w 0 -d > signed.psbt`
+
+signed.psbt was transferred back to the "live" computer and broadcast to the Bitcoin Network.
+
+Funds were sent to the multi-signature addresses and another wallet and back multiple times using different combinations of keys (i.e. separately with keys 1-3, keys 4-6, and with keys 2, 5 , and 7) each time completely wiping and restoring the "clean" computer.
+
+#########################################################################################
+
+Rationale for project:
+Setup is difficult even for experienced technical users, mistakes can be made and since process is manual and contains a lot of manual checking, unknown failure modes certainly exist. Automated tooling to aid creating and verifying setup URGENTLY needed. GUI creation would allow for non-technical (or minimally technical users) to create robust custody solutions.
+
+Goal:
+Build project and compile to a single binary which can be downloaded, verified, and run without installing any other packages on a clean installation of Debian/Ubuntu.
+
+Initial Project Scope:
+Create simple GUI for satisfying dependencies, setting up 3 of 7 multisignature descriptors, and build a GUI flow for restoring wallets and signing transactions.
+
+Note on dependencies:
+Security is paramount on a project like this. Using only open-source, validated, widely used software is a must. Minimizing dependencies should be a goal of any implementation.
+
+#########################################################################################
+Architecture:
+
+Programming Language: C
+Build Tooling: gnu autotools
+GUI Libary: gtk
+Target OS: Debian (with verification on Ubuntu).
+Packages required to build: cryptsetup-dev libgtk-3-dev
+
+Multi-threaded GUI application. Non-blocking GUI thread receives events from the front-end. Secondary GUI thread receives events, updates state, and updates GUI. Background thread(s) perform background tasks.
+
+Primary problems to tackle:
+-UX of requiring root permissions (installing packages, mount/umount, mkfs.ext4, etc.)
+-running shell commands in a verifiable way (fork + execl?, which), outputing results, failure modes
+
+Three primary GUI flows need to be created.
+
+First flow is satisfying dependencies:
+-automated installing of required packages: jq, mkfs.ext4 (part of the e2fsprogs package)
+-automated installing and validation (requires gpg?) of Bitcoin Core
+-once all dependencies setup, shutdown networking and start Bitcoin Core
+
+NOTE: mount/umount have C bindings (see `man mount.2` and `man umount.2`). The functionality of nmcli, shred, eject, base64, and wipefs should be able to be easily extracted from source-code of their respective packages and can be eliminated as dependencies. The rest of the commands used above (echo, tr, cat, dd) can be eliminated by simple functions.
+
+Second flow is creating multi-signature setup:
+-entering passphrase and generating cryptsetup key
+-choosing, mounting, setting up, unmounting usbs one-by-one
+-walkthrough for setting up a live wallet in Bitcoin Core on a separate computer
+
+Third flow is restoring wallets and signing a psbt:
+-loading psbt into GUI
+-insert usb, decrypting, load wallet, signing psbt, saving result, unloading wallet
+-saving completed psbt
+
+In addition to the three primary flows, extensive testing framework should be created to validate setup.
+
+Avoid dymically (malloc, etc.) allocated memory.
+
+#########################################################################################
+Later:
+-use Yubikey instead of passphrase
+-flow for testing setup
+-flow for signing a message
+-remove dependency on Bitcoin Core, jq
+-remove dependency on mkfs.ext4