Return results as opaque structs from ffi calls
This commit is contained in:
parent
76087b9aec
commit
f6c10da805
70
build.sh
70
build.sh
@ -15,38 +15,38 @@ cp target/debug/libbdk_ffi.so bdk-kotlin/jar/libs/x86_64_linux
|
|||||||
|
|
||||||
(cd bdk-kotlin && gradle :jar:build)
|
(cd bdk-kotlin && gradle :jar:build)
|
||||||
|
|
||||||
# rust android
|
## rust android
|
||||||
|
#
|
||||||
# If ANDROID_NDK_HOME is not set then set it to github actions default
|
## If ANDROID_NDK_HOME is not set then set it to github actions default
|
||||||
[ -z "$ANDROID_NDK_HOME" ] && export ANDROID_NDK_HOME=$ANDROID_HOME/ndk-bundle
|
#[ -z "$ANDROID_NDK_HOME" ] && export ANDROID_NDK_HOME=$ANDROID_HOME/ndk-bundle
|
||||||
|
#
|
||||||
# Update this line accordingly if you are not building *from* darwin-x86_64 or linux-x86_64
|
## Update this line accordingly if you are not building *from* darwin-x86_64 or linux-x86_64
|
||||||
export PATH=$PATH:$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/`uname | tr '[:upper:]' '[:lower:]'`-x86_64/bin
|
#export PATH=$PATH:$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/`uname | tr '[:upper:]' '[:lower:]'`-x86_64/bin
|
||||||
|
#
|
||||||
# Required for 'ring' dependency to cross-compile to Android platform, must be at least 21
|
## Required for 'ring' dependency to cross-compile to Android platform, must be at least 21
|
||||||
export CFLAGS="-D__ANDROID_API__=21"
|
#export CFLAGS="-D__ANDROID_API__=21"
|
||||||
|
#
|
||||||
# IMPORTANT: make sure every target is not a substring of a different one. We check for them with grep later on
|
## IMPORTANT: make sure every target is not a substring of a different one. We check for them with grep later on
|
||||||
BUILD_TARGETS="${BUILD_TARGETS:-aarch64,armv7,x86_64,i686}"
|
#BUILD_TARGETS="${BUILD_TARGETS:-aarch64,armv7,x86_64,i686}"
|
||||||
|
#
|
||||||
mkdir -p bdk-kotlin/aar/src/main/jniLibs/ bdk-kotlin/aar/src/main/jniLibs/arm64-v8a bdk-kotlin/aar/src/main/jniLibs/x86_64 bdk-kotlin/aar/src/main/jniLibs/armeabi-v7a bdk-kotlin/aar/src/main/jniLibs/x86
|
#mkdir -p bdk-kotlin/aar/src/main/jniLibs/ bdk-kotlin/aar/src/main/jniLibs/arm64-v8a bdk-kotlin/aar/src/main/jniLibs/x86_64 bdk-kotlin/aar/src/main/jniLibs/armeabi-v7a bdk-kotlin/aar/src/main/jniLibs/x86
|
||||||
|
#
|
||||||
if echo $BUILD_TARGETS | grep "aarch64"; then
|
#if echo $BUILD_TARGETS | grep "aarch64"; then
|
||||||
CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="aarch64-linux-android21-clang" CC="aarch64-linux-android21-clang" cargo build --target=aarch64-linux-android
|
# CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="aarch64-linux-android21-clang" CC="aarch64-linux-android21-clang" cargo build --target=aarch64-linux-android
|
||||||
cp target/aarch64-linux-android/debug/libbdk_ffi.so bdk-kotlin/aar/src/main/jniLibs/arm64-v8a
|
# cp target/aarch64-linux-android/debug/libbdk_ffi.so bdk-kotlin/aar/src/main/jniLibs/arm64-v8a
|
||||||
fi
|
#fi
|
||||||
if echo $BUILD_TARGETS | grep "x86_64"; then
|
#if echo $BUILD_TARGETS | grep "x86_64"; then
|
||||||
CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER="x86_64-linux-android21-clang" CC="x86_64-linux-android21-clang" cargo build --target=x86_64-linux-android
|
# CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER="x86_64-linux-android21-clang" CC="x86_64-linux-android21-clang" cargo build --target=x86_64-linux-android
|
||||||
cp target/x86_64-linux-android/debug/libbdk_ffi.so bdk-kotlin/aar/src/main/jniLibs/x86_64
|
# cp target/x86_64-linux-android/debug/libbdk_ffi.so bdk-kotlin/aar/src/main/jniLibs/x86_64
|
||||||
fi
|
#fi
|
||||||
if echo $BUILD_TARGETS | grep "armv7"; then
|
#if echo $BUILD_TARGETS | grep "armv7"; then
|
||||||
CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="armv7a-linux-androideabi21-clang" CC="armv7a-linux-androideabi21-clang" cargo build --target=armv7-linux-androideabi
|
# CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER="armv7a-linux-androideabi21-clang" CC="armv7a-linux-androideabi21-clang" cargo build --target=armv7-linux-androideabi
|
||||||
cp target/armv7-linux-androideabi/debug/libbdk_ffi.so bdk-kotlin/aar/src/main/jniLibs/armeabi-v7a
|
# cp target/armv7-linux-androideabi/debug/libbdk_ffi.so bdk-kotlin/aar/src/main/jniLibs/armeabi-v7a
|
||||||
fi
|
#fi
|
||||||
if echo $BUILD_TARGETS | grep "i686"; then
|
#if echo $BUILD_TARGETS | grep "i686"; then
|
||||||
CARGO_TARGET_I686_LINUX_ANDROID_LINKER="i686-linux-android21-clang" CC="i686-linux-android21-clang" cargo build --target=i686-linux-android
|
# CARGO_TARGET_I686_LINUX_ANDROID_LINKER="i686-linux-android21-clang" CC="i686-linux-android21-clang" cargo build --target=i686-linux-android
|
||||||
cp target/i686-linux-android/debug/libbdk_ffi.so bdk-kotlin/aar/src/main/jniLibs/x86
|
# cp target/i686-linux-android/debug/libbdk_ffi.so bdk-kotlin/aar/src/main/jniLibs/x86
|
||||||
fi
|
#fi
|
||||||
|
#
|
||||||
# bdk-kotlin aar
|
## bdk-kotlin aar
|
||||||
(cd bdk-kotlin && gradle :aar:build)
|
#(cd bdk-kotlin && gradle :aar:build)
|
||||||
|
197
src/error.rs
Normal file
197
src/error.rs
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
//use ::safer_ffi::prelude::*;
|
||||||
|
use bdk::Error;
|
||||||
|
|
||||||
|
pub fn error_name(error: &bdk::Error) -> &'static str {
|
||||||
|
match error {
|
||||||
|
Error::InvalidU32Bytes(_) => "InvalidU32Bytes",
|
||||||
|
Error::Generic(_) => "Generic",
|
||||||
|
Error::ScriptDoesntHaveAddressForm => "ScriptDoesntHaveAddressForm",
|
||||||
|
Error::SingleRecipientMultipleOutputs => "SingleRecipientMultipleOutputs",
|
||||||
|
Error::SingleRecipientNoInputs => "SingleRecipientNoInputs",
|
||||||
|
Error::NoRecipients => "NoRecipients",
|
||||||
|
Error::NoUtxosSelected => "NoUtxosSelected",
|
||||||
|
Error::OutputBelowDustLimit(_) => "OutputBelowDustLimit",
|
||||||
|
Error::InsufficientFunds { .. } => "InsufficientFunds",
|
||||||
|
Error::BnBTotalTriesExceeded => "BnBTotalTriesExceeded",
|
||||||
|
Error::BnBNoExactMatch => "BnBNoExactMatch",
|
||||||
|
Error::UnknownUtxo => "UnknownUtxo",
|
||||||
|
Error::TransactionNotFound => "TransactionNotFound",
|
||||||
|
Error::TransactionConfirmed => "TransactionConfirmed",
|
||||||
|
Error::IrreplaceableTransaction => "IrreplaceableTransaction",
|
||||||
|
Error::FeeRateTooLow { .. } => "FeeRateTooLow",
|
||||||
|
Error::FeeTooLow { .. } => "FeeTooLow",
|
||||||
|
Error::MissingKeyOrigin(_) => "MissingKeyOrigin",
|
||||||
|
Error::Key(_) => "Key",
|
||||||
|
Error::ChecksumMismatch => "ChecksumMismatch",
|
||||||
|
Error::SpendingPolicyRequired(_) => "SpendingPolicyRequired",
|
||||||
|
Error::InvalidPolicyPathError(_) => "InvalidPolicyPathError",
|
||||||
|
Error::Signer(_) => "Signer",
|
||||||
|
Error::InvalidProgressValue(_) => "InvalidProgressValue",
|
||||||
|
Error::ProgressUpdateError => "ProgressUpdateError",
|
||||||
|
Error::InvalidOutpoint(_) => "InvalidOutpoint",
|
||||||
|
Error::Descriptor(_) => "Descriptor",
|
||||||
|
Error::AddressValidator(_) => "AddressValidator",
|
||||||
|
Error::Encode(_) => "Encode",
|
||||||
|
Error::Miniscript(_) => "Miniscript",
|
||||||
|
Error::Bip32(_) => "Bip32",
|
||||||
|
Error::Secp256k1(_) => "Secp256k1",
|
||||||
|
Error::Json(_) => "Json",
|
||||||
|
Error::Hex(_) => "Hex",
|
||||||
|
Error::Psbt(_) => "Psbt",
|
||||||
|
Error::Electrum(_) => "Electrum",
|
||||||
|
// Error::Esplora(_) => {}
|
||||||
|
// Error::CompactFilters(_) => {}
|
||||||
|
Error::Sled(_) => "Sled",
|
||||||
|
_ => "Unknown",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//// Errors that can be thrown by the [`Wallet`](crate::wallet::Wallet)
|
||||||
|
//// Simplified to work over the FFI interface
|
||||||
|
//#[derive_ReprC]
|
||||||
|
//#[repr(i16)]
|
||||||
|
//#[derive(Debug)]
|
||||||
|
//pub enum WalletError {
|
||||||
|
// None,
|
||||||
|
// InvalidU32Bytes,
|
||||||
|
// Generic,
|
||||||
|
// ScriptDoesntHaveAddressForm,
|
||||||
|
// SingleRecipientMultipleOutputs,
|
||||||
|
// SingleRecipientNoInputs,
|
||||||
|
// NoRecipients,
|
||||||
|
// NoUtxosSelected,
|
||||||
|
// OutputBelowDustLimit,
|
||||||
|
// InsufficientFunds,
|
||||||
|
// BnBTotalTriesExceeded,
|
||||||
|
// BnBNoExactMatch,
|
||||||
|
// UnknownUtxo,
|
||||||
|
// TransactionNotFound,
|
||||||
|
// TransactionConfirmed,
|
||||||
|
// IrreplaceableTransaction,
|
||||||
|
// FeeRateTooLow,
|
||||||
|
// FeeTooLow,
|
||||||
|
// FeeRateUnavailable,
|
||||||
|
// MissingKeyOrigin,
|
||||||
|
// Key,
|
||||||
|
// ChecksumMismatch,
|
||||||
|
// SpendingPolicyRequired,
|
||||||
|
// InvalidPolicyPathError,
|
||||||
|
// Signer,
|
||||||
|
// InvalidNetwork,
|
||||||
|
// InvalidProgressValue,
|
||||||
|
// ProgressUpdateError,
|
||||||
|
// InvalidOutpoint,
|
||||||
|
// Descriptor,
|
||||||
|
// AddressValidator,
|
||||||
|
// Encode,
|
||||||
|
// Miniscript,
|
||||||
|
// Bip32,
|
||||||
|
// Secp256k1,
|
||||||
|
// Json,
|
||||||
|
// Hex,
|
||||||
|
// Psbt,
|
||||||
|
// PsbtParse,
|
||||||
|
// //#[cfg(feature = "electrum")]
|
||||||
|
// Electrum,
|
||||||
|
// //#[cfg(feature = "esplora")]
|
||||||
|
// //Esplora,
|
||||||
|
// //#[cfg(feature = "compact_filters")]
|
||||||
|
// //CompactFilters,
|
||||||
|
// //#[cfg(feature = "key-value-db")]
|
||||||
|
// Sled,
|
||||||
|
//}
|
||||||
|
|
||||||
|
//impl From<bdk::Error> for WalletError {
|
||||||
|
// fn from(error: bdk::Error) -> Self {
|
||||||
|
// match error {
|
||||||
|
// Error::InvalidU32Bytes(_) => WalletError::InvalidNetwork,
|
||||||
|
// Error::Generic(_) => WalletError::Generic,
|
||||||
|
// Error::ScriptDoesntHaveAddressForm => WalletError::ScriptDoesntHaveAddressForm,
|
||||||
|
// Error::SingleRecipientMultipleOutputs => WalletError::SingleRecipientMultipleOutputs,
|
||||||
|
// Error::SingleRecipientNoInputs => WalletError::SingleRecipientNoInputs,
|
||||||
|
// Error::NoRecipients => WalletError::NoRecipients,
|
||||||
|
// Error::NoUtxosSelected => WalletError::NoUtxosSelected,
|
||||||
|
// Error::OutputBelowDustLimit(_) => WalletError::OutputBelowDustLimit,
|
||||||
|
// Error::InsufficientFunds { .. } => WalletError::InsufficientFunds,
|
||||||
|
// Error::BnBTotalTriesExceeded => WalletError::BnBTotalTriesExceeded,
|
||||||
|
// Error::BnBNoExactMatch => WalletError::BnBNoExactMatch,
|
||||||
|
// Error::UnknownUtxo => WalletError::UnknownUtxo,
|
||||||
|
// Error::TransactionNotFound => WalletError::TransactionNotFound,
|
||||||
|
// Error::TransactionConfirmed => WalletError::TransactionConfirmed,
|
||||||
|
// Error::IrreplaceableTransaction => WalletError::IrreplaceableTransaction,
|
||||||
|
// Error::FeeRateTooLow { .. } => WalletError::FeeRateTooLow,
|
||||||
|
// Error::FeeTooLow { .. } => WalletError::FeeTooLow,
|
||||||
|
// Error::MissingKeyOrigin(_) => WalletError::MissingKeyOrigin,
|
||||||
|
// Error::Key(_) => WalletError::Key,
|
||||||
|
// Error::ChecksumMismatch => WalletError::ChecksumMismatch,
|
||||||
|
// Error::SpendingPolicyRequired(_) => WalletError::SpendingPolicyRequired,
|
||||||
|
// Error::InvalidPolicyPathError(_) => WalletError::InvalidPolicyPathError,
|
||||||
|
// Error::Signer(_) => WalletError::Signer,
|
||||||
|
// Error::InvalidProgressValue(_) => WalletError::InvalidProgressValue,
|
||||||
|
// Error::ProgressUpdateError => WalletError::ProgressUpdateError,
|
||||||
|
// Error::InvalidOutpoint(_) => WalletError::InvalidOutpoint,
|
||||||
|
// Error::Descriptor(_) => WalletError::Descriptor,
|
||||||
|
// Error::AddressValidator(_) => WalletError::AddressValidator,
|
||||||
|
// Error::Encode(_) => WalletError::Encode,
|
||||||
|
// Error::Miniscript(_) => WalletError::Miniscript,
|
||||||
|
// Error::Bip32(_) => WalletError::Bip32,
|
||||||
|
// Error::Secp256k1(_) => WalletError::Secp256k1,
|
||||||
|
// Error::Json(_) => WalletError::Json,
|
||||||
|
// Error::Hex(_) => WalletError::Hex,
|
||||||
|
// Error::Psbt(_) => WalletError::Psbt,
|
||||||
|
// Error::Electrum(_) => WalletError::Electrum,
|
||||||
|
// //Error::Esplora(_) => WalletError::Esplora,
|
||||||
|
// //Error::CompactFilters(_) => {}
|
||||||
|
// Error::Sled(_) => WalletError::Sled,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//type error_code = i16;
|
||||||
|
//
|
||||||
|
//impl From<bdk::Error> for error_code {
|
||||||
|
// fn from(error: bdk::Error) -> Self {
|
||||||
|
// match error {
|
||||||
|
// Error::InvalidU32Bytes(_) => 1,
|
||||||
|
// Error::Generic(_) => 2,
|
||||||
|
// Error::ScriptDoesntHaveAddressForm => 3,
|
||||||
|
// Error::SingleRecipientMultipleOutputs => 4,
|
||||||
|
// Error::SingleRecipientNoInputs => 5,
|
||||||
|
// Error::NoRecipients => 6,
|
||||||
|
// Error::NoUtxosSelected => 7,
|
||||||
|
// Error::OutputBelowDustLimit(_) => 8,
|
||||||
|
// Error::InsufficientFunds { .. } => 9,
|
||||||
|
// Error::BnBTotalTriesExceeded => 10,
|
||||||
|
// Error::BnBNoExactMatch => 11,
|
||||||
|
// Error::UnknownUtxo => 12,
|
||||||
|
// Error::TransactionNotFound => 13,
|
||||||
|
// Error::TransactionConfirmed => 14,
|
||||||
|
// Error::IrreplaceableTransaction => 15,
|
||||||
|
// Error::FeeRateTooLow { .. } => 16,
|
||||||
|
// Error::FeeTooLow { .. } => 17,
|
||||||
|
// Error::MissingKeyOrigin(_) => 18,
|
||||||
|
// Error::Key(_) => 19,
|
||||||
|
// Error::ChecksumMismatch => 20,
|
||||||
|
// Error::SpendingPolicyRequired(_) => 21,
|
||||||
|
// Error::InvalidPolicyPathError(_) => 22,
|
||||||
|
// Error::Signer(_) => 23,
|
||||||
|
// Error::InvalidProgressValue(_) => 24,
|
||||||
|
// Error::ProgressUpdateError => 25,
|
||||||
|
// Error::InvalidOutpoint(_) => 26,
|
||||||
|
// Error::Descriptor(_) => 27,
|
||||||
|
// Error::AddressValidator(_) => 28,
|
||||||
|
// Error::Encode(_) => 29,
|
||||||
|
// Error::Miniscript(_) => 30,
|
||||||
|
// Error::Bip32(_) => 31,
|
||||||
|
// Error::Secp256k1(_) => 32,
|
||||||
|
// Error::Json(_) => 33,
|
||||||
|
// Error::Hex(_) => 34,
|
||||||
|
// Error::Psbt(_) => 35,
|
||||||
|
// Error::Electrum(_) => 36,
|
||||||
|
// //Error::Esplora(_) => WalletError::Esplora,
|
||||||
|
// //Error::CompactFilters(_) => {}
|
||||||
|
// Error::Sled(_) => 37,
|
||||||
|
// _ => -1
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
126
src/wallet.rs
126
src/wallet.rs
@ -6,33 +6,84 @@ use bdk::blockchain::{
|
|||||||
};
|
};
|
||||||
use bdk::database::{AnyDatabase, AnyDatabaseConfig, ConfigurableDatabase};
|
use bdk::database::{AnyDatabase, AnyDatabaseConfig, ConfigurableDatabase};
|
||||||
use bdk::wallet::AddressIndex::New;
|
use bdk::wallet::AddressIndex::New;
|
||||||
use bdk::Wallet;
|
use bdk::{Error, Wallet};
|
||||||
use safer_ffi::boxed::Box;
|
use safer_ffi::boxed::Box;
|
||||||
use safer_ffi::char_p::{char_p_boxed, char_p_ref};
|
use safer_ffi::char_p::{char_p_boxed, char_p_ref};
|
||||||
|
|
||||||
#[derive_ReprC]
|
#[derive_ReprC]
|
||||||
#[ReprC::opaque]
|
#[ReprC::opaque]
|
||||||
pub struct WalletPtr {
|
pub struct VoidResult {
|
||||||
raw: Wallet<AnyBlockchain, AnyDatabase>,
|
raw: Result<(), String>,
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Wallet<AnyBlockchain, AnyDatabase>> for WalletPtr {
|
|
||||||
fn from(wallet: Wallet<AnyBlockchain, AnyDatabase>) -> Self {
|
|
||||||
WalletPtr { raw: wallet }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[ffi_export]
|
#[ffi_export]
|
||||||
fn new_wallet(
|
fn get_void_err(void_result: &VoidResult) -> Option<char_p_boxed> {
|
||||||
|
void_result
|
||||||
|
.raw
|
||||||
|
.as_ref()
|
||||||
|
.err()
|
||||||
|
.map(|s| char_p_boxed::try_from(s.clone()).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffi_export]
|
||||||
|
fn free_void_result(void_result: Option<Box<VoidResult>>) {
|
||||||
|
drop(void_result)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive_ReprC]
|
||||||
|
#[ReprC::opaque]
|
||||||
|
pub struct StringResult {
|
||||||
|
raw: Result<String, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffi_export]
|
||||||
|
fn get_string_ok(string_result: &StringResult) -> Option<char_p_boxed> {
|
||||||
|
string_result
|
||||||
|
.raw
|
||||||
|
.as_ref()
|
||||||
|
.ok()
|
||||||
|
.map(|s| char_p_boxed::try_from(s.clone()).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffi_export]
|
||||||
|
fn get_string_err(string_result: &StringResult) -> Option<char_p_boxed> {
|
||||||
|
string_result
|
||||||
|
.raw
|
||||||
|
.as_ref()
|
||||||
|
.err()
|
||||||
|
.map(|s| char_p_boxed::try_from(s.clone()).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffi_export]
|
||||||
|
fn free_string_result(string_result: Option<Box<StringResult>>) {
|
||||||
|
drop(string_result)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive_ReprC]
|
||||||
|
#[ReprC::opaque]
|
||||||
|
pub struct WalletResult {
|
||||||
|
raw: Result<Wallet<AnyBlockchain, AnyDatabase>, String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffi_export]
|
||||||
|
fn new_wallet_result(
|
||||||
name: char_p_ref,
|
name: char_p_ref,
|
||||||
descriptor: char_p_ref,
|
descriptor: char_p_ref,
|
||||||
change_descriptor: Option<char_p_ref>,
|
change_descriptor: Option<char_p_ref>,
|
||||||
) -> Box<WalletPtr> {
|
) -> Box<WalletResult> {
|
||||||
let network = Testnet;
|
let name = name.to_string();
|
||||||
let _name = name.to_string();
|
|
||||||
let descriptor = descriptor.to_string();
|
let descriptor = descriptor.to_string();
|
||||||
let change_descriptor = change_descriptor.map(|s| s.to_string());
|
let change_descriptor = change_descriptor.map(|s| s.to_string());
|
||||||
|
let wallet_result = new_wallet(name, descriptor, change_descriptor).map_err(|e| e.to_string());
|
||||||
|
Box::new(WalletResult { raw: wallet_result })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_wallet(
|
||||||
|
name: String,
|
||||||
|
descriptor: String,
|
||||||
|
change_descriptor: Option<String>,
|
||||||
|
) -> Result<Wallet<AnyBlockchain, AnyDatabase>, Error> {
|
||||||
|
let network = Testnet;
|
||||||
let electrum_config = AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
|
let electrum_config = AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
|
||||||
url: "ssl://electrum.blockstream.info:60002".to_string(),
|
url: "ssl://electrum.blockstream.info:60002".to_string(),
|
||||||
socks5: None,
|
socks5: None,
|
||||||
@ -40,39 +91,52 @@ fn new_wallet(
|
|||||||
timeout: None,
|
timeout: None,
|
||||||
});
|
});
|
||||||
let blockchain_config = electrum_config;
|
let blockchain_config = electrum_config;
|
||||||
let client = AnyBlockchain::from_config(&blockchain_config).unwrap();
|
let client = AnyBlockchain::from_config(&blockchain_config)?;
|
||||||
|
|
||||||
let database_config = AnyDatabaseConfig::Memory(());
|
let database_config = AnyDatabaseConfig::Memory(());
|
||||||
let database = AnyDatabase::from_config(&database_config).unwrap();
|
let database = AnyDatabase::from_config(&database_config)?;
|
||||||
|
|
||||||
let descriptor: &str = descriptor.as_str();
|
let descriptor: &str = descriptor.as_str();
|
||||||
let change_descriptor: Option<&str> = change_descriptor.as_deref();
|
let change_descriptor: Option<&str> = change_descriptor.as_deref();
|
||||||
|
|
||||||
let wallet = Wallet::new(descriptor, change_descriptor, network, database, client).unwrap();
|
Wallet::new(descriptor, change_descriptor, network, database, client)
|
||||||
|
|
||||||
Box::new(WalletPtr::from(wallet))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[ffi_export]
|
#[ffi_export]
|
||||||
fn sync_wallet(wallet: &WalletPtr) {
|
fn get_wallet_err(wallet_result: &WalletResult) -> Option<char_p_boxed> {
|
||||||
let _r = wallet.raw.sync(log_progress(), Some(100));
|
wallet_result
|
||||||
|
.raw
|
||||||
|
.as_ref()
|
||||||
|
.err()
|
||||||
|
.map(|s| char_p_boxed::try_from(s.clone()).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[ffi_export]
|
#[ffi_export]
|
||||||
fn new_address(wallet: &WalletPtr) -> char_p_boxed {
|
fn sync_wallet(wallet_result: &WalletResult) -> Box<VoidResult> {
|
||||||
let new_address = wallet.raw.get_address(New);
|
let wallet_result_ref = wallet_result.raw.as_ref().map_err(|error| error.clone());
|
||||||
let new_address = new_address.unwrap();
|
let void_result = wallet_result_ref
|
||||||
let new_address = new_address.to_string();
|
.and_then(|w| w.sync(log_progress(), Some(100)).map_err(|e| e.to_string()));
|
||||||
new_address.try_into().unwrap()
|
Box::new(VoidResult { raw: void_result })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffi_export]
|
||||||
|
fn new_address(wallet_result: &WalletResult) -> Box<StringResult> {
|
||||||
|
let new_address = wallet_result
|
||||||
|
.raw
|
||||||
|
.as_ref()
|
||||||
|
.map_err(|error| error.clone())
|
||||||
|
.and_then(|w| w.get_address(New).map_err(|error| error.to_string()));
|
||||||
|
let string_result = new_address.map(|a| a.to_string());
|
||||||
|
Box::new(StringResult { raw: string_result })
|
||||||
|
}
|
||||||
|
|
||||||
|
#[ffi_export]
|
||||||
|
fn free_wallet_result(wallet_result: Option<Box<WalletResult>>) {
|
||||||
|
drop(wallet_result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Frees a Rust-allocated string
|
/// Frees a Rust-allocated string
|
||||||
#[ffi_export]
|
#[ffi_export]
|
||||||
fn free_string(string: char_p_boxed) {
|
fn free_string(string: Option<char_p_boxed>) {
|
||||||
drop(string)
|
drop(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[ffi_export]
|
|
||||||
fn free_wallet(wallet: Option<Box<WalletPtr>>) {
|
|
||||||
drop(wallet)
|
|
||||||
}
|
|
||||||
|
6
test.sh
6
test.sh
@ -6,9 +6,9 @@ cargo test --features c-headers -- generate_headers
|
|||||||
|
|
||||||
# cc
|
# cc
|
||||||
export LD_LIBRARY_PATH=`pwd`/target/debug
|
export LD_LIBRARY_PATH=`pwd`/target/debug
|
||||||
valgrind --leak-check=full cc/bdk_ffi_test
|
#valgrind --leak-check=full cc/bdk_ffi_test
|
||||||
#cc/bdk_ffi_test
|
cc/bdk_ffi_test
|
||||||
|
|
||||||
# bdk-kotlin
|
# bdk-kotlin
|
||||||
(cd bdk-kotlin && gradle test)
|
(cd bdk-kotlin && gradle test)
|
||||||
(cd bdk-kotlin && gradle :aar:connectedDebugAndroidTest)
|
#(cd bdk-kotlin && gradle :aar:connectedDebugAndroidTest)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user