Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dash-spv-ffi/src/bin/ffi_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ fn main() {
}

let mnemonic_c = CString::new(mnemonic.as_str()).unwrap();
let mut error = FFIError::success();
let mut error = FFIError::default();
let success = wallet_manager_add_wallet_from_mnemonic(
wallet_manager as *mut _,
mnemonic_c.as_ptr(),
Expand Down
6 changes: 3 additions & 3 deletions dash-spv-ffi/tests/dashd_sync/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ impl FFITestContext {
pub(super) unsafe fn add_wallet(&self, mnemonic: &str) -> Vec<u8> {
let mnemonic_c = CString::new(mnemonic).unwrap();
let passphrase = CString::new("").unwrap();
let mut error = FFIError::success();
let mut error = FFIError::default();
let wm = self.session.wallet_manager as *mut FFIWalletManager;

let success = wallet_manager_add_wallet_from_mnemonic(
Expand Down Expand Up @@ -208,7 +208,7 @@ impl FFITestContext {
pub(super) unsafe fn get_wallet_balance(&self, wallet_id: &[u8]) -> (u64, u64) {
let mut confirmed: u64 = 0;
let mut unconfirmed: u64 = 0;
let mut error = FFIError::success();
let mut error = FFIError::default();
let wm = self.session.wallet_manager as *mut FFIWalletManager;

let success = wallet_manager_get_wallet_balance(
Expand Down Expand Up @@ -279,7 +279,7 @@ impl FFITestContext {
///
/// Calls FFI wallet functions through raw pointers held by the context.
pub(super) unsafe fn get_receive_address(&self, wallet_id: &[u8]) -> Address {
let mut error = FFIError::success();
let mut error = FFIError::default();
let wm = self.session.wallet_manager as *mut FFIWalletManager;

let ffi_wallet = wallet_manager_get_wallet(wm, wallet_id.as_ptr(), &mut error);
Expand Down
6 changes: 3 additions & 3 deletions dash-spv-ffi/tests/test_wallet_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ mod tests {
assert_eq!((*wallet_manager_ptr).network(), FFINetwork::Testnet);

// Get wallet count (should be 0 initially)
let mut error = FFIError::success();
let mut error = FFIError::default();
let count = wallet_manager_wallet_count(
wallet_manager as *const FFIWalletManager,
&mut error as *mut FFIError,
Expand Down Expand Up @@ -88,7 +88,7 @@ mod tests {
.expect("wallet serialization should succeed");

// Import the serialized wallet through the FFI pointer we retrieved from the client
let mut error = FFIError::success();
let mut error = FFIError::default();
let mut imported_wallet_id = [0u8; 32];
let import_ok = wallet_manager_import_wallet_from_bytes(
wallet_manager_ptr,
Expand Down Expand Up @@ -118,7 +118,7 @@ mod tests {
wallet_manager_free_wallet_ids(ids_ptr, id_count);

// Call the describe helper through FFI to ensure the shared instance reports correctly
let mut description_error = FFIError::success();
let mut description_error = FFIError::default();
let description_ptr = key_wallet_ffi::wallet_manager_describe(
wallet_manager_ptr as *const FFIWalletManager,
&mut description_error as *mut FFIError,
Expand Down
249 changes: 138 additions & 111 deletions key-wallet-ffi/FFI_API.md

Large diffs are not rendered by default.

9 changes: 2 additions & 7 deletions key-wallet-ffi/src/account.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Account management functions

use crate::deref_ptr;
use crate::error::{FFIError, FFIErrorCode};
use crate::types::{FFIAccountResult, FFIAccountType, FFIWallet};
use dashcore::ffi::FFINetwork;
Expand Down Expand Up @@ -554,14 +555,8 @@ pub unsafe extern "C" fn wallet_get_account_count(
wallet: *const FFIWallet,
error: *mut FFIError,
) -> c_uint {
if wallet.is_null() {
FFIError::set_error(error, FFIErrorCode::InvalidInput, "Wallet is null".to_string());
return 0;
}

let wallet = &*wallet;
let wallet = deref_ptr!(wallet, error);
let accounts = &wallet.inner().accounts;
FFIError::set_success(error);
let count = accounts.standard_bip44_accounts.len()
+ accounts.standard_bip32_accounts.len()
+ accounts.coinjoin_accounts.len()
Expand Down
53 changes: 28 additions & 25 deletions key-wallet-ffi/src/account_collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use std::os::raw::{c_char, c_uint};
use std::ptr;

use crate::account::FFIAccount;
use crate::error::{FFIError, FFIErrorCode};
use crate::deref_ptr;
use crate::error::FFIError;
use crate::types::FFIWallet;

/// Opaque handle to an account collection
Expand Down Expand Up @@ -78,20 +79,14 @@ pub struct FFIAccountCollectionSummary {
/// # Safety
///
/// - `wallet` must be a valid pointer to an FFIWallet instance
/// - `error` must be a valid pointer to an FFIError structure or null
/// - `error` must be a valid pointer to an FFIError structure
/// - The returned pointer must be freed with `account_collection_free` when no longer needed
#[no_mangle]
pub unsafe extern "C" fn wallet_get_account_collection(
wallet: *const FFIWallet,
error: *mut FFIError,
) -> *mut FFIAccountCollection {
if wallet.is_null() {
FFIError::set_error(error, FFIErrorCode::InvalidInput, "Wallet is null".to_string());
return ptr::null_mut();
}

let wallet = &*wallet;
FFIError::set_success(error);
let wallet = deref_ptr!(wallet, error);
let ffi_collection = FFIAccountCollection::new(&wallet.inner().accounts);
Box::into_raw(Box::new(ffi_collection))
}
Expand Down Expand Up @@ -1071,19 +1066,20 @@ mod tests {
fn test_account_collection_basic() {
unsafe {
let mnemonic = CString::new("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about").unwrap();
let error = &mut FFIError::default();

// Create wallet with default accounts
let wallet = wallet_create_from_mnemonic_with_options(
mnemonic.as_ptr(),
ptr::null(),
FFINetwork::Testnet,
ptr::null(),
ptr::null_mut(),
error,
);
assert!(!wallet.is_null());

// Get account collection
let collection = wallet_get_account_collection(wallet, ptr::null_mut());
let collection = wallet_get_account_collection(wallet, error);
assert!(!collection.is_null());

// Check that we have some accounts
Expand Down Expand Up @@ -1117,6 +1113,7 @@ mod tests {
fn test_bls_account() {
unsafe {
let mnemonic = CString::new("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about").unwrap();
let error = &mut FFIError::default();

// Create wallet with provider accounts
let mut options = crate::types::FFIWalletAccountCreationOptions::default_options();
Expand All @@ -1132,12 +1129,12 @@ mod tests {
ptr::null(),
FFINetwork::Testnet,
&options,
ptr::null_mut(),
error,
);
assert!(!wallet.is_null());

// Get account collection
let collection = wallet_get_account_collection(wallet, ptr::null_mut());
let collection = wallet_get_account_collection(wallet, error);
assert!(!collection.is_null());

// Check for provider operator keys account (BLS)
Expand All @@ -1163,6 +1160,7 @@ mod tests {
fn test_eddsa_account() {
unsafe {
let mnemonic = CString::new("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about").unwrap();
let error = &mut FFIError::default();

// Create wallet with provider accounts
let mut options = crate::types::FFIWalletAccountCreationOptions::default_options();
Expand All @@ -1178,12 +1176,12 @@ mod tests {
ptr::null(),
FFINetwork::Testnet,
&options,
ptr::null_mut(),
error,
);
assert!(!wallet.is_null());

// Get account collection
let collection = wallet_get_account_collection(wallet, ptr::null_mut());
let collection = wallet_get_account_collection(wallet, error);
assert!(!collection.is_null());

// Check for provider platform keys account (EdDSA)
Expand All @@ -1210,6 +1208,7 @@ mod tests {
use std::ffi::CStr;

let mnemonic = CString::new("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about").unwrap();
let error = &mut FFIError::default();

// Create wallet with multiple account types
let mut options = crate::types::FFIWalletAccountCreationOptions::default_options();
Expand Down Expand Up @@ -1248,12 +1247,12 @@ mod tests {
ptr::null(),
FFINetwork::Testnet,
&options,
ptr::null_mut(),
error,
);
assert!(!wallet.is_null());

// Get account collection
let collection = wallet_get_account_collection(wallet, ptr::null_mut());
let collection = wallet_get_account_collection(wallet, error);
assert!(!collection.is_null());

// Get the summary
Expand Down Expand Up @@ -1289,6 +1288,7 @@ mod tests {
use std::ffi::CStr;

let mnemonic = CString::new("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about").unwrap();
let error = &mut FFIError::default();

// Create wallet with no accounts using SpecificAccounts with empty lists
let mut options = crate::types::FFIWalletAccountCreationOptions::default_options();
Expand All @@ -1300,12 +1300,12 @@ mod tests {
ptr::null(),
FFINetwork::Testnet,
&options,
ptr::null_mut(),
error,
);
assert!(!wallet.is_null());

// Get account collection
let collection = wallet_get_account_collection(wallet, ptr::null_mut());
let collection = wallet_get_account_collection(wallet, error);

// With SpecificAccounts and empty lists, collection might be null or empty
if collection.is_null() {
Expand Down Expand Up @@ -1346,6 +1346,7 @@ mod tests {
fn test_account_collection_summary_data() {
unsafe {
let mnemonic = CString::new("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about").unwrap();
let error = &mut FFIError::default();

// Create wallet with various account types
let mut options = crate::types::FFIWalletAccountCreationOptions::default_options();
Expand Down Expand Up @@ -1384,12 +1385,12 @@ mod tests {
ptr::null(),
FFINetwork::Testnet,
&options,
ptr::null_mut(),
error,
);
assert!(!wallet.is_null());

// Get account collection
let collection = wallet_get_account_collection(wallet, ptr::null_mut());
let collection = wallet_get_account_collection(wallet, error);
assert!(!collection.is_null());

// Get the summary data
Expand Down Expand Up @@ -1447,6 +1448,7 @@ mod tests {
fn test_account_collection_summary_data_empty() {
unsafe {
let mnemonic = CString::new("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about").unwrap();
let error = &mut FFIError::default();

// Create wallet with no accounts - but still create a collection on the network
// Use SpecificAccounts with empty lists to get truly empty collections
Expand All @@ -1470,12 +1472,12 @@ mod tests {
ptr::null(),
FFINetwork::Testnet,
&options,
ptr::null_mut(),
error,
);
assert!(!wallet.is_null());

// Get account collection
let collection = wallet_get_account_collection(wallet, ptr::null_mut());
let collection = wallet_get_account_collection(wallet, error);

// With AllAccounts but empty lists, collection should still exist
if collection.is_null() {
Expand Down Expand Up @@ -1533,19 +1535,20 @@ mod tests {
fn test_account_collection_summary_memory_management() {
unsafe {
let mnemonic = CString::new("abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about").unwrap();
let error = &mut FFIError::default();

// Create wallet with default accounts (which should have at least BIP44 account 0)
let wallet = wallet_create_from_mnemonic_with_options(
mnemonic.as_ptr(),
ptr::null(),
FFINetwork::Testnet,
ptr::null(),
ptr::null_mut(),
error,
);
assert!(!wallet.is_null());

// Get account collection
let collection = wallet_get_account_collection(wallet, ptr::null_mut());
let collection = wallet_get_account_collection(wallet, error);
assert!(!collection.is_null());

// Get multiple summaries to test memory management
Expand Down
Loading
Loading