A simple example how to use libwally - from generation of the recovery phrase to signing of the psbt transaction
Diff: main.cpp
- 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); }