Skip to content
Closed
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
20 changes: 16 additions & 4 deletions dash-spv-ffi/src/callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use key_wallet_ffi::types::{
FFITransactionType,
};
use key_wallet_manager::WalletEvent;
use std::ffi::CString;
use std::ffi::{self, CString};
use std::os::raw::{c_char, c_void};

// ============================================================================
Expand Down Expand Up @@ -728,9 +728,21 @@ impl FFIWalletEventCallbacks {
let output_details: Vec<FFIOutputDetail> = record
.output_details
.iter()
.map(|d| FFIOutputDetail {
index: d.index,
role: FFIOutputRole::from(d.role),
.map(|d| {
let address = if let Some(address) = &d.address {
ffi::CString::new(address.to_string())
.unwrap_or_default()
.into_raw()
} else {
std::ptr::null_mut()
};

FFIOutputDetail {
index: d.index,
role: FFIOutputRole::from(d.role),
value: d.value,
address,
}
})
.collect();

Expand Down
19 changes: 16 additions & 3 deletions key-wallet-ffi/src/managed_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//! ManagedAccount instances from the key-wallet crate. FFIManagedCoreAccount is a
//! simple wrapper around `Arc<ManagedAccount>` without additional fields.

use std::ffi::{self};
use std::os::raw::{c_char, c_uint};
use std::sync::Arc;

Expand Down Expand Up @@ -788,9 +789,19 @@ pub unsafe extern "C" fn managed_core_account_get_transactions(
let output_slice: Box<[FFIOutputDetail]> = record
.output_details
.iter()
.map(|d| FFIOutputDetail {
index: d.index,
role: FFIOutputRole::from(d.role),
.map(|d| {
let address = if let Some(address) = &d.address {
ffi::CString::new(address.to_string()).unwrap_or_default().into_raw()
} else {
std::ptr::null_mut()
};

FFIOutputDetail {
index: d.index,
role: FFIOutputRole::from(d.role),
value: d.value,
address,
}
})
.collect::<Vec<_>>()
.into_boxed_slice();
Expand Down Expand Up @@ -2038,6 +2049,8 @@ mod tests {
let output_slice = vec![FFIOutputDetail {
index: 0,
role: FFIOutputRole::Received,
value: 100000,
address: std::ptr::null_mut(),
}]
.into_boxed_slice();
r0.output_details_count = output_slice.len();
Expand Down
14 changes: 14 additions & 0 deletions key-wallet-ffi/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use key_wallet::managed_account::transaction_record::{OutputRole, TransactionDir
use key_wallet::transaction_checking::transaction_router::TransactionType;
use key_wallet::transaction_checking::{BlockInfo, TransactionContext};
use key_wallet::{Network, Wallet};
use std::ffi;
use std::os::raw::c_char;
use std::sync::Arc;

Expand Down Expand Up @@ -926,10 +927,23 @@ pub struct FFIInputDetail {
}

/// FFI-compatible output detail
/// Address is optional, will be null for unspendable or sent output roles
#[repr(C)]
pub struct FFIOutputDetail {
pub index: u32,
pub role: FFIOutputRole,
pub value: u64,
pub address: *mut std::os::raw::c_char,
}

impl Drop for FFIOutputDetail {
fn drop(&mut self) {
if self.address != std::ptr::null_mut() {
unsafe {
let _ = ffi::CString::from_raw(self.address);
}
}
}
}

#[cfg(test)]
Expand Down
6 changes: 5 additions & 1 deletion key-wallet/src/managed_account/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,8 @@ impl ManagedCoreAccount {
// Build output details — annotate every output with its role
let mut output_details = Vec::new();
for (idx, output) in tx.output.iter().enumerate() {
let role = match &resolved_outputs[idx] {
let address = resolved_outputs[idx].clone();
let role = match &address {
Some(addr) if receive_addrs.contains(addr) => OutputRole::Received,
Some(addr) if change_addrs.contains(addr) => OutputRole::Change,
Some(_) if has_inputs => OutputRole::Sent,
Expand All @@ -501,9 +502,12 @@ impl ManagedCoreAccount {
}
}
};

output_details.push(OutputDetail {
index: idx as u32,
role,
value: output.value,
address,
});
}

Expand Down
3 changes: 3 additions & 0 deletions key-wallet/src/managed_account/transaction_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ pub struct OutputDetail {
pub index: u32,
/// Role of this output from the wallet's perspective
pub role: OutputRole,
/// Output value in satoshis
pub value: u64,
pub address: Option<Address>,
}

/// Role of a transaction output from the wallet's perspective
Expand Down
Loading