Add Wallet.balance()
This commit is contained in:
parent
adadcbc982
commit
cd813a14b1
@ -232,10 +232,35 @@ 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);
|
||||||
fun sync_wallet(opaque_wallet: OpaqueWallet_t): FfiResultVoid_t.ByValue
|
fun sync_wallet(opaque_wallet: OpaqueWallet_t): FfiResultVoid_t.ByValue
|
||||||
@ -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