Skip to content

Commit af64bc4

Browse files
fixes
1 parent 165c578 commit af64bc4

File tree

14 files changed

+402
-72
lines changed

14 files changed

+402
-72
lines changed

dash-spv-ffi/FFI_API.md

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This document provides a comprehensive reference for all FFI (Foreign Function I
44

55
**Auto-generated**: This documentation is automatically generated from the source code. Do not edit manually.
66

7-
**Total Functions**: 70
7+
**Total Functions**: 71
88

99
## Table of Contents
1010

@@ -138,7 +138,7 @@ Functions: 2
138138

139139
### Utility Functions
140140

141-
Functions: 18
141+
Functions: 19
142142

143143
| Function | Description | Module |
144144
|----------|-------------|--------|
@@ -151,7 +151,7 @@ Functions: 18
151151
| `dash_spv_ffi_client_get_stats` | Get current runtime statistics for the SPV client | client |
152152
| `dash_spv_ffi_client_get_tip_hash` | Get the current chain tip hash (32 bytes) if available | client |
153153
| `dash_spv_ffi_client_get_tip_height` | Get the current chain tip height (absolute) | client |
154-
| `dash_spv_ffi_client_get_wallet_manager` | Get the wallet manager from the SPV client Returns an opaque pointer to FFIW... | client |
154+
| `dash_spv_ffi_client_get_wallet_manager` | Get the wallet manager from the SPV client Returns a pointer to an `FFIWalle... | client |
155155
| `dash_spv_ffi_client_record_send` | Record that we attempted to send a transaction by its txid | client |
156156
| `dash_spv_ffi_client_rescan_blockchain` | Request a rescan of the blockchain from a given height (not yet implemented) | client |
157157
| `dash_spv_ffi_enable_test_mode` | No description | utils |
@@ -160,6 +160,7 @@ Functions: 18
160160
| `dash_spv_ffi_string_array_destroy` | Destroy an array of FFIString pointers (Vec<*mut FFIString>) and their contents | types |
161161
| `dash_spv_ffi_string_destroy` | No description | types |
162162
| `dash_spv_ffi_version` | No description | utils |
163+
| `dash_spv_ffi_wallet_manager_free` | Release a wallet manager obtained from `dash_spv_ffi_client_get_wallet_manager` | client |
163164

164165
## Detailed Function Documentation
165166

@@ -1117,14 +1118,14 @@ Get the current chain tip height (absolute). # Safety - `client` must be a vali
11171118
#### `dash_spv_ffi_client_get_wallet_manager`
11181119
11191120
```c
1120-
dash_spv_ffi_client_get_wallet_manager(client: *mut FFIDashSpvClient,) -> *mut c_void
1121+
dash_spv_ffi_client_get_wallet_manager(client: *mut FFIDashSpvClient,) -> *mut FFIWalletManager
11211122
```
11221123

11231124
**Description:**
1124-
Get the wallet manager from the SPV client Returns an opaque pointer to FFIWalletManager that contains a cloned Arc reference to the wallet manager. This allows direct interaction with the wallet manager without going through the client. # Safety The caller must ensure that: - The client pointer is valid - The returned pointer is freed using `wallet_manager_free` from key-wallet-ffi # Returns An opaque pointer (void*) to the wallet manager, or NULL if the client is not initialized. Swift should treat this as an OpaquePointer. Get a handle to the wallet manager owned by this client. # Safety - `client` must be a valid, non-null pointer.
1125+
Get the wallet manager from the SPV client Returns a pointer to an `FFIWalletManager` wrapper that clones the underlying `Arc<RwLock<WalletManager>>`. This allows direct interaction with the wallet manager without going back through the client for each call. # Safety The caller must ensure that: - The client pointer is valid - The returned pointer is released exactly once using `dash_spv_ffi_wallet_manager_free` # Returns A pointer to the wallet manager wrapper, or NULL if the client is not initialized.
11251126

11261127
**Safety:**
1127-
The caller must ensure that: - The client pointer is valid - The returned pointer is freed using `wallet_manager_free` from key-wallet-ffi
1128+
The caller must ensure that: - The client pointer is valid - The returned pointer is released exactly once using `dash_spv_ffi_wallet_manager_free`
11281129

11291130
**Module:** `client`
11301131

@@ -1237,6 +1238,22 @@ dash_spv_ffi_version() -> *const c_char
12371238

12381239
---
12391240

1241+
#### `dash_spv_ffi_wallet_manager_free`
1242+
1243+
```c
1244+
dash_spv_ffi_wallet_manager_free(manager: *mut FFIWalletManager) -> ()
1245+
```
1246+
1247+
**Description:**
1248+
Release a wallet manager obtained from `dash_spv_ffi_client_get_wallet_manager`. This simply forwards to `wallet_manager_free` in key-wallet-ffi so that lifetime management is consistent between direct key-wallet usage and the SPV client pathway. # Safety - `manager` must either be null or a pointer previously returned by `dash_spv_ffi_client_get_wallet_manager`.
1249+
1250+
**Safety:**
1251+
- `manager` must either be null or a pointer previously returned by `dash_spv_ffi_client_get_wallet_manager`.
1252+
1253+
**Module:** `client`
1254+
1255+
---
1256+
12401257
## Type Definitions
12411258
12421259
### Core Types
@@ -1266,7 +1283,7 @@ dash_spv_ffi_version() -> *const c_char
12661283
2. **Cleanup Required**: All returned pointers must be freed using the appropriate `_destroy` function
12671284
3. **Thread Safety**: The SPV client is thread-safe
12681285
4. **Error Handling**: Check return codes and use `dash_spv_ffi_get_last_error()` for details
1269-
5. **Opaque Pointers**: `dash_spv_ffi_client_get_wallet_manager()` returns `void*` for Swift compatibility
1286+
5. **Shared Ownership**: `dash_spv_ffi_client_get_wallet_manager()` returns `FFIWalletManager*` that must be released with `dash_spv_ffi_wallet_manager_free()`
12701287
12711288
## Usage Examples
12721289
@@ -1289,8 +1306,8 @@ if (result != 0) {
12891306
// Sync to chain tip
12901307
dash_spv_ffi_client_sync_to_tip(client, NULL, NULL);
12911308
1292-
// Get wallet manager (returns void* for Swift)
1293-
void* wallet_manager = dash_spv_ffi_client_get_wallet_manager(client);
1309+
// Get wallet manager (shares ownership with the client)
1310+
FFIWalletManager* wallet_manager = dash_spv_ffi_client_get_wallet_manager(client);
12941311
12951312
// Clean up
12961313
dash_spv_ffi_client_destroy(client);

dash-spv-ffi/dash_spv_ffi.h

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -531,27 +531,35 @@ int32_t dash_spv_ffi_client_enable_mempool_tracking(struct FFIDashSpvClient *cli
531531
/**
532532
* Get the wallet manager from the SPV client
533533
*
534-
* Returns an opaque pointer to FFIWalletManager that contains a cloned Arc reference to the wallet manager.
535-
* This allows direct interaction with the wallet manager without going through the client.
534+
* Returns a pointer to an `FFIWalletManager` wrapper that clones the underlying
535+
* `Arc<RwLock<WalletManager>>`. This allows direct interaction with the wallet
536+
* manager without going back through the client for each call.
536537
*
537538
* # Safety
538539
*
539540
* The caller must ensure that:
540541
* - The client pointer is valid
541-
* - The returned pointer is freed using `wallet_manager_free` from key-wallet-ffi
542+
* - The returned pointer is released exactly once using
543+
* `dash_spv_ffi_wallet_manager_free`
542544
*
543545
* # Returns
544546
*
545-
* An opaque pointer (void*) to the wallet manager, or NULL if the client is not initialized.
546-
* Swift should treat this as an OpaquePointer.
547-
* Get a handle to the wallet manager owned by this client.
547+
* A pointer to the wallet manager wrapper, or NULL if the client is not initialized.
548+
*/
549+
FFIWalletManager *dash_spv_ffi_client_get_wallet_manager(struct FFIDashSpvClient *client) ;
550+
551+
/**
552+
* Release a wallet manager obtained from `dash_spv_ffi_client_get_wallet_manager`.
553+
*
554+
* This simply forwards to `wallet_manager_free` in key-wallet-ffi so that
555+
* lifetime management is consistent between direct key-wallet usage and the
556+
* SPV client pathway.
548557
*
549558
* # Safety
550-
* - `client` must be a valid, non-null pointer.
559+
* - `manager` must either be null or a pointer previously returned by
560+
* `dash_spv_ffi_client_get_wallet_manager`.
551561
*/
552-
553-
void *dash_spv_ffi_client_get_wallet_manager(struct FFIDashSpvClient *client)
554-
;
562+
void dash_spv_ffi_wallet_manager_free(FFIWalletManager *manager) ;
555563

556564
struct FFIClientConfig *dash_spv_ffi_config_new(FFINetwork network) ;
557565

dash-spv-ffi/examples/wallet_manager_usage.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/// 2. No longer requires going through the client for each operation
66
/// 3. Cleaner and more efficient access to wallet functionality
77
use dash_spv_ffi::*;
8-
use key_wallet_ffi::{wallet_manager_free, wallet_manager_wallet_count, FFIError};
8+
use key_wallet_ffi::{wallet_manager_wallet_count, FFIError};
99

1010
fn main() {
1111
unsafe {
@@ -21,22 +21,22 @@ fn main() {
2121
panic!("Failed to create client");
2222
}
2323

24-
// Get the wallet manager - now returns void* for Swift compatibility
25-
// This contains a cloned Arc to the wallet manager, allowing
26-
// direct interaction without going through the client
27-
let wallet_manager_ptr = dash_spv_ffi_client_get_wallet_manager(client);
28-
if wallet_manager_ptr.is_null() {
24+
// Get the wallet manager - this returns a strongly typed pointer that
25+
// shares the Arc with the SPV client, allowing direct interaction
26+
let wallet_manager = dash_spv_ffi_client_get_wallet_manager(client);
27+
if wallet_manager.is_null() {
2928
panic!("Failed to get wallet manager");
3029
}
31-
// Cast back to FFIWalletManager for use
32-
let wallet_manager = wallet_manager_ptr as *mut key_wallet_ffi::FFIWalletManager;
3330

3431
// Now we can use the wallet manager directly
3532
// No need to go through client -> inner -> spv_client -> wallet()
3633

3734
// Get the number of wallets (should be 0 initially)
3835
let mut error = std::mem::zeroed::<FFIError>();
39-
let wallet_count = wallet_manager_wallet_count(wallet_manager, &mut error);
36+
let wallet_count = wallet_manager_wallet_count(
37+
wallet_manager as *const key_wallet_ffi::FFIWalletManager,
38+
&mut error,
39+
);
4040
println!("Number of wallets: {}", wallet_count);
4141

4242
// Note: To get total balance, you would need to iterate through wallets
@@ -66,7 +66,7 @@ fn main() {
6666
// Clean up
6767
// The wallet manager can now be independently destroyed
6868
// It maintains its own Arc reference to the underlying wallet
69-
wallet_manager_free(wallet_manager);
69+
dash_spv_ffi_wallet_manager_free(wallet_manager);
7070
dash_spv_ffi_client_destroy(client);
7171
dash_spv_ffi_config_destroy(config);
7272

dash-spv-ffi/include/dash_spv_ffi.h

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -531,27 +531,35 @@ int32_t dash_spv_ffi_client_enable_mempool_tracking(struct FFIDashSpvClient *cli
531531
/**
532532
* Get the wallet manager from the SPV client
533533
*
534-
* Returns an opaque pointer to FFIWalletManager that contains a cloned Arc reference to the wallet manager.
535-
* This allows direct interaction with the wallet manager without going through the client.
534+
* Returns a pointer to an `FFIWalletManager` wrapper that clones the underlying
535+
* `Arc<RwLock<WalletManager>>`. This allows direct interaction with the wallet
536+
* manager without going back through the client for each call.
536537
*
537538
* # Safety
538539
*
539540
* The caller must ensure that:
540541
* - The client pointer is valid
541-
* - The returned pointer is freed using `wallet_manager_free` from key-wallet-ffi
542+
* - The returned pointer is released exactly once using
543+
* `dash_spv_ffi_wallet_manager_free`
542544
*
543545
* # Returns
544546
*
545-
* An opaque pointer (void*) to the wallet manager, or NULL if the client is not initialized.
546-
* Swift should treat this as an OpaquePointer.
547-
* Get a handle to the wallet manager owned by this client.
547+
* A pointer to the wallet manager wrapper, or NULL if the client is not initialized.
548+
*/
549+
FFIWalletManager *dash_spv_ffi_client_get_wallet_manager(struct FFIDashSpvClient *client) ;
550+
551+
/**
552+
* Release a wallet manager obtained from `dash_spv_ffi_client_get_wallet_manager`.
553+
*
554+
* This simply forwards to `wallet_manager_free` in key-wallet-ffi so that
555+
* lifetime management is consistent between direct key-wallet usage and the
556+
* SPV client pathway.
548557
*
549558
* # Safety
550-
* - `client` must be a valid, non-null pointer.
559+
* - `manager` must either be null or a pointer previously returned by
560+
* `dash_spv_ffi_client_get_wallet_manager`.
551561
*/
552-
553-
void *dash_spv_ffi_client_get_wallet_manager(struct FFIDashSpvClient *client)
554-
;
562+
void dash_spv_ffi_wallet_manager_free(FFIWalletManager *manager) ;
555563

556564
struct FFIClientConfig *dash_spv_ffi_config_new(FFINetwork network) ;
557565

dash-spv-ffi/scripts/generate_ffi_docs.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,10 @@ def generate_markdown(functions: List[FFIFunction]) -> str:
287287
md.append("2. **Cleanup Required**: All returned pointers must be freed using the appropriate `_destroy` function")
288288
md.append("3. **Thread Safety**: The SPV client is thread-safe")
289289
md.append("4. **Error Handling**: Check return codes and use `dash_spv_ffi_get_last_error()` for details")
290-
md.append("5. **Opaque Pointers**: `dash_spv_ffi_client_get_wallet_manager()` returns `void*` for Swift compatibility")
290+
md.append(
291+
"5. **Shared Ownership**: `dash_spv_ffi_client_get_wallet_manager()` returns `FFIWalletManager*` "
292+
"that must be released with `dash_spv_ffi_wallet_manager_free()`"
293+
)
291294
md.append("")
292295

293296
# Usage Examples
@@ -312,8 +315,8 @@ def generate_markdown(functions: List[FFIFunction]) -> str:
312315
md.append("// Sync to chain tip")
313316
md.append("dash_spv_ffi_client_sync_to_tip(client, NULL, NULL);")
314317
md.append("")
315-
md.append("// Get wallet manager (returns void* for Swift)")
316-
md.append("void* wallet_manager = dash_spv_ffi_client_get_wallet_manager(client);")
318+
md.append("// Get wallet manager (shares ownership with the client)")
319+
md.append("FFIWalletManager* wallet_manager = dash_spv_ffi_client_get_wallet_manager(client);")
317320
md.append("")
318321
md.append("// Clean up")
319322
md.append("dash_spv_ffi_client_destroy(client);")

dash-spv-ffi/src/client.rs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1485,27 +1485,24 @@ pub unsafe extern "C" fn dash_spv_ffi_client_record_send(
14851485

14861486
/// Get the wallet manager from the SPV client
14871487
///
1488-
/// Returns an opaque pointer to FFIWalletManager that contains a cloned Arc reference to the wallet manager.
1489-
/// This allows direct interaction with the wallet manager without going through the client.
1488+
/// Returns a pointer to an `FFIWalletManager` wrapper that clones the underlying
1489+
/// `Arc<RwLock<WalletManager>>`. This allows direct interaction with the wallet
1490+
/// manager without going back through the client for each call.
14901491
///
14911492
/// # Safety
14921493
///
14931494
/// The caller must ensure that:
14941495
/// - The client pointer is valid
1495-
/// - The returned pointer is freed using `wallet_manager_free` from key-wallet-ffi
1496+
/// - The returned pointer is released exactly once using
1497+
/// `dash_spv_ffi_wallet_manager_free`
14961498
///
14971499
/// # Returns
14981500
///
1499-
/// An opaque pointer (void*) to the wallet manager, or NULL if the client is not initialized.
1500-
/// Swift should treat this as an OpaquePointer.
1501-
/// Get a handle to the wallet manager owned by this client.
1502-
///
1503-
/// # Safety
1504-
/// - `client` must be a valid, non-null pointer.
1501+
/// A pointer to the wallet manager wrapper, or NULL if the client is not initialized.
15051502
#[no_mangle]
15061503
pub unsafe extern "C" fn dash_spv_ffi_client_get_wallet_manager(
15071504
client: *mut FFIDashSpvClient,
1508-
) -> *mut c_void {
1505+
) -> *mut FFIWalletManager {
15091506
null_check!(client, std::ptr::null_mut());
15101507

15111508
let client = &*client;
@@ -1519,9 +1516,27 @@ pub unsafe extern "C" fn dash_spv_ffi_client_get_wallet_manager(
15191516
// Create the FFIWalletManager with the cloned Arc
15201517
let manager = FFIWalletManager::from_arc(wallet_arc, runtime);
15211518

1522-
Box::into_raw(Box::new(manager)) as *mut c_void
1519+
Box::into_raw(Box::new(manager))
15231520
} else {
15241521
set_last_error("Client not initialized");
15251522
std::ptr::null_mut()
15261523
}
15271524
}
1525+
1526+
/// Release a wallet manager obtained from `dash_spv_ffi_client_get_wallet_manager`.
1527+
///
1528+
/// This simply forwards to `wallet_manager_free` in key-wallet-ffi so that
1529+
/// lifetime management is consistent between direct key-wallet usage and the
1530+
/// SPV client pathway.
1531+
///
1532+
/// # Safety
1533+
/// - `manager` must either be null or a pointer previously returned by
1534+
/// `dash_spv_ffi_client_get_wallet_manager`.
1535+
#[no_mangle]
1536+
pub unsafe extern "C" fn dash_spv_ffi_wallet_manager_free(manager: *mut FFIWalletManager) {
1537+
if manager.is_null() {
1538+
return;
1539+
}
1540+
1541+
key_wallet_ffi::wallet_manager::wallet_manager_free(manager);
1542+
}

0 commit comments

Comments
 (0)