Add Wallet.balance()
This commit is contained in:
		
							parent
							
								
									adadcbc982
								
							
						
					
					
						commit
						cd813a14b1
					
				| @ -232,9 +232,34 @@ interface LibJna : Library { | |||||||
|         override fun getFieldOrder() = listOf("ok", "err") |         override fun getFieldOrder() = listOf("ok", "err") | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // void free_unspent_result ( |     // void free_veclocalutxo_result ( | ||||||
|     //    FfiResult_Vec_LocalUtxo_t unspent_result); |     //    FfiResult_Vec_LocalUtxo_t unspent_result); | ||||||
|     fun free_unspent_result(unspent_result: FfiResultVec_LocalUtxo_t.ByValue) |     fun free_veclocalutxo_result(unspent_result: FfiResultVec_LocalUtxo_t.ByValue) | ||||||
|  | 
 | ||||||
|  |     // typedef struct { | ||||||
|  |     // | ||||||
|  |     //    uint64_t ok; | ||||||
|  |     // | ||||||
|  |     //    FfiError_t err; | ||||||
|  |     // | ||||||
|  |     // } FfiResult_uint64_t; | ||||||
|  |     open class FfiResult_uint64_t : Structure() { | ||||||
|  | 
 | ||||||
|  |         class ByValue : FfiResult_uint64_t(), Structure.ByValue | ||||||
|  |         class ByReference : FfiResult_uint64_t(), Structure.ByReference | ||||||
|  |          | ||||||
|  |         @JvmField | ||||||
|  |         var ok: Long = Long.MIN_VALUE | ||||||
|  | 
 | ||||||
|  |         @JvmField | ||||||
|  |         var err: Short = 0 | ||||||
|  | 
 | ||||||
|  |         override fun getFieldOrder() = listOf("ok", "err") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // void free_uint64_result ( | ||||||
|  |     //    FfiResult_uint64_t void_result); | ||||||
|  |     fun free_uint64_result(unspent_result: FfiResult_uint64_t.ByValue) | ||||||
|      |      | ||||||
|     // FfiResultVoid_t sync_wallet ( |     // FfiResultVoid_t sync_wallet ( | ||||||
|     //    OpaqueWallet_t const * opaque_wallet); |     //    OpaqueWallet_t const * opaque_wallet); | ||||||
| @ -248,6 +273,10 @@ interface LibJna : Library { | |||||||
|     //    OpaqueWallet_t const * opaque_wallet); |     //    OpaqueWallet_t const * opaque_wallet); | ||||||
|     fun list_unspent(opaque_wallet: OpaqueWallet_t): FfiResultVec_LocalUtxo_t.ByValue |     fun list_unspent(opaque_wallet: OpaqueWallet_t): FfiResultVec_LocalUtxo_t.ByValue | ||||||
| 
 | 
 | ||||||
|  |     // FfiResult_uint64_t balance ( | ||||||
|  |     //    OpaqueWallet_t const * opaque_wallet); | ||||||
|  |     fun balance(opaque_wallet: OpaqueWallet_t): FfiResult_uint64_t.ByValue | ||||||
|  |      | ||||||
|     // DatabaseConfig_t * new_memory_config (void); |     // DatabaseConfig_t * new_memory_config (void); | ||||||
|     fun new_memory_config(): DatabaseConfig_t |     fun new_memory_config(): DatabaseConfig_t | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -0,0 +1,31 @@ | |||||||
|  | package org.bitcoindevkit.bdk.types | ||||||
|  | 
 | ||||||
|  | import org.bitcoindevkit.bdk.FfiException | ||||||
|  | import org.bitcoindevkit.bdk.LibBase | ||||||
|  | import org.bitcoindevkit.bdk.LibJna | ||||||
|  | import org.slf4j.Logger | ||||||
|  | import org.slf4j.LoggerFactory | ||||||
|  | 
 | ||||||
|  | class UInt64Result constructor(private val ffiResultUint64T: LibJna.FfiResult_uint64_t.ByValue) : | ||||||
|  |     LibBase() { | ||||||
|  | 
 | ||||||
|  |     private val log: Logger = LoggerFactory.getLogger(UInt64Result::class.java) | ||||||
|  | 
 | ||||||
|  |     fun value(): Long { | ||||||
|  |         val err = ffiResultUint64T.err | ||||||
|  |         val ok = ffiResultUint64T.ok | ||||||
|  |         when { | ||||||
|  |             err > 0 -> { | ||||||
|  |                 throw FfiException(err) | ||||||
|  |             } | ||||||
|  |             else -> { | ||||||
|  |                 return ok | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected fun finalize() { | ||||||
|  |         libJna.free_uint64_result(ffiResultUint64T) | ||||||
|  |         log.debug("$ffiResultUint64T freed") | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -26,7 +26,7 @@ class VecLocalUtxoResult(private val ffiResultVecLocalUtxoT: LibJna.FfiResultVec | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected fun finalize() { |     protected fun finalize() { | ||||||
|         libJna.free_unspent_result(ffiResultVecLocalUtxoT) |         libJna.free_veclocalutxo_result(ffiResultVecLocalUtxoT) | ||||||
|         log.debug("$ffiResultVecLocalUtxoT freed") |         log.debug("$ffiResultVecLocalUtxoT freed") | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -5,6 +5,7 @@ import org.bitcoindevkit.bdk.DatabaseConfig | |||||||
| import org.bitcoindevkit.bdk.LibBase | import org.bitcoindevkit.bdk.LibBase | ||||||
| import org.bitcoindevkit.bdk.LibJna | import org.bitcoindevkit.bdk.LibJna | ||||||
| import org.bitcoindevkit.bdk.types.StringResult | import org.bitcoindevkit.bdk.types.StringResult | ||||||
|  | import org.bitcoindevkit.bdk.types.UInt64Result | ||||||
| import org.bitcoindevkit.bdk.types.VoidResult | import org.bitcoindevkit.bdk.types.VoidResult | ||||||
| import org.slf4j.Logger | import org.slf4j.Logger | ||||||
| import org.slf4j.LoggerFactory | import org.slf4j.LoggerFactory | ||||||
| @ -42,4 +43,9 @@ class Wallet constructor( | |||||||
|         val vecLocalUtxoResult = VecLocalUtxoResult(libJna.list_unspent(wallet)) |         val vecLocalUtxoResult = VecLocalUtxoResult(libJna.list_unspent(wallet)) | ||||||
|         return vecLocalUtxoResult.value() |         return vecLocalUtxoResult.value() | ||||||
|     } |     } | ||||||
|  |      | ||||||
|  |     fun balance(): Long { | ||||||
|  |         val longResult = UInt64Result(libJna.balance(wallet)) | ||||||
|  |         return longResult.value() | ||||||
|  |     } | ||||||
| } | } | ||||||
| @ -96,4 +96,13 @@ abstract class LibTest : LibBase() { | |||||||
|             assertTrue(it.keychain!! >= 0) |             assertTrue(it.keychain!! >= 0) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     fun walletBalance() { | ||||||
|  |         val wallet = Wallet(desc, change, blockchainConfig, databaseConfig) | ||||||
|  |         wallet.sync() | ||||||
|  |         val balance = wallet.balance() | ||||||
|  |         //log.debug("balance from kotlin: $balance") | ||||||
|  |         assertTrue(balance > 0) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										98
									
								
								cc/bdk_ffi.h
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								cc/bdk_ffi.h
									
									
									
									
									
								
							| @ -14,6 +14,12 @@ | |||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | typedef struct BlockchainConfig BlockchainConfig_t; | ||||||
|  | 
 | ||||||
|  | typedef struct DatabaseConfig DatabaseConfig_t; | ||||||
|  | 
 | ||||||
|  | typedef struct OpaqueWallet OpaqueWallet_t; | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| #include <stddef.h> | #include <stddef.h> | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| @ -107,47 +113,6 @@ FfiError_t | |||||||
| #endif | #endif | ||||||
| ; | ; | ||||||
| 
 | 
 | ||||||
| typedef struct { |  | ||||||
| 
 |  | ||||||
|     char * ok; |  | ||||||
| 
 |  | ||||||
|     FfiError_t err; |  | ||||||
| 
 |  | ||||||
| } FfiResult_char_ptr_t; |  | ||||||
| 
 |  | ||||||
| void free_string_result ( |  | ||||||
|     FfiResult_char_ptr_t string_result); |  | ||||||
| 
 |  | ||||||
| typedef struct { |  | ||||||
| 
 |  | ||||||
|     FfiError_t err; |  | ||||||
| 
 |  | ||||||
| } FfiResultVoid_t; |  | ||||||
| 
 |  | ||||||
| void free_void_result ( |  | ||||||
|     FfiResultVoid_t void_result); |  | ||||||
| 
 |  | ||||||
| /** \brief
 |  | ||||||
|  *  Free a Rust-allocated string |  | ||||||
|  */ |  | ||||||
| void free_string ( |  | ||||||
|     char * string); |  | ||||||
| 
 |  | ||||||
| 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 { | typedef struct { | ||||||
| 
 | 
 | ||||||
|     OpaqueWallet_t * ok; |     OpaqueWallet_t * ok; | ||||||
| @ -165,9 +130,23 @@ FfiResult_OpaqueWallet_ptr_t new_wallet_result ( | |||||||
| void free_wallet_result ( | void free_wallet_result ( | ||||||
|     FfiResult_OpaqueWallet_ptr_t wallet_result); |     FfiResult_OpaqueWallet_ptr_t wallet_result); | ||||||
| 
 | 
 | ||||||
|  | typedef struct { | ||||||
|  | 
 | ||||||
|  |     FfiError_t err; | ||||||
|  | 
 | ||||||
|  | } FfiResultVoid_t; | ||||||
|  | 
 | ||||||
| FfiResultVoid_t sync_wallet ( | FfiResultVoid_t sync_wallet ( | ||||||
|     OpaqueWallet_t const * opaque_wallet); |     OpaqueWallet_t const * opaque_wallet); | ||||||
| 
 | 
 | ||||||
|  | typedef struct { | ||||||
|  | 
 | ||||||
|  |     char * ok; | ||||||
|  | 
 | ||||||
|  |     FfiError_t err; | ||||||
|  | 
 | ||||||
|  | } FfiResult_char_ptr_t; | ||||||
|  | 
 | ||||||
| FfiResult_char_ptr_t new_address ( | FfiResult_char_ptr_t new_address ( | ||||||
|     OpaqueWallet_t const * opaque_wallet); |     OpaqueWallet_t const * opaque_wallet); | ||||||
| 
 | 
 | ||||||
| @ -221,9 +200,44 @@ typedef struct { | |||||||
| FfiResult_Vec_LocalUtxo_t list_unspent ( | FfiResult_Vec_LocalUtxo_t list_unspent ( | ||||||
|     OpaqueWallet_t const * opaque_wallet); |     OpaqueWallet_t const * opaque_wallet); | ||||||
| 
 | 
 | ||||||
| void free_unspent_result ( | void free_veclocalutxo_result ( | ||||||
|     FfiResult_Vec_LocalUtxo_t unspent_result); |     FfiResult_Vec_LocalUtxo_t unspent_result); | ||||||
| 
 | 
 | ||||||
|  | typedef struct { | ||||||
|  | 
 | ||||||
|  |     uint64_t ok; | ||||||
|  | 
 | ||||||
|  |     FfiError_t err; | ||||||
|  | 
 | ||||||
|  | } FfiResult_uint64_t; | ||||||
|  | 
 | ||||||
|  | FfiResult_uint64_t balance ( | ||||||
|  |     OpaqueWallet_t const * opaque_wallet); | ||||||
|  | 
 | ||||||
|  | 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); | ||||||
|  | 
 | ||||||
|  | void free_string_result ( | ||||||
|  |     FfiResult_char_ptr_t string_result); | ||||||
|  | 
 | ||||||
|  | void free_void_result ( | ||||||
|  |     FfiResultVoid_t void_result); | ||||||
|  | 
 | ||||||
|  | void free_uint64_result ( | ||||||
|  |     FfiResult_uint64_t void_result); | ||||||
|  | 
 | ||||||
|  | /** \brief
 | ||||||
|  |  *  Free a Rust-allocated string | ||||||
|  |  */ | ||||||
|  | void free_string ( | ||||||
|  |     char * string); | ||||||
|  | 
 | ||||||
| DatabaseConfig_t * new_memory_config (void); | DatabaseConfig_t * new_memory_config (void); | ||||||
| 
 | 
 | ||||||
| DatabaseConfig_t * new_sled_config ( | DatabaseConfig_t * new_sled_config ( | ||||||
|  | |||||||
| @ -114,12 +114,12 @@ int main (int argc, char const * const argv[]) | |||||||
|             assert(unspent_ptr[i].keychain >= 0); |             assert(unspent_ptr[i].keychain >= 0); | ||||||
|         } |         } | ||||||
|          |          | ||||||
|         free_unspent_result(unspent_result);           |         free_veclocalutxo_result(unspent_result);           | ||||||
|         free_wallet_result(wallet_result); |         free_wallet_result(wallet_result); | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     // test balance 
 |     // test balance 
 | ||||||
|     /*{
 |     { | ||||||
|         char const *desc = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)"; |         char const *desc = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)"; | ||||||
|         char const *change = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"; |         char const *change = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"; | ||||||
|      |      | ||||||
| @ -128,7 +128,7 @@ int main (int argc, char const * const argv[]) | |||||||
|      |      | ||||||
|         // new wallet
 |         // new wallet
 | ||||||
|         FfiResult_OpaqueWallet_ptr_t wallet_result = new_wallet_result(desc,change,bc_config,db_config); |         FfiResult_OpaqueWallet_ptr_t wallet_result = new_wallet_result(desc,change,bc_config,db_config); | ||||||
|         assert(wallet_result.err == NULL);     |         assert(wallet_result.err == FFI_ERROR_NONE);     | ||||||
|         assert(wallet_result.ok != NULL); |         assert(wallet_result.ok != NULL); | ||||||
|          |          | ||||||
|         free_blockchain_config(bc_config); |         free_blockchain_config(bc_config); | ||||||
| @ -138,19 +138,20 @@ int main (int argc, char const * const argv[]) | |||||||
|          |          | ||||||
|         // sync wallet
 |         // sync wallet
 | ||||||
|         FfiResultVoid_t sync_result = sync_wallet(wallet);    |         FfiResultVoid_t sync_result = sync_wallet(wallet);    | ||||||
|         assert(sync_result.err == NULL);     |         assert(sync_result.err == FFI_ERROR_NONE);     | ||||||
|         free_void_result(sync_result); |         free_void_result(sync_result); | ||||||
|          |          | ||||||
|         // get balance
 |         // get balance
 | ||||||
|         FfiResultT_uint64_t balance_result = balance(wallet); |         FfiResult_uint64_t balance_result = balance(wallet); | ||||||
|         assert(balance_result.err == NULL);   |         //printf("balance.err = %d\n", (balance_result.err));
 | ||||||
|         printf("balance = %lu\n", balance_result.ok); |         assert(balance_result.err == FFI_ERROR_NONE);           | ||||||
|  |         //printf("balance.ok = %ld\n", balance_result.ok);                
 | ||||||
|         assert(balance_result.ok > 0);   |         assert(balance_result.ok > 0);   | ||||||
|          |          | ||||||
|         // free balance and wallet results
 |         // free balance and wallet results
 | ||||||
|         free_u64_result(balance_result); |         free_uint64_result(balance_result); | ||||||
|         free_wallet_result(wallet_result); |         free_wallet_result(wallet_result); | ||||||
|     }*/ |     } | ||||||
|          |          | ||||||
|     return EXIT_SUCCESS; |     return EXIT_SUCCESS; | ||||||
| } | } | ||||||
|  | |||||||
| @ -27,6 +27,11 @@ fn free_void_result(void_result: FfiResultVoid) { | |||||||
|     drop(void_result) |     drop(void_result) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[ffi_export] | ||||||
|  | fn free_uint64_result(void_result: FfiResult<u64>) { | ||||||
|  |     drop(void_result) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // TODO do we need this? remove?
 | // TODO do we need this? remove?
 | ||||||
| /// Free a Rust-allocated string
 | /// Free a Rust-allocated string
 | ||||||
| #[ffi_export] | #[ffi_export] | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| use std::convert::TryFrom; | use std::convert::TryFrom; | ||||||
|  | use std::ffi::CString; | ||||||
| 
 | 
 | ||||||
| use ::safer_ffi::prelude::*; | use ::safer_ffi::prelude::*; | ||||||
| use bdk::bitcoin::network::constants::Network::Testnet; | use bdk::bitcoin::network::constants::Network::Testnet; | ||||||
| @ -14,7 +15,6 @@ use database::DatabaseConfig; | |||||||
| 
 | 
 | ||||||
| use crate::error::FfiError; | use crate::error::FfiError; | ||||||
| use crate::types::{FfiResult, FfiResultVoid}; | use crate::types::{FfiResult, FfiResultVoid}; | ||||||
| use std::ffi::CString; |  | ||||||
| 
 | 
 | ||||||
| mod blockchain; | mod blockchain; | ||||||
| mod database; | mod database; | ||||||
| @ -125,10 +125,26 @@ fn list_unspent(opaque_wallet: &OpaqueWallet) -> FfiResult<repr_c::Vec<LocalUtxo | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[ffi_export] | #[ffi_export] | ||||||
| fn free_unspent_result(unspent_result: FfiResult<repr_c::Vec<LocalUtxo>>) { | fn free_veclocalutxo_result(unspent_result: FfiResult<repr_c::Vec<LocalUtxo>>) { | ||||||
|     drop(unspent_result) |     drop(unspent_result) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #[ffi_export] | ||||||
|  | fn balance(opaque_wallet: &OpaqueWallet) -> FfiResult<u64> { | ||||||
|  |     let balance_result = opaque_wallet.raw.get_balance(); | ||||||
|  | 
 | ||||||
|  |     match balance_result { | ||||||
|  |         Ok(b) => FfiResult { | ||||||
|  |             ok: b, | ||||||
|  |             err: FfiError::None, | ||||||
|  |         }, | ||||||
|  |         Err(e) => FfiResult { | ||||||
|  |             ok: u64::MIN, | ||||||
|  |             err: FfiError::from(&e), | ||||||
|  |         }, | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // Non-opaque returned values
 | // Non-opaque returned values
 | ||||||
| 
 | 
 | ||||||
| #[derive_ReprC] | #[derive_ReprC] | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user