A simple example how to use libwally - from generation of the recovery phrase to signing of the psbt transaction

Revision:
3:3d6e031ab07b
Parent:
0:3729443d0bf8
--- a/main.cpp	Mon Sep 16 12:16:53 2019 +0000
+++ b/main.cpp	Thu Sep 19 09:21:23 2019 +0000
@@ -67,36 +67,36 @@
     /**************** BIP-32 HD keys ******************/
 
     // root HD key
-    ext_key root;
-    res = bip32_key_from_seed(seed, sizeof(seed), BIP32_VER_TEST_PRIVATE, 0, &root);
+    ext_key * root = NULL;
+    res = bip32_key_from_seed_alloc(seed, sizeof(seed), BIP32_VER_TEST_PRIVATE, 0, &root);
     // get base58 xprv string
     char *xprv = NULL;
-    res = bip32_key_to_base58(&root, BIP32_FLAG_KEY_PRIVATE, &xprv);
+    res = bip32_key_to_base58(root, BIP32_FLAG_KEY_PRIVATE, &xprv);
     printf("Root key: %s\r\n", xprv);
     // don't forget to securely clean up the string when done
     wally_free_string(xprv);
 
     // deriving account key for native segwit, testnet: m/84h/1h/0h
-    ext_key account;
+    ext_key * account = NULL;
     uint32_t path[] = {
         BIP32_INITIAL_HARDENED_CHILD+84, // 84h
         BIP32_INITIAL_HARDENED_CHILD+1,  // 1h
         BIP32_INITIAL_HARDENED_CHILD     // 0h
     };
-    res = bip32_key_from_parent_path(&root, path, 3, BIP32_FLAG_KEY_PRIVATE, &account);
+    res = bip32_key_from_parent_path_alloc(root, path, 3, BIP32_FLAG_KEY_PRIVATE, &account);
 
-    res = bip32_key_to_base58(&account, BIP32_FLAG_KEY_PRIVATE, &xprv);
+    res = bip32_key_to_base58(account, BIP32_FLAG_KEY_PRIVATE, &xprv);
     printf("Account private key: %s\r\n", xprv);
     // don't forget to securely clean up the string when done
     wally_free_string(xprv);
 
     char *xpub = NULL;
-    res = bip32_key_to_base58(&account, BIP32_FLAG_KEY_PUBLIC, &xpub);
+    res = bip32_key_to_base58(account, BIP32_FLAG_KEY_PUBLIC, &xpub);
     printf("Account public key: %s\r\n", xpub);
 
     // fingerprint
     printf("Derivation information: [");
-    print_hex(root.hash160, 4);
+    print_hex(root->hash160, 4);
     printf("/84h/1h/0h]%s\r\n", xpub);
 
     // don't forget to securely clean up the string when done
@@ -105,35 +105,36 @@
     /**************** Addresses ******************/
 
     // key for the first address
-    ext_key first_recv;
+    ext_key * first_recv = NULL;
     uint32_t recv_path[] = {0, 0};
     // we only need public key here, no need in private key
-    res = bip32_key_from_parent_path(&account, recv_path, 2, BIP32_FLAG_KEY_PUBLIC, &first_recv);
+    res = bip32_key_from_parent_path_alloc(account, recv_path, 2, BIP32_FLAG_KEY_PUBLIC, &first_recv);
     char * addr = NULL;
 
     // native segwit address
-    res = wally_bip32_key_to_addr_segwit(&first_recv, "tb", 0, &addr);
+    res = wally_bip32_key_to_addr_segwit(first_recv, "tb", 0, &addr);
     printf("Segwit address: %s\r\n", addr);
     wally_free_string(addr);
 
     // nested segwit address
-    res = wally_bip32_key_to_address(&first_recv, WALLY_ADDRESS_TYPE_P2SH_P2WPKH, WALLY_ADDRESS_VERSION_P2SH_TESTNET, &addr);
+    res = wally_bip32_key_to_address(first_recv, WALLY_ADDRESS_TYPE_P2SH_P2WPKH, WALLY_ADDRESS_VERSION_P2SH_TESTNET, &addr);
     printf("Nested segwit address: %s\r\n", addr);
     wally_free_string(addr);
 
     // legacy address
-    res = wally_bip32_key_to_address(&first_recv, WALLY_ADDRESS_TYPE_P2PKH, WALLY_ADDRESS_VERSION_P2PKH_TESTNET, &addr);
+    res = wally_bip32_key_to_address(first_recv, WALLY_ADDRESS_TYPE_P2PKH, WALLY_ADDRESS_VERSION_P2PKH_TESTNET, &addr);
     printf("Legacy address: %s\r\n", addr);
     wally_free_string(addr);
 
     /**************** PSBT ******************/
 
-    char b64_psbt[] = "cHNidP8BAHICAAAAAZ6vI6XXFrVMCyCnY0pmGQkwTsHi/kNK0dQmMZj+JqsiAAAAA"
-                      "AD/////AlDDAAAAAAAAF6kUTrBkI8NYr13XpG4aVhwsUgkq+HaHwsIAAAAAAAAWAB"
-                      "Q8T0jHl7apZZwNbvwMz66pfT0A0wAAAAAAAQEfoIYBAAAAAAAWABRy2Nt/+F2j9EY"
-                      "d2bcI5CfSqeeyMSIGAmijc35Kh8Nfa9oC0jGb2I1UfzkS0MqAfHw0BKA6JRwuGCbd"
-                      "2XhUAACAAQAAgAAAAIAAAAAAAAAAAAAAIgIDk0lh/hfivA7GPZc1jEGSabYwVJjFY"
-                      "HRPtfNeC2TMFRUYJt3ZeFQAAIABAACAAAAAgAEAAAAAAAAAAA==";
+    char b64_psbt[] = "cHNidP8BAHICAAAAAX7U8W8nyYJcYzFjoHa5UH5j0Ug43ej/q2bf"
+                          "IPq8XnjeAAAAAAD/////AihATAAAAAAAFgAUPE9Ix5e2qWWcDW78"
+                          "DM+uqX09ANNAS0wAAAAAABepFPPNvp1TAyho+Kys4wwejY8iakgQ"
+                          "hwAAAAAAAQEfgJaYAAAAAAAWABRy2Nt/+F2j9EYd2bcI5CfSqeey"
+                          "MSIGAmijc35Kh8Nfa9oC0jGb2I1UfzkS0MqAfHw0BKA6JRwuGCbd"
+                          "2XhUAACAAQAAgAAAAIAAAAAAAAAAAAAiAgOTSWH+F+K8DsY9lzWM"
+                          "QZJptjBUmMVgdE+1814LZMwVFRgm3dl4VAAAgAEAAIAAAACAAQAAAAAAAAAAAA==";
     wally_psbt * psbt = NULL;
     res = wally_psbt_from_base64(b64_psbt, &psbt);
 
@@ -163,19 +164,20 @@
             );
         printf("Input %d. Hash to sign: ", i);
         println_hex(hash, 32);
-        ext_key pk;
-        bip32_key_from_parent_path(&root, 
+        ext_key * pk = NULL;
+        bip32_key_from_parent_path_alloc(root, 
             psbt->inputs[i].keypaths->items[0].origin.path, 
             psbt->inputs[i].keypaths->items[0].origin.path_len, 
             BIP32_FLAG_KEY_PRIVATE, &pk);
 
         uint8_t sig[EC_SIGNATURE_LEN];
         wally_ec_sig_from_bytes(
-                pk.priv_key+1, 32, // first byte of ext_key.priv_key is 0x00
+                pk->priv_key+1, 32, // first byte of ext_key.priv_key is 0x00
                 hash, 32,
                 EC_FLAG_ECDSA,
                 sig, EC_SIGNATURE_LEN
             );
+        bip32_key_free(pk);
         uint8_t der[EC_SIGNATURE_DER_MAX_LEN+1];
         wally_ec_sig_to_der(
                 sig, EC_SIGNATURE_LEN,
@@ -187,7 +189,7 @@
             partial_sigs_map_init_alloc(1, &psbt->inputs[i].partial_sigs);
         }
         add_new_partial_sig(psbt->inputs[i].partial_sigs,
-                pk.pub_key, 
+                pk->pub_key, 
                 der, len+1
             );
     }
@@ -199,6 +201,8 @@
     printf("PSBT: %s\r\n", output);
     wally_free_string(output);
 
+    bip32_key_free(root);
+    bip32_key_free(account);
     wally_cleanup(0);
 }