]> infiniteadaptability.org Git - cold/commitdiff
...
authoralex <[email protected]>
Thu, 23 Jun 2022 01:02:19 +0000 (18:02 -0700)
committeralex <[email protected]>
Thu, 23 Jun 2022 01:02:19 +0000 (18:02 -0700)
.gitignore
cold-setup
test/setup.sh
test/wallet_correctness.tests.sh [new file with mode: 0755]
test/wallet_create_blank.tests.sh [new file with mode: 0755]
test/wallet_dump_descriptors.tests.sh [new file with mode: 0755]
test/wallet_dump_descriptors_correctness.tests.sh [new file with mode: 0755]
test/wallet_load.tests.sh [new file with mode: 0755]

index c0755f805104bed560563558d8ebd2f81f5a0e5f..707288d100a28cd9bd75cca4a8173ce6971d5cb8 100644 (file)
@@ -18,9 +18,6 @@ configure.scan
 **/Makefile.in
 stamp-h1
 
-# tags
-tags
-
 # build objects
 *.o
 *.log
index 8c441fe8ceae5110d1c7b7540967136d6baf9b73..ec45d85c788fbb93ec11604cd32b103fd6f843ca 100755 (executable)
@@ -120,6 +120,12 @@ wallet_create() {
        log_info "created wallet: wallet$1"
 }
 
+wallet_create_blank() {
+       local CMD="$BITCOIN_CLI -named createwallet wallet_name=wallet$1 descriptors=true blank=true"
+       eval "$CMD" > /dev/null
+       log_info "created blank wallet: wallet$1"
+}
+
 wallet_descriptors() {
        local CMD="$BITCOIN_CLI -rpcwallet=wallet$1 listdescriptors | jq -j '.descriptors | map(select(.desc | startswith(\"wpkh(\"))) | map(select(.internal == false)) | map(.desc | ltrimstr(\"wpkh(\")) | .[] | split(\")\") | .[0]'"
        local DESCRIPTORS=$(eval "$CMD")
@@ -134,6 +140,18 @@ wallet_dump_descriptors() {
        log_info "dumped descriptors for wallet$1 into $DUMPFILE"
 }
 
+wallet_load() {
+       if [[ ! -e "$2" ]]; then
+               log_error "file not found: $2"
+               exit 1
+       fi
+
+       local CMD="$BITCOIN_CLI -stdin -rpcwallet=wallet$1 importdescriptors"
+       wallet_create_blank "$1"
+       cat "$2" | jq -r '.descriptors' | tr -d '\n' | eval "$CMD"
+       log_info "loaded descriptors for wallet$1 from $2"
+}
+
 wallets() {
        for((i = 1; i <= $1; i++)); do
                wallet_create "$i"
index 14eabdaddce1646e31f4c92c2240589712743212..adbda6e3d4a02a04b6efae680c69985fc6ec7d24 100644 (file)
@@ -16,6 +16,714 @@ setup_env() {
        bitcoin_core_start
 } > /dev/null 2>&1
 
+setup_test_wallets() {
+       cat > wallet1.descriptors << EOF
+{
+  "wallet_name": "wallet1",
+  "descriptors": [
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPeD8yyw44GTpzonPir41WK5cS3o7UMDLJiufmNbW4ReMCk9q5UrS9ynty9vyH2QCbxatZsDg4MZUrrujWfSPVNCujUXtSDKx/44'/1'/0'/0/*)#tzs7n72a",
+      "timestamp": 1655929836,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPeD8yyw44GTpzonPir41WK5cS3o7UMDLJiufmNbW4ReMCk9q5UrS9ynty9vyH2QCbxatZsDg4MZUrrujWfSPVNCujUXtSDKx/49'/1'/0'/0/*))#jmxrm0zc",
+      "timestamp": 1655929836,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPeD8yyw44GTpzonPir41WK5cS3o7UMDLJiufmNbW4ReMCk9q5UrS9ynty9vyH2QCbxatZsDg4MZUrrujWfSPVNCujUXtSDKx/84'/1'/0'/0/*)#llselrjy",
+      "timestamp": 1655929836,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPeD8yyw44GTpzonPir41WK5cS3o7UMDLJiufmNbW4ReMCk9q5UrS9ynty9vyH2QCbxatZsDg4MZUrrujWfSPVNCujUXtSDKx/86'/1'/0'/0/*)#p0vpuryp",
+      "timestamp": 1655929836,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPeD8yyw44GTpzonPir41WK5cS3o7UMDLJiufmNbW4ReMCk9q5UrS9ynty9vyH2QCbxatZsDg4MZUrrujWfSPVNCujUXtSDKx/44'/1'/0'/1/*)#6k4lwt69",
+      "timestamp": 1655929836,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPeD8yyw44GTpzonPir41WK5cS3o7UMDLJiufmNbW4ReMCk9q5UrS9ynty9vyH2QCbxatZsDg4MZUrrujWfSPVNCujUXtSDKx/49'/1'/0'/1/*))#5cwxqzfv",
+      "timestamp": 1655929837,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPeD8yyw44GTpzonPir41WK5cS3o7UMDLJiufmNbW4ReMCk9q5UrS9ynty9vyH2QCbxatZsDg4MZUrrujWfSPVNCujUXtSDKx/84'/1'/0'/1/*)#wt4czkzu",
+      "timestamp": 1655929837,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPeD8yyw44GTpzonPir41WK5cS3o7UMDLJiufmNbW4ReMCk9q5UrS9ynty9vyH2QCbxatZsDg4MZUrrujWfSPVNCujUXtSDKx/86'/1'/0'/1/*)#smfqpk5e",
+      "timestamp": 1655929837,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    }
+  ]
+}
+EOF
+
+       cat > wallet2.descriptors << EOF
+{
+  "wallet_name": "wallet2",
+  "descriptors": [
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPdqqBLnUjZibmJ1CQfNPengbCfJCN4H1ryHVvW36CMhZ7kTCyyGANzeLGFzZwFCYuiMs9m1u32YVgrqA3c7Bm7yk3kM6AVvd/44'/1'/0'/0/*)#hta7kvm6",
+      "timestamp": 1655929837,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPdqqBLnUjZibmJ1CQfNPengbCfJCN4H1ryHVvW36CMhZ7kTCyyGANzeLGFzZwFCYuiMs9m1u32YVgrqA3c7Bm7yk3kM6AVvd/49'/1'/0'/0/*))#qgt78vw3",
+      "timestamp": 1655929837,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPdqqBLnUjZibmJ1CQfNPengbCfJCN4H1ryHVvW36CMhZ7kTCyyGANzeLGFzZwFCYuiMs9m1u32YVgrqA3c7Bm7yk3kM6AVvd/84'/1'/0'/0/*)#7n5mv4hy",
+      "timestamp": 1655929837,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPdqqBLnUjZibmJ1CQfNPengbCfJCN4H1ryHVvW36CMhZ7kTCyyGANzeLGFzZwFCYuiMs9m1u32YVgrqA3c7Bm7yk3kM6AVvd/86'/1'/0'/0/*)#5rj7jqqr",
+      "timestamp": 1655929837,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPdqqBLnUjZibmJ1CQfNPengbCfJCN4H1ryHVvW36CMhZ7kTCyyGANzeLGFzZwFCYuiMs9m1u32YVgrqA3c7Bm7yk3kM6AVvd/44'/1'/0'/1/*)#xlcltetz",
+      "timestamp": 1655929837,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPdqqBLnUjZibmJ1CQfNPengbCfJCN4H1ryHVvW36CMhZ7kTCyyGANzeLGFzZwFCYuiMs9m1u32YVgrqA3c7Bm7yk3kM6AVvd/49'/1'/0'/1/*))#xtrmup99",
+      "timestamp": 1655929837,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPdqqBLnUjZibmJ1CQfNPengbCfJCN4H1ryHVvW36CMhZ7kTCyyGANzeLGFzZwFCYuiMs9m1u32YVgrqA3c7Bm7yk3kM6AVvd/84'/1'/0'/1/*)#08363q8u",
+      "timestamp": 1655929837,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPdqqBLnUjZibmJ1CQfNPengbCfJCN4H1ryHVvW36CMhZ7kTCyyGANzeLGFzZwFCYuiMs9m1u32YVgrqA3c7Bm7yk3kM6AVvd/86'/1'/0'/1/*)#9hhl04sm",
+      "timestamp": 1655929837,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    }
+  ]
+}
+EOF
+
+       cat > wallet3.descriptors << EOF
+{
+  "wallet_name": "wallet3",
+  "descriptors": [
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPf8ajraNisX2tTyjeGHaeqh4kzu3uzdc4D9RrRJmoErxhhzb5dcNUH1PqUcr3d3aGxJLdBqi6w38iiD31GyjQVxKcuoNdU7V/44'/1'/0'/0/*)#f4evjc6q",
+      "timestamp": 1655929838,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPf8ajraNisX2tTyjeGHaeqh4kzu3uzdc4D9RrRJmoErxhhzb5dcNUH1PqUcr3d3aGxJLdBqi6w38iiD31GyjQVxKcuoNdU7V/49'/1'/0'/0/*))#64pdkks9",
+      "timestamp": 1655929838,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPf8ajraNisX2tTyjeGHaeqh4kzu3uzdc4D9RrRJmoErxhhzb5dcNUH1PqUcr3d3aGxJLdBqi6w38iiD31GyjQVxKcuoNdU7V/84'/1'/0'/0/*)#0m0c82sf",
+      "timestamp": 1655929838,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPf8ajraNisX2tTyjeGHaeqh4kzu3uzdc4D9RrRJmoErxhhzb5dcNUH1PqUcr3d3aGxJLdBqi6w38iiD31GyjQVxKcuoNdU7V/86'/1'/0'/0/*)#frryg4st",
+      "timestamp": 1655929838,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPf8ajraNisX2tTyjeGHaeqh4kzu3uzdc4D9RrRJmoErxhhzb5dcNUH1PqUcr3d3aGxJLdBqi6w38iiD31GyjQVxKcuoNdU7V/44'/1'/0'/1/*)#cpud0d2c",
+      "timestamp": 1655929838,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPf8ajraNisX2tTyjeGHaeqh4kzu3uzdc4D9RrRJmoErxhhzb5dcNUH1PqUcr3d3aGxJLdBqi6w38iiD31GyjQVxKcuoNdU7V/49'/1'/0'/1/*))#ukfgdmm3",
+      "timestamp": 1655929838,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPf8ajraNisX2tTyjeGHaeqh4kzu3uzdc4D9RrRJmoErxhhzb5dcNUH1PqUcr3d3aGxJLdBqi6w38iiD31GyjQVxKcuoNdU7V/84'/1'/0'/1/*)#702e6lq3",
+      "timestamp": 1655929838,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPf8ajraNisX2tTyjeGHaeqh4kzu3uzdc4D9RrRJmoErxhhzb5dcNUH1PqUcr3d3aGxJLdBqi6w38iiD31GyjQVxKcuoNdU7V/86'/1'/0'/1/*)#chx94qqn",
+      "timestamp": 1655929838,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    }
+  ]
+}
+EOF
+
+       cat > wallet4.descriptors << EOF
+{
+  "wallet_name": "wallet4",
+  "descriptors": [
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPfLE512gVXfTk3irRnPToR2EhJ1iWJQWgjqqhDN17YTqr31nV1KuBtX86NrfFzvCSoxB9zQKAwPVttXqCN831WAreyPff1Q2/44'/1'/0'/0/*)#vhqrracp",
+      "timestamp": 1655929838,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPfLE512gVXfTk3irRnPToR2EhJ1iWJQWgjqqhDN17YTqr31nV1KuBtX86NrfFzvCSoxB9zQKAwPVttXqCN831WAreyPff1Q2/49'/1'/0'/0/*))#0wh3dpek",
+      "timestamp": 1655929838,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPfLE512gVXfTk3irRnPToR2EhJ1iWJQWgjqqhDN17YTqr31nV1KuBtX86NrfFzvCSoxB9zQKAwPVttXqCN831WAreyPff1Q2/84'/1'/0'/0/*)#xklz7ech",
+      "timestamp": 1655929838,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPfLE512gVXfTk3irRnPToR2EhJ1iWJQWgjqqhDN17YTqr31nV1KuBtX86NrfFzvCSoxB9zQKAwPVttXqCN831WAreyPff1Q2/86'/1'/0'/0/*)#cq8cfl65",
+      "timestamp": 1655929838,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPfLE512gVXfTk3irRnPToR2EhJ1iWJQWgjqqhDN17YTqr31nV1KuBtX86NrfFzvCSoxB9zQKAwPVttXqCN831WAreyPff1Q2/44'/1'/0'/1/*)#ar9z7gge",
+      "timestamp": 1655929839,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPfLE512gVXfTk3irRnPToR2EhJ1iWJQWgjqqhDN17YTqr31nV1KuBtX86NrfFzvCSoxB9zQKAwPVttXqCN831WAreyPff1Q2/49'/1'/0'/1/*))#fdl5kvjz",
+      "timestamp": 1655929839,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPfLE512gVXfTk3irRnPToR2EhJ1iWJQWgjqqhDN17YTqr31nV1KuBtX86NrfFzvCSoxB9zQKAwPVttXqCN831WAreyPff1Q2/84'/1'/0'/1/*)#hz6rrvg0",
+      "timestamp": 1655929839,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPfLE512gVXfTk3irRnPToR2EhJ1iWJQWgjqqhDN17YTqr31nV1KuBtX86NrfFzvCSoxB9zQKAwPVttXqCN831WAreyPff1Q2/86'/1'/0'/1/*)#f5ze522v",
+      "timestamp": 1655929839,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    }
+  ]
+}
+EOF
+
+       cat > wallet5.descriptors << EOF
+{
+  "wallet_name": "wallet5",
+  "descriptors": [
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPdzeP7ZpsmpfNR1vVg8Vk4fRbQtStrrzuBx2NieArfZ8ykZtvBfbFtrhsnfSrSGKZqRdyXK8CJdCw3GmXx12JvMi91R8Y5MB/44'/1'/0'/0/*)#h5mmuhls",
+      "timestamp": 1655929839,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPdzeP7ZpsmpfNR1vVg8Vk4fRbQtStrrzuBx2NieArfZ8ykZtvBfbFtrhsnfSrSGKZqRdyXK8CJdCw3GmXx12JvMi91R8Y5MB/49'/1'/0'/0/*))#0jj2f86a",
+      "timestamp": 1655929839,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPdzeP7ZpsmpfNR1vVg8Vk4fRbQtStrrzuBx2NieArfZ8ykZtvBfbFtrhsnfSrSGKZqRdyXK8CJdCw3GmXx12JvMi91R8Y5MB/84'/1'/0'/0/*)#3jv9sxhx",
+      "timestamp": 1655929839,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPdzeP7ZpsmpfNR1vVg8Vk4fRbQtStrrzuBx2NieArfZ8ykZtvBfbFtrhsnfSrSGKZqRdyXK8CJdCw3GmXx12JvMi91R8Y5MB/86'/1'/0'/0/*)#3d8cykkz",
+      "timestamp": 1655929839,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPdzeP7ZpsmpfNR1vVg8Vk4fRbQtStrrzuBx2NieArfZ8ykZtvBfbFtrhsnfSrSGKZqRdyXK8CJdCw3GmXx12JvMi91R8Y5MB/44'/1'/0'/1/*)#xq76pz0g",
+      "timestamp": 1655929839,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPdzeP7ZpsmpfNR1vVg8Vk4fRbQtStrrzuBx2NieArfZ8ykZtvBfbFtrhsnfSrSGKZqRdyXK8CJdCw3GmXx12JvMi91R8Y5MB/49'/1'/0'/1/*))#f360j23f",
+      "timestamp": 1655929839,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPdzeP7ZpsmpfNR1vVg8Vk4fRbQtStrrzuBx2NieArfZ8ykZtvBfbFtrhsnfSrSGKZqRdyXK8CJdCw3GmXx12JvMi91R8Y5MB/84'/1'/0'/1/*)#qxfydn87",
+      "timestamp": 1655929839,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPdzeP7ZpsmpfNR1vVg8Vk4fRbQtStrrzuBx2NieArfZ8ykZtvBfbFtrhsnfSrSGKZqRdyXK8CJdCw3GmXx12JvMi91R8Y5MB/86'/1'/0'/1/*)#qezeerx6",
+      "timestamp": 1655929840,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    }
+  ]
+}
+EOF
+
+       cat > wallet6.descriptors << EOF
+{
+  "wallet_name": "wallet6",
+  "descriptors": [
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPedDiqJFarv77bfM5gsHkdknBrJUj5PRzt27zW778tQZzuDoxAir8CwamSDRkFWtTY3RRBEHaqDdTexvFHJ4cvurLiQ4fbzW/44'/1'/0'/0/*)#z6tplava",
+      "timestamp": 1655929840,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPedDiqJFarv77bfM5gsHkdknBrJUj5PRzt27zW778tQZzuDoxAir8CwamSDRkFWtTY3RRBEHaqDdTexvFHJ4cvurLiQ4fbzW/49'/1'/0'/0/*))#ktstdeta",
+      "timestamp": 1655929840,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPedDiqJFarv77bfM5gsHkdknBrJUj5PRzt27zW778tQZzuDoxAir8CwamSDRkFWtTY3RRBEHaqDdTexvFHJ4cvurLiQ4fbzW/84'/1'/0'/0/*)#3t483zfh",
+      "timestamp": 1655929840,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPedDiqJFarv77bfM5gsHkdknBrJUj5PRzt27zW778tQZzuDoxAir8CwamSDRkFWtTY3RRBEHaqDdTexvFHJ4cvurLiQ4fbzW/86'/1'/0'/0/*)#23xjrzsm",
+      "timestamp": 1655929840,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPedDiqJFarv77bfM5gsHkdknBrJUj5PRzt27zW778tQZzuDoxAir8CwamSDRkFWtTY3RRBEHaqDdTexvFHJ4cvurLiQ4fbzW/44'/1'/0'/1/*)#nwwqzgu9",
+      "timestamp": 1655929840,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPedDiqJFarv77bfM5gsHkdknBrJUj5PRzt27zW778tQZzuDoxAir8CwamSDRkFWtTY3RRBEHaqDdTexvFHJ4cvurLiQ4fbzW/49'/1'/0'/1/*))#sgcwk5qf",
+      "timestamp": 1655929840,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPedDiqJFarv77bfM5gsHkdknBrJUj5PRzt27zW778tQZzuDoxAir8CwamSDRkFWtTY3RRBEHaqDdTexvFHJ4cvurLiQ4fbzW/84'/1'/0'/1/*)#qlsxvhe0",
+      "timestamp": 1655929840,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPedDiqJFarv77bfM5gsHkdknBrJUj5PRzt27zW778tQZzuDoxAir8CwamSDRkFWtTY3RRBEHaqDdTexvFHJ4cvurLiQ4fbzW/86'/1'/0'/1/*)#m9rn7hqr",
+      "timestamp": 1655929840,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    }
+  ]
+}
+EOF
+
+       cat > wallet7.descriptors << EOF
+{
+  "wallet_name": "wallet7",
+  "descriptors": [
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPefbF8gAMusMAzPTZ4JdaFe4sVt28fenqXhpCUmKKW7oFxxKKrctrWJXhieR9mywgsfFq4eXiudU27Jri7pZLrFzxvVN3Jc3/44'/1'/0'/0/*)#c4ec65vr",
+      "timestamp": 1655929840,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPefbF8gAMusMAzPTZ4JdaFe4sVt28fenqXhpCUmKKW7oFxxKKrctrWJXhieR9mywgsfFq4eXiudU27Jri7pZLrFzxvVN3Jc3/49'/1'/0'/0/*))#vuy63der",
+      "timestamp": 1655929841,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPefbF8gAMusMAzPTZ4JdaFe4sVt28fenqXhpCUmKKW7oFxxKKrctrWJXhieR9mywgsfFq4eXiudU27Jri7pZLrFzxvVN3Jc3/84'/1'/0'/0/*)#u2825h6t",
+      "timestamp": 1655929841,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPefbF8gAMusMAzPTZ4JdaFe4sVt28fenqXhpCUmKKW7oFxxKKrctrWJXhieR9mywgsfFq4eXiudU27Jri7pZLrFzxvVN3Jc3/86'/1'/0'/0/*)#hs066nsw",
+      "timestamp": 1655929841,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPefbF8gAMusMAzPTZ4JdaFe4sVt28fenqXhpCUmKKW7oFxxKKrctrWJXhieR9mywgsfFq4eXiudU27Jri7pZLrFzxvVN3Jc3/44'/1'/0'/1/*)#fpue8pum",
+      "timestamp": 1655929841,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPefbF8gAMusMAzPTZ4JdaFe4sVt28fenqXhpCUmKKW7oFxxKKrctrWJXhieR9mywgsfFq4eXiudU27Jri7pZLrFzxvVN3Jc3/49'/1'/0'/1/*))#2lvl2qjh",
+      "timestamp": 1655929841,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPefbF8gAMusMAzPTZ4JdaFe4sVt28fenqXhpCUmKKW7oFxxKKrctrWJXhieR9mywgsfFq4eXiudU27Jri7pZLrFzxvVN3Jc3/84'/1'/0'/1/*)#d7ztfz2n",
+      "timestamp": 1655929841,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPefbF8gAMusMAzPTZ4JdaFe4sVt28fenqXhpCUmKKW7oFxxKKrctrWJXhieR9mywgsfFq4eXiudU27Jri7pZLrFzxvVN3Jc3/86'/1'/0'/1/*)#xy2m8xqk",
+      "timestamp": 1655929841,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    }
+  ]
+}
+EOF
+
+       for((i = 1; i<= 7; i++)); do
+               (wallet_load "$i" "wallet$i.descriptors" > result 2>&1)
+               EXPECTED="created blank wallet: wallet$i
+[
+  {
+    \"success\": true
+  },
+  {
+    \"success\": true
+  },
+  {
+    \"success\": true
+  },
+  {
+    \"success\": true
+  },
+  {
+    \"success\": true
+  },
+  {
+    \"success\": true
+  },
+  {
+    \"success\": true
+  },
+  {
+    \"success\": true
+  }
+]
+loaded descriptors for wallet$i from wallet$i.descriptors"
+               RESULT=$(<result)
+               assert "$EXPECTED" "$RESULT"
+       done
+}
+
 reset_env() {
        clean_env
        setup_env
diff --git a/test/wallet_correctness.tests.sh b/test/wallet_correctness.tests.sh
new file mode 100755 (executable)
index 0000000..8009f82
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+source setup.sh
+
+setup_env
+
+setup_test_wallets
+
+for((i = 1; i <= 7; i++)); do
+       for((j = 1; j <= 1000; j++)); do
+               echo "`$BITCOIN_CLI -rpcwallet=wallet$i getnewaddress`" >> addresses
+       done
+done
+
+assert "4c51b3003c3733763bac695a214ffa11c81fcff4099752536da661c8349eb4e90b60b8463152c4009542611c0639df7be10ece2c291d27a06673292f1d395bb4  addresses" "`b2sum addresses`"
+clean_env
+
+test_succeeded
diff --git a/test/wallet_create_blank.tests.sh b/test/wallet_create_blank.tests.sh
new file mode 100755 (executable)
index 0000000..10230b3
--- /dev/null
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+source setup.sh
+
+setup_env
+
+(wallet_create_blank 1 > result 2>&1)
+EXPECTED="created blank wallet: wallet1"
+RESULT=$(<result)
+assert "$EXPECTED" "$RESULT"
+
+(wallet_create_blank 2 > result 2>&1)
+EXPECTED="created blank wallet: wallet2"
+RESULT=$(<result)
+assert "$EXPECTED" "$RESULT"
+
+clean_env
+
+test_succeeded
diff --git a/test/wallet_dump_descriptors.tests.sh b/test/wallet_dump_descriptors.tests.sh
new file mode 100755 (executable)
index 0000000..400ac9d
--- /dev/null
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+source setup.sh
+
+setup_env
+
+(wallet_create 1 > result 2>&1)
+EXPECTED="created wallet: wallet1"
+RESULT=$(<result)
+assert "$EXPECTED" "$RESULT"
+
+(wallet_dump_descriptors 1 > result 2>&1)
+EXPECTED="dumped descriptors for wallet1 into $DATA_DIRECTORY/wallet1.descriptors"
+RESULT=$(<result)
+assert "$EXPECTED" "$RESULT"
+
+clean_env
+
+test_succeeded
diff --git a/test/wallet_dump_descriptors_correctness.tests.sh b/test/wallet_dump_descriptors_correctness.tests.sh
new file mode 100755 (executable)
index 0000000..77afe14
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+source setup.sh
+
+setup_env
+
+setup_test_wallets
+
+rm *.descriptors
+
+for((i = 1; i <= 7; i++)); do
+       (wallet_dump_descriptors "$i" > result 2>&1)
+       EXPECTED="dumped descriptors for wallet$i into $DATA_DIRECTORY/wallet$i.descriptors"
+       RESULT=$(<result)
+       assert "$EXPECTED" "$RESULT"
+done
+
+EXPECTED="8abc670921298bdff8d28593b4fd6d581a4c83f539e3ffb6d295248dbbf31558fff8681af20b607f9483d0981b184b39cfad107e63a2309f9a6319321659f750  $DATA_DIRECTORY/wallet1.descriptors
+0f8b2546105fc4501dabffba85d4eddcb066a0d8e8e9fd557489de239f1cff47549ea9ee3a001eae3a88ee28355941e4814157c3508f53538131548fb4f97d5d  $DATA_DIRECTORY/wallet2.descriptors
+fa731c649b6dce35dfacabe7bc863462170f4cc612c84957320ee65a1c9ef85b20222c0c199e0f4244413176e75c76e2a42b81ee1cd90906270ae99ec2d003eb  $DATA_DIRECTORY/wallet3.descriptors
+f86b85d9ff88604e1669beaf37138674671d024decb7ff801543208209b387ccce466dc970b1e5b7c3a3a99511ce034e2aa9585208ef3cc3e9a5a52c7cd6a1c9  $DATA_DIRECTORY/wallet4.descriptors
+13cbc0c1b4911720cdda5e0fa8f10bb2798aa34bf03f32ffcebf194f5c664e7082192c58ae4f3812789f24ac96127d105315658e70801315fe6987e0530d36f3  $DATA_DIRECTORY/wallet5.descriptors
+0b3d072b59b4c01161daff81467fda485ee97360767d79c3d5161f783ae4ac282ec03dc2d9bb33b490006df85f62d5b676e178589f6c67c178c4c4300a231783  $DATA_DIRECTORY/wallet6.descriptors
+df5d6ac961e6008ab83ab1e4843cb52628f2250d84df467dffd3b208c290e2d0125de6f12faf9f47ee1201703084f8a06b18772e434d7fa5f40424bcd86a03a6  $DATA_DIRECTORY/wallet7.descriptors"
+RESULT="`b2sum $DATA_DIRECTORY/*.descriptors`"
+assert "$EXPECTED" "$RESULT"
+
+clean_env
+
+test_succeeded
diff --git a/test/wallet_load.tests.sh b/test/wallet_load.tests.sh
new file mode 100755 (executable)
index 0000000..3097cc3
--- /dev/null
@@ -0,0 +1,149 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+source setup.sh
+
+setup_env
+
+set +e
+(wallet_load 1 "walletX.descriptors" > result 2>&1)
+assert "1" "$?"
+set -e
+EXPECTED="file not found: walletX.descriptors"
+RESULT=$(<result)
+assert "$EXPECTED" "$RESULT"
+
+cat > wallet2.descriptors << EOF
+{
+  "wallet_name": "wallet2",
+  "descriptors": [
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPdbbppJxbeuNmjC9wNgqefkQeJPtnDPmRZNCgwb6paPYvRQxUAMm1TCEicmUbdKtWdbD2Yz37R3nMJtgNBiabNUK3Dvq9yf4/44'/1'/0'/0/*)#gfjq40y4",
+      "timestamp": 1655928865,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPdbbppJxbeuNmjC9wNgqefkQeJPtnDPmRZNCgwb6paPYvRQxUAMm1TCEicmUbdKtWdbD2Yz37R3nMJtgNBiabNUK3Dvq9yf4/49'/1'/0'/0/*))#sek2p7p6",
+      "timestamp": 1655928865,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPdbbppJxbeuNmjC9wNgqefkQeJPtnDPmRZNCgwb6paPYvRQxUAMm1TCEicmUbdKtWdbD2Yz37R3nMJtgNBiabNUK3Dvq9yf4/84'/1'/0'/0/*)#f82ydgve",
+      "timestamp": 1655928865,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPdbbppJxbeuNmjC9wNgqefkQeJPtnDPmRZNCgwb6paPYvRQxUAMm1TCEicmUbdKtWdbD2Yz37R3nMJtgNBiabNUK3Dvq9yf4/86'/1'/0'/0/*)#am0y6gu3",
+      "timestamp": 1655928865,
+      "active": true,
+      "internal": false,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "pkh(tprv8ZgxMBicQKsPdbbppJxbeuNmjC9wNgqefkQeJPtnDPmRZNCgwb6paPYvRQxUAMm1TCEicmUbdKtWdbD2Yz37R3nMJtgNBiabNUK3Dvq9yf4/44'/1'/0'/1/*)#eahpg65d",
+      "timestamp": 1655928865,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "sh(wpkh(tprv8ZgxMBicQKsPdbbppJxbeuNmjC9wNgqefkQeJPtnDPmRZNCgwb6paPYvRQxUAMm1TCEicmUbdKtWdbD2Yz37R3nMJtgNBiabNUK3Dvq9yf4/49'/1'/0'/1/*))#k6706n2w",
+      "timestamp": 1655928865,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "wpkh(tprv8ZgxMBicQKsPdbbppJxbeuNmjC9wNgqefkQeJPtnDPmRZNCgwb6paPYvRQxUAMm1TCEicmUbdKtWdbD2Yz37R3nMJtgNBiabNUK3Dvq9yf4/84'/1'/0'/1/*)#cn09saup",
+      "timestamp": 1655928865,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    },
+    {
+      "desc": "tr(tprv8ZgxMBicQKsPdbbppJxbeuNmjC9wNgqefkQeJPtnDPmRZNCgwb6paPYvRQxUAMm1TCEicmUbdKtWdbD2Yz37R3nMJtgNBiabNUK3Dvq9yf4/86'/1'/0'/1/*)#v0298avf",
+      "timestamp": 1655928866,
+      "active": true,
+      "internal": true,
+      "range": [
+        0,
+        999
+      ],
+      "next": 0
+    }
+  ]
+}
+EOF
+
+assert "ae894dbe95838f35513bff5707a0bcd6930920fe210940215505cff2b55c9ae7f493a41010a0dcc2789bec2583c4d6af7001da0a04a0ea92e371137e636bd6c5  wallet2.descriptors" "`b2sum wallet2.descriptors`"
+
+(wallet_load 2 "wallet2.descriptors" > result 2>&1)
+EXPECTED="created blank wallet: wallet2
+[
+  {
+    \"success\": true
+  },
+  {
+    \"success\": true
+  },
+  {
+    \"success\": true
+  },
+  {
+    \"success\": true
+  },
+  {
+    \"success\": true
+  },
+  {
+    \"success\": true
+  },
+  {
+    \"success\": true
+  },
+  {
+    \"success\": true
+  }
+]
+loaded descriptors for wallet2 from wallet2.descriptors"
+RESULT=$(<result)
+assert "$EXPECTED" "$RESULT"
+
+clean_env
+
+test_succeeded