Refactor to return results by value, add wallet list_unspent and related types
This commit is contained in:
154
cc/bdk_ffi.h
Normal file
154
cc/bdk_ffi.h
Normal file
@@ -0,0 +1,154 @@
|
||||
/*! \file */
|
||||
/*******************************************
|
||||
* *
|
||||
* File auto-generated by `::safer_ffi`. *
|
||||
* *
|
||||
* Do not manually edit this file. *
|
||||
* *
|
||||
*******************************************/
|
||||
|
||||
#ifndef __RUST_BDK_FFI__
|
||||
#define __RUST_BDK_FFI__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct BlockchainConfig BlockchainConfig_t;
|
||||
|
||||
BlockchainConfig_t * new_electrum_config (
|
||||
char const * url,
|
||||
char const * socks5,
|
||||
int16_t retry,
|
||||
int16_t timeout);
|
||||
|
||||
void free_blockchain_config (
|
||||
BlockchainConfig_t * blockchain_config);
|
||||
|
||||
typedef struct DatabaseConfig DatabaseConfig_t;
|
||||
|
||||
typedef struct OpaqueWallet OpaqueWallet_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
OpaqueWallet_t * ok;
|
||||
|
||||
char * * err;
|
||||
|
||||
} FfiResult_OpaqueWallet_t;
|
||||
|
||||
FfiResult_OpaqueWallet_t new_wallet_result (
|
||||
char const * descriptor,
|
||||
char const * change_descriptor,
|
||||
BlockchainConfig_t const * blockchain_config,
|
||||
DatabaseConfig_t const * database_config);
|
||||
|
||||
void free_wallet_result (
|
||||
FfiResult_OpaqueWallet_t wallet_result);
|
||||
|
||||
typedef struct {
|
||||
|
||||
char * txid;
|
||||
|
||||
uint32_t vout;
|
||||
|
||||
} OutPoint_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
uint64_t value;
|
||||
|
||||
char * script_pubkey;
|
||||
|
||||
} TxOut_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
OutPoint_t outpoint;
|
||||
|
||||
TxOut_t txout;
|
||||
|
||||
uint16_t keychain;
|
||||
|
||||
} LocalUtxo_t;
|
||||
|
||||
/** \brief
|
||||
* Same as [`Vec<T>`][`rust::Vec`], but with guaranteed `#[repr(C)]` layout
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
LocalUtxo_t * ptr;
|
||||
|
||||
size_t len;
|
||||
|
||||
size_t cap;
|
||||
|
||||
} Vec_LocalUtxo_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
Vec_LocalUtxo_t ok;
|
||||
|
||||
char * * err;
|
||||
|
||||
} FfiResultVec_LocalUtxo_t;
|
||||
|
||||
void free_unspent_result (
|
||||
FfiResultVec_LocalUtxo_t unspent_result);
|
||||
|
||||
typedef struct {
|
||||
|
||||
void * ok;
|
||||
|
||||
char * * err;
|
||||
|
||||
} FfiResult_void_t;
|
||||
|
||||
FfiResult_void_t sync_wallet (
|
||||
OpaqueWallet_t const * opaque_wallet);
|
||||
|
||||
typedef struct {
|
||||
|
||||
char * * ok;
|
||||
|
||||
char * * err;
|
||||
|
||||
} FfiResult_char_ptr_t;
|
||||
|
||||
FfiResult_char_ptr_t new_address (
|
||||
OpaqueWallet_t const * opaque_wallet);
|
||||
|
||||
FfiResultVec_LocalUtxo_t list_unspent (
|
||||
OpaqueWallet_t const * opaque_wallet);
|
||||
|
||||
DatabaseConfig_t * new_memory_config (void);
|
||||
|
||||
DatabaseConfig_t * new_sled_config (
|
||||
char const * path,
|
||||
char const * tree_name);
|
||||
|
||||
void free_database_config (
|
||||
DatabaseConfig_t * database_config);
|
||||
|
||||
void free_string_result (
|
||||
FfiResult_char_ptr_t string_result);
|
||||
|
||||
void free_void_result (
|
||||
FfiResult_void_t void_result);
|
||||
|
||||
/** \brief
|
||||
* Frees a Rust-allocated string
|
||||
*/
|
||||
void free_string (
|
||||
char * string);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* __RUST_BDK_FFI__ */
|
||||
@@ -12,19 +12,20 @@ int main (int argc, char const * const argv[])
|
||||
//DatabaseConfig_t *db_config = new_sled_config("/home/steve/.bdk", "test_wallet");
|
||||
DatabaseConfig_t *db_config = new_memory_config();
|
||||
|
||||
WalletResult_t *wallet_result = new_wallet_result("bad", "bad", bc_config, db_config);
|
||||
assert(wallet_result != NULL);
|
||||
// new wallet with bad descriptor
|
||||
FfiResult_OpaqueWallet_t wallet_result = new_wallet_result("bad","bad",bc_config,db_config);
|
||||
assert(wallet_result.err != NULL);
|
||||
assert(wallet_result.ok == NULL);
|
||||
|
||||
free_blockchain_config(bc_config);
|
||||
free_database_config(db_config);
|
||||
char *wallet_err = get_wallet_err(wallet_result);
|
||||
|
||||
char *wallet_err = *wallet_result.err;
|
||||
assert(wallet_err != NULL);
|
||||
assert( 0 == strcmp(wallet_err,"Descriptor") );
|
||||
//printf("wallet err: %s\n", wallet_err);
|
||||
WalletRef_t *wallet_ref = get_wallet_ok(wallet_result);
|
||||
assert(wallet_ref == NULL);
|
||||
free_string(wallet_err);
|
||||
// printf("wallet err: %s\n", wallet_err);
|
||||
|
||||
free_wallet_result(wallet_result);
|
||||
|
||||
}
|
||||
|
||||
// test new wallet
|
||||
@@ -33,51 +34,94 @@ int main (int argc, char const * const argv[])
|
||||
char const *change = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)";
|
||||
|
||||
BlockchainConfig_t *bc_config = new_electrum_config("ssl://electrum.blockstream.info:60002", NULL, 5, 30);
|
||||
//DatabaseConfig_t *db_config = new_sled_config("/home/steve/.bdk", "test_wallet");
|
||||
DatabaseConfig_t *db_config = new_memory_config();
|
||||
|
||||
WalletResult_t *wallet_result = new_wallet_result(desc, change, bc_config, db_config);
|
||||
assert(wallet_result != NULL);
|
||||
// new wallet
|
||||
FfiResult_OpaqueWallet_t wallet_result = new_wallet_result(desc,change,bc_config,db_config);
|
||||
assert(wallet_result.err == NULL);
|
||||
assert(wallet_result.ok != NULL);
|
||||
|
||||
free_blockchain_config(bc_config);
|
||||
free_database_config(db_config);
|
||||
char *wallet_err = get_wallet_err(wallet_result);
|
||||
assert(wallet_err == NULL);
|
||||
WalletRef_t *wallet_ref = get_wallet_ok(wallet_result);
|
||||
assert(wallet_ref != NULL);
|
||||
|
||||
// test sync_wallet
|
||||
VoidResult_t *sync_result = sync_wallet(wallet_ref);
|
||||
free_void_result(sync_result);
|
||||
OpaqueWallet_t *wallet = wallet_result.ok;
|
||||
|
||||
// test new_address
|
||||
StringResult_t *address_result1 = new_address(wallet_ref);
|
||||
char *address1 = get_string_ok(address_result1);
|
||||
//printf("address1: %s\n", address1);
|
||||
assert( 0 == strcmp(address1,"tb1qgkhp034fyxeta00h0nne9tzfm0vsxq4prduzxp"));
|
||||
free_string(address1);
|
||||
// test sync wallet
|
||||
FfiResult_void_t sync_result = sync_wallet(wallet);
|
||||
assert(sync_result.ok != NULL);
|
||||
assert(sync_result.err == NULL);
|
||||
free_void_result(sync_result);
|
||||
|
||||
// test new address
|
||||
FfiResult_char_ptr_t address_result1 = new_address(wallet);
|
||||
assert(address_result1.ok != NULL);
|
||||
assert(address_result1.err == NULL);
|
||||
// printf("address1 = %s\n", *address_result1.ok);
|
||||
assert( 0 == strcmp(*address_result1.ok,"tb1qgkhp034fyxeta00h0nne9tzfm0vsxq4prduzxp"));
|
||||
free_string_result(address_result1);
|
||||
|
||||
StringResult_t *address_result2 = new_address(wallet_ref);
|
||||
char *address2 = get_string_ok(address_result2);
|
||||
//printf("address2: %s\n", address2);
|
||||
assert(0 == strcmp(address2,"tb1qd6u9q327sru2ljvwzdtfrdg36sapax7udz97wf"));
|
||||
free_string(address2);
|
||||
FfiResult_char_ptr_t address_result2 = new_address(wallet);
|
||||
assert(address_result2.ok != NULL);
|
||||
assert(address_result2.err == NULL);
|
||||
// printf("address2 = %s\n", *address_result2.ok);
|
||||
assert( 0 == strcmp(*address_result2.ok,"tb1qd6u9q327sru2ljvwzdtfrdg36sapax7udz97wf"));
|
||||
free_string_result(address_result2);
|
||||
|
||||
free_wallet_ref(wallet_ref);
|
||||
|
||||
// test free_wallet
|
||||
free_wallet_result(wallet_result);
|
||||
|
||||
// test free_wallet NULL doesn't crash
|
||||
free_wallet_result(NULL);
|
||||
|
||||
// verify free_wallet after free_wallet fails (core dumped)
|
||||
////free_wallet_result(wallet_result);
|
||||
//// free_wallet_result(wallet_result);
|
||||
|
||||
// verify sync_wallet after free_wallet fails (core dumped)
|
||||
////VoidResult_t sync_result2 = sync_wallet(wallet_result);
|
||||
|
||||
//// FfiResult_void_t sync_result2 = sync_wallet(wallet);
|
||||
}
|
||||
|
||||
// test get unspent utxos
|
||||
{
|
||||
char const *desc = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)";
|
||||
char const *change = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)";
|
||||
|
||||
BlockchainConfig_t *bc_config = new_electrum_config("ssl://electrum.blockstream.info:60002", NULL, 5, 30);
|
||||
DatabaseConfig_t *db_config = new_memory_config();
|
||||
|
||||
// new wallet
|
||||
FfiResult_OpaqueWallet_t wallet_result = new_wallet_result(desc,change,bc_config,db_config);
|
||||
assert(wallet_result.err == NULL);
|
||||
assert(wallet_result.ok != NULL);
|
||||
|
||||
free_blockchain_config(bc_config);
|
||||
free_database_config(db_config);
|
||||
|
||||
OpaqueWallet_t *wallet = wallet_result.ok;
|
||||
|
||||
// test sync wallet
|
||||
FfiResult_void_t sync_result = sync_wallet(wallet);
|
||||
assert(sync_result.ok != NULL);
|
||||
assert(sync_result.err == NULL);
|
||||
free_void_result(sync_result);
|
||||
|
||||
// list unspent
|
||||
FfiResultVec_LocalUtxo_t unspent_result = list_unspent(wallet);
|
||||
assert(unspent_result.ok.len == 7);
|
||||
assert(unspent_result.err == NULL);
|
||||
|
||||
LocalUtxo_t * unspent_ptr = unspent_result.ok.ptr;
|
||||
for (int i = 0; i < unspent_result.ok.len; i++) {
|
||||
// printf("%d: outpoint.txid: %s\n", i, unspent_ptr[i].outpoint.txid);
|
||||
assert(unspent_ptr[i].outpoint.txid != NULL);
|
||||
// printf("%d: outpoint.vout: %d\n", i, unspent_ptr[i].outpoint.vout);
|
||||
assert(unspent_ptr[i].outpoint.vout >= 0);
|
||||
// printf("%d: txout.value: %ld\n", i, unspent_ptr[i].txout.value);
|
||||
assert(unspent_ptr[i].txout.value > 0);
|
||||
// printf("%d: txout.script_pubkey: %s\n", i, unspent_ptr[i].txout.script_pubkey);
|
||||
assert(unspent_ptr[i].txout.script_pubkey != NULL);
|
||||
// printf("%d: keychain: %d\n", i, unspent_ptr[i].keychain);
|
||||
assert(unspent_ptr[i].keychain >= 0);
|
||||
}
|
||||
|
||||
free_unspent_result(unspent_result);
|
||||
free_wallet_result(wallet_result);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
Reference in New Issue
Block a user