Remove unneeded test structs and functions, cleanup tests
This commit is contained in:
parent
a5ad4cd0a5
commit
a37bae5b9d
@ -1,65 +1,36 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include "bdk_ffi.h"
|
#include "bdk_ffi.h"
|
||||||
|
|
||||||
int main (int argc, char const * const argv[])
|
int main (int argc, char const * const argv[])
|
||||||
{
|
{
|
||||||
// test print_string
|
|
||||||
print_string("hello 123");
|
|
||||||
|
|
||||||
// test concat_string
|
|
||||||
char const * string1 = "string1";
|
|
||||||
char const * string2 = "string2";
|
|
||||||
char * string3 = concat_string(string1, string2);
|
|
||||||
print_string(string3);
|
|
||||||
free_string(string3);
|
|
||||||
// verify free_string after free_string fails
|
|
||||||
////free_string(string3);
|
|
||||||
|
|
||||||
// test print_config with c created config
|
|
||||||
Config_t config1 = { .name = "test", .count = 101 };
|
|
||||||
print_config(&config1);
|
|
||||||
|
|
||||||
// test new_config
|
|
||||||
Config_t * config2 = new_config("test test", 202);
|
|
||||||
print_config(config2);
|
|
||||||
|
|
||||||
// test free_config
|
|
||||||
free_config(config2);
|
|
||||||
// verify print_config after free_config fails (invalid data)
|
|
||||||
////print_config(config2);
|
|
||||||
// verify free_config after free_config fails (double free detected, core dumped)
|
|
||||||
////free_config(config2);
|
|
||||||
|
|
||||||
char const * name = "test_wallet";
|
char const * name = "test_wallet";
|
||||||
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/*)";
|
||||||
//char const * change = NULL;
|
|
||||||
|
|
||||||
// test new_wallet
|
// test new_wallet
|
||||||
{
|
{
|
||||||
WalletPtr_t * wallet = new_wallet(name, desc, change);
|
WalletPtr_t * wallet = new_wallet(name, desc, change);
|
||||||
|
assert(wallet != NULL);
|
||||||
|
|
||||||
// test sync_wallet
|
// test sync_wallet
|
||||||
sync_wallet(wallet);
|
sync_wallet(wallet);
|
||||||
printf("after sync_wallet\n");
|
|
||||||
sync_wallet(wallet);
|
|
||||||
printf("after sync_wallet\n");
|
|
||||||
|
|
||||||
// test new_address
|
// test new_address
|
||||||
char * address1 = new_address(wallet);
|
char * address1 = new_address(wallet);
|
||||||
printf("address1: %s\n", address1);
|
//printf("address1: %s\n", address1);
|
||||||
|
assert( 0 == strcmp(address1,"tb1qgkhp034fyxeta00h0nne9tzfm0vsxq4prduzxp"));
|
||||||
free_string(address1);
|
free_string(address1);
|
||||||
assert(address1 != NULL);
|
|
||||||
char * address2 = new_address(wallet);
|
char * address2 = new_address(wallet);
|
||||||
printf("address2: %s\n", address2);
|
//printf("address2: %s\n", address2);
|
||||||
assert(address2 != NULL);
|
assert(0 == strcmp(address2,"tb1qd6u9q327sru2ljvwzdtfrdg36sapax7udz97wf"));
|
||||||
free_string(address2);
|
free_string(address2);
|
||||||
|
|
||||||
// test free_wallet
|
// test free_wallet
|
||||||
free_wallet(wallet);
|
free_wallet(wallet);
|
||||||
printf("after free_wallet\n");
|
|
||||||
|
|
||||||
// test free_wallet NULL doesn't crash
|
// test free_wallet NULL doesn't crash
|
||||||
free_wallet(NULL);
|
free_wallet(NULL);
|
||||||
|
@ -30,7 +30,7 @@ dependencies {
|
|||||||
publishing {
|
publishing {
|
||||||
publications {
|
publications {
|
||||||
maven(MavenPublication) {
|
maven(MavenPublication) {
|
||||||
groupId = 'org.bitcoindevkit.bdkjni'
|
groupId = 'org.bitcoindevkit.bdkffi'
|
||||||
artifactId = 'bdk-jvm-debug'
|
artifactId = 'bdk-jvm-debug'
|
||||||
version = '0.2.1-dev'
|
version = '0.2.1-dev'
|
||||||
|
|
||||||
|
36
jvm/src/main/java/org/bitcoindevkit/bdkffi/Lib.kt
Normal file
36
jvm/src/main/java/org/bitcoindevkit/bdkffi/Lib.kt
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package org.bitcoindevkit.bdkjni
|
||||||
|
|
||||||
|
import com.sun.jna.*
|
||||||
|
import com.sun.jna.ptr.PointerByReference
|
||||||
|
|
||||||
|
interface Lib : Library {
|
||||||
|
|
||||||
|
// typedef struct WalletPtr WalletPtr_t;
|
||||||
|
class WalletPtr_t : PointerType {
|
||||||
|
constructor(): super()
|
||||||
|
constructor(pointer: Pointer): super(pointer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// void free_string (
|
||||||
|
// char * string);
|
||||||
|
fun free_string(string: String)
|
||||||
|
|
||||||
|
// WalletPtr_t * new_wallet (
|
||||||
|
// char const * name,
|
||||||
|
// char const * descriptor,
|
||||||
|
// char const * change_descriptor);
|
||||||
|
fun new_wallet(name: String, descriptor: String, changeDescriptor: String?): WalletPtr_t
|
||||||
|
|
||||||
|
// void sync_wallet (
|
||||||
|
// WalletPtr_t * const * wallet);
|
||||||
|
//fun sync_wallet(wallet: WalletPtr_t)
|
||||||
|
fun sync_wallet(wallet: WalletPtr_t)
|
||||||
|
|
||||||
|
// char * new_address (
|
||||||
|
// WalletPtr_t * const * wallet);
|
||||||
|
fun new_address(wallet: WalletPtr_t): String
|
||||||
|
|
||||||
|
// void free_wallet (
|
||||||
|
// WalletPtr_t * wallet);
|
||||||
|
fun free_wallet(wallet: WalletPtr_t)
|
||||||
|
}
|
@ -1,73 +0,0 @@
|
|||||||
package org.bitcoindevkit.bdkjni
|
|
||||||
|
|
||||||
import com.sun.jna.*
|
|
||||||
import com.sun.jna.ptr.PointerByReference
|
|
||||||
|
|
||||||
// typedef struct {
|
|
||||||
//
|
|
||||||
// char * name;
|
|
||||||
//
|
|
||||||
// int32_t count;
|
|
||||||
//
|
|
||||||
// } Config_t;
|
|
||||||
@Structure.FieldOrder("name", "count")
|
|
||||||
class Config_t : Structure() {
|
|
||||||
@JvmField
|
|
||||||
var name: String? = null
|
|
||||||
@JvmField
|
|
||||||
var count: NativeLong? = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// typedef struct WalletPtr WalletPtr_t;
|
|
||||||
class WalletPtr_t : PointerType {
|
|
||||||
constructor(): super()
|
|
||||||
constructor(pointer: Pointer): super(pointer)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Lib : Library {
|
|
||||||
|
|
||||||
// void print_string (
|
|
||||||
// char const * string);
|
|
||||||
fun print_string(name: String)
|
|
||||||
|
|
||||||
// char * concat_string (
|
|
||||||
// char const * fst,
|
|
||||||
// char const * snd);
|
|
||||||
fun concat_string(fst: String, snd: String): String
|
|
||||||
|
|
||||||
// void free_string (
|
|
||||||
// char * string);
|
|
||||||
fun free_string(string: String)
|
|
||||||
|
|
||||||
// void print_config (
|
|
||||||
// Config_t const * config);
|
|
||||||
fun print_config(config: Config_t)
|
|
||||||
|
|
||||||
// Config_t new_config (
|
|
||||||
// char * name,
|
|
||||||
// int32_t count);
|
|
||||||
fun new_config(name: String, count: NativeLong): Config_t
|
|
||||||
|
|
||||||
// void free_config (
|
|
||||||
// Config_t * config);
|
|
||||||
fun free_config(config: Config_t)
|
|
||||||
|
|
||||||
// WalletPtr_t * new_wallet (
|
|
||||||
// char const * name,
|
|
||||||
// char const * descriptor,
|
|
||||||
// char const * change_descriptor);
|
|
||||||
fun new_wallet(name: String, descriptor: String, changeDescriptor: String?): WalletPtr_t
|
|
||||||
|
|
||||||
// void sync_wallet (
|
|
||||||
// WalletPtr_t * const * wallet);
|
|
||||||
//fun sync_wallet(wallet: WalletPtr_t)
|
|
||||||
fun sync_wallet(wallet: WalletPtr_t)
|
|
||||||
|
|
||||||
// char * new_address (
|
|
||||||
// WalletPtr_t * const * wallet);
|
|
||||||
fun new_address(wallet: WalletPtr_t): String
|
|
||||||
|
|
||||||
// void free_wallet (
|
|
||||||
// WalletPtr_t * wallet);
|
|
||||||
fun free_wallet(wallet: WalletPtr_t)
|
|
||||||
}
|
|
40
jvm/src/test/java/org/bitcoindevkit/bdkffi/LibTest.kt
Normal file
40
jvm/src/test/java/org/bitcoindevkit/bdkffi/LibTest.kt
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package org.bitcoindevkit.bdkjni
|
||||||
|
|
||||||
|
import com.sun.jna.Native
|
||||||
|
import com.sun.jna.NativeLong
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Library test, which will execute on linux host.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class LibTest {
|
||||||
|
|
||||||
|
private val bdkFfi: Lib = Native.load("bdk_ffi", Lib::class.java)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun new_sync_free_wallet() {
|
||||||
|
val name = "test_wallet"
|
||||||
|
val desc = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)"
|
||||||
|
val change = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"
|
||||||
|
|
||||||
|
val wallet = bdkFfi.new_wallet(name, desc, change)
|
||||||
|
bdkFfi.sync_wallet(wallet)
|
||||||
|
bdkFfi.free_wallet(wallet)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun new_newaddress_wallet() {
|
||||||
|
val name = "test_wallet"
|
||||||
|
val desc = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)"
|
||||||
|
val change = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"
|
||||||
|
|
||||||
|
val wallet = bdkFfi.new_wallet(name, desc, change)
|
||||||
|
val address = bdkFfi.new_address(wallet)
|
||||||
|
//println("address created from kotlin: $address")
|
||||||
|
assertEquals(address, "tb1qzg4mckdh50nwdm9hkzq06528rsu73hjxxzem3e")
|
||||||
|
bdkFfi.free_string(address)
|
||||||
|
bdkFfi.free_wallet(wallet)
|
||||||
|
}
|
||||||
|
}
|
@ -1,66 +0,0 @@
|
|||||||
package org.bitcoindevkit.bdkjni
|
|
||||||
|
|
||||||
import com.sun.jna.Native
|
|
||||||
import com.sun.jna.NativeLong
|
|
||||||
import org.junit.Test
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Library test, which will execute on linux host.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class LibTest {
|
|
||||||
|
|
||||||
private val lib: Lib = Native.load("bdk_ffi", Lib::class.java)
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun print_string() {
|
|
||||||
lib.print_string("hello print string")
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun concat_print_free_string() {
|
|
||||||
val concat = lib.concat_string("hello", "concat")
|
|
||||||
lib.print_string(concat)
|
|
||||||
lib.free_string(concat)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun print_free_config() {
|
|
||||||
val config = Config_t()
|
|
||||||
config.name = "test"
|
|
||||||
config.count = NativeLong(101)
|
|
||||||
lib.print_config(config)
|
|
||||||
lib.free_config(config)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun new_print_free_config() {
|
|
||||||
println("Long max value = ${Long.MAX_VALUE}")
|
|
||||||
val config = lib.new_config("test test", NativeLong(Long.MAX_VALUE))
|
|
||||||
lib.print_config(config)
|
|
||||||
lib.free_config(config)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun new_sync_free_wallet() {
|
|
||||||
val name = "test_wallet"
|
|
||||||
val desc = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)"
|
|
||||||
val change = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"
|
|
||||||
|
|
||||||
val wallet = lib.new_wallet(name, desc, change)
|
|
||||||
lib.sync_wallet(wallet)
|
|
||||||
lib.free_wallet(wallet)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun new_newaddress_wallet() {
|
|
||||||
val name = "test_wallet"
|
|
||||||
val desc = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)"
|
|
||||||
val change = "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/1/*)"
|
|
||||||
|
|
||||||
val wallet = lib.new_wallet(name, desc, change)
|
|
||||||
val address = lib.new_address(wallet)
|
|
||||||
println("address created from kotlin: $address")
|
|
||||||
lib.free_wallet(wallet)
|
|
||||||
}
|
|
||||||
}
|
|
127
src/lib.rs
127
src/lib.rs
@ -1,131 +1,6 @@
|
|||||||
#![deny(unsafe_code)] /* No `unsafe` needed! */
|
#![deny(unsafe_code)] /* No `unsafe` needed! */
|
||||||
|
|
||||||
use ::safer_ffi::prelude::*;
|
mod wallet;
|
||||||
use bdk::bitcoin::network::constants::Network::Testnet;
|
|
||||||
use bdk::blockchain::{ElectrumBlockchain, log_progress};
|
|
||||||
use bdk::electrum_client::Client;
|
|
||||||
use bdk::sled;
|
|
||||||
use bdk::sled::Tree;
|
|
||||||
use bdk::Wallet;
|
|
||||||
use bdk::wallet::AddressIndex::New;
|
|
||||||
use safer_ffi::char_p::{char_p_ref, char_p_boxed};
|
|
||||||
use safer_ffi::boxed::Box;
|
|
||||||
|
|
||||||
#[ffi_export]
|
|
||||||
fn print_string (string: char_p_ref)
|
|
||||||
{
|
|
||||||
println!("{}", string);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Concatenate two input UTF-8 (_e.g._, ASCII) strings.
|
|
||||||
///
|
|
||||||
/// The returned string must be freed with `rust_free_string`
|
|
||||||
#[ffi_export]
|
|
||||||
fn concat_string(fst: char_p_ref, snd: char_p_ref)
|
|
||||||
-> char_p_boxed
|
|
||||||
{
|
|
||||||
let fst = fst.to_str(); // : &'_ str
|
|
||||||
let snd = snd.to_str(); // : &'_ str
|
|
||||||
let ccat = format!("{}{}", fst, snd).try_into().unwrap();
|
|
||||||
ccat
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Frees a Rust-allocated string
|
|
||||||
#[ffi_export]
|
|
||||||
fn free_string (string: char_p_boxed)
|
|
||||||
{
|
|
||||||
drop(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A `struct` usable from both Rust and C
|
|
||||||
#[derive_ReprC]
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Config {
|
|
||||||
name: char_p_boxed,
|
|
||||||
count: i64
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Debug print a Point
|
|
||||||
#[ffi_export]
|
|
||||||
fn print_config(config: &Config) {
|
|
||||||
println!("{:?}", config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new Config
|
|
||||||
#[ffi_export]
|
|
||||||
fn new_config(name: char_p_ref, count: i64) -> Box<Config> {
|
|
||||||
let name = name.to_string().try_into().unwrap();
|
|
||||||
Box::new(Config { name, count })
|
|
||||||
}
|
|
||||||
|
|
||||||
#[ffi_export]
|
|
||||||
fn free_config(config: Box<Config>) {
|
|
||||||
drop(config)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive_ReprC]
|
|
||||||
#[ReprC::opaque]
|
|
||||||
pub struct WalletPtr {
|
|
||||||
raw: Wallet<ElectrumBlockchain, Tree>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Wallet<ElectrumBlockchain, Tree>> for WalletPtr {
|
|
||||||
fn from(wallet: Wallet<ElectrumBlockchain, Tree>) -> Self {
|
|
||||||
WalletPtr {
|
|
||||||
raw: wallet,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[ffi_export]
|
|
||||||
fn new_wallet(
|
|
||||||
name: char_p_ref,
|
|
||||||
descriptor: char_p_ref,
|
|
||||||
change_descriptor: Option<char_p_ref>,
|
|
||||||
) -> Box<WalletPtr> {
|
|
||||||
let name = name.to_string();
|
|
||||||
let descriptor = descriptor.to_string();
|
|
||||||
let change_descriptor = change_descriptor.map(|s| s.to_string());
|
|
||||||
|
|
||||||
let database = sled::open("./wallet_db").unwrap();
|
|
||||||
let tree = database.open_tree(name.clone()).unwrap();
|
|
||||||
|
|
||||||
let descriptor: &str = descriptor.as_str();
|
|
||||||
let change_descriptor: Option<&str> = change_descriptor.as_deref();
|
|
||||||
|
|
||||||
let electrum_url = "ssl://electrum.blockstream.info:60002";
|
|
||||||
let client = Client::new(&electrum_url).unwrap();
|
|
||||||
|
|
||||||
let wallet = Wallet::new(
|
|
||||||
descriptor,
|
|
||||||
change_descriptor,
|
|
||||||
Testnet,
|
|
||||||
tree,
|
|
||||||
ElectrumBlockchain::from(client),
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
println!("created wallet");
|
|
||||||
Box::new(WalletPtr::from(wallet))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[ffi_export]
|
|
||||||
fn sync_wallet( wallet: &WalletPtr) {
|
|
||||||
let _r = wallet.raw.sync(log_progress(), Some(100));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[ffi_export]
|
|
||||||
fn new_address( wallet: &WalletPtr) -> char_p_boxed {
|
|
||||||
let new_address = wallet.raw.get_address(New);
|
|
||||||
let new_address = new_address.unwrap();
|
|
||||||
let new_address = new_address.to_string();
|
|
||||||
new_address.try_into().unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[ffi_export]
|
|
||||||
fn free_wallet( wallet: Option<Box<WalletPtr>>) {
|
|
||||||
drop(wallet)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The following test function is necessary for the header generation.
|
/// The following test function is necessary for the header generation.
|
||||||
#[::safer_ffi::cfg_headers]
|
#[::safer_ffi::cfg_headers]
|
||||||
|
78
src/wallet.rs
Normal file
78
src/wallet.rs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
use ::safer_ffi::prelude::*;
|
||||||
|
use bdk::bitcoin::network::constants::Network::Testnet;
|
||||||
|
use bdk::blockchain::{
|
||||||
|
log_progress, AnyBlockchain, AnyBlockchainConfig, ConfigurableBlockchain,
|
||||||
|
ElectrumBlockchainConfig,
|
||||||
|
};
|
||||||
|
use bdk::database::{AnyDatabase, AnyDatabaseConfig, ConfigurableDatabase};
|
||||||
|
use bdk::wallet::AddressIndex::New;
|
||||||
|
use bdk::Wallet;
|
||||||
|
use safer_ffi::boxed::Box;
|
||||||
|
use safer_ffi::char_p::{char_p_boxed, char_p_ref};
|
||||||
|
|
||||||
|
#[derive_ReprC]
|
||||||
|
#[ReprC::opaque]
|
||||||
|
pub struct WalletPtr {
|
||||||
|
raw: Wallet<AnyBlockchain, AnyDatabase>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Wallet<AnyBlockchain, AnyDatabase>> for WalletPtr {
|
||||||
|
fn from(wallet: Wallet<AnyBlockchain, AnyDatabase>) -> Self {
|
||||||
|
WalletPtr { raw: wallet }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffi_export]
|
||||||
|
fn new_wallet(
|
||||||
|
name: char_p_ref,
|
||||||
|
descriptor: char_p_ref,
|
||||||
|
change_descriptor: Option<char_p_ref>,
|
||||||
|
) -> Box<WalletPtr> {
|
||||||
|
let network = Testnet;
|
||||||
|
let _name = name.to_string();
|
||||||
|
let descriptor = descriptor.to_string();
|
||||||
|
let change_descriptor = change_descriptor.map(|s| s.to_string());
|
||||||
|
|
||||||
|
let electrum_config = AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
|
||||||
|
url: "ssl://electrum.blockstream.info:60002".to_string(),
|
||||||
|
socks5: None,
|
||||||
|
retry: 5,
|
||||||
|
timeout: None,
|
||||||
|
});
|
||||||
|
let blockchain_config = electrum_config;
|
||||||
|
let client = AnyBlockchain::from_config(&blockchain_config).unwrap();
|
||||||
|
|
||||||
|
let database_config = AnyDatabaseConfig::Memory(());
|
||||||
|
let database = AnyDatabase::from_config(&database_config).unwrap();
|
||||||
|
|
||||||
|
let descriptor: &str = descriptor.as_str();
|
||||||
|
let change_descriptor: Option<&str> = change_descriptor.as_deref();
|
||||||
|
|
||||||
|
let wallet = Wallet::new(descriptor, change_descriptor, network, database, client).unwrap();
|
||||||
|
|
||||||
|
Box::new(WalletPtr::from(wallet))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffi_export]
|
||||||
|
fn sync_wallet(wallet: &WalletPtr) {
|
||||||
|
let _r = wallet.raw.sync(log_progress(), Some(100));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffi_export]
|
||||||
|
fn new_address(wallet: &WalletPtr) -> char_p_boxed {
|
||||||
|
let new_address = wallet.raw.get_address(New);
|
||||||
|
let new_address = new_address.unwrap();
|
||||||
|
let new_address = new_address.to_string();
|
||||||
|
new_address.try_into().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Frees a Rust-allocated string
|
||||||
|
#[ffi_export]
|
||||||
|
fn free_string(string: char_p_boxed) {
|
||||||
|
drop(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffi_export]
|
||||||
|
fn free_wallet(wallet: Option<Box<WalletPtr>>) {
|
||||||
|
drop(wallet)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user