From 5e1b90d8968af52900bd13368849a3d92b15eefb Mon Sep 17 00:00:00 2001 From: Borja Castellano Date: Wed, 15 Apr 2026 15:30:06 -0700 Subject: [PATCH] use platform-wallet-ffi headers instead of hardcoded function signatures --- Cargo.lock | 5 +- packages/rs-platform-wallet-ffi/Cargo.toml | 6 +- packages/rs-platform-wallet-ffi/build.rs | 32 + packages/rs-platform-wallet-ffi/cbindgen.toml | 7 +- .../platform_wallet_ffi.h | 670 ------------------ .../src/platform_wallet_info.rs | 18 +- packages/rs-platform-wallet-ffi/src/types.rs | 2 - .../tests/integration_tests.rs | 11 +- packages/rs-sdk-ffi/Cargo.toml | 5 +- packages/rs-sdk-ffi/src/lib.rs | 86 --- .../rs-sdk-ffi/src/platform_wallet_types.rs | 7 - packages/rs-unified-sdk-ffi/Cargo.toml | 1 + packages/rs-unified-sdk-ffi/src/lib.rs | 1 + .../PlatformWallet/ContactRequest.swift | 12 +- .../PlatformWallet/DashPayService.swift | 32 +- .../PlatformWallet/EstablishedContact.swift | 2 +- .../PlatformWallet/IdentityManager.swift | 13 +- .../PlatformWallet/ManagedIdentity.swift | 69 +- .../PlatformWallet/PlatformWallet.swift | 16 +- .../PlatformWallet/PlatformWalletFFI.swift | 403 ----------- .../PlatformWallet/PlatformWalletTypes.swift | 137 ++-- packages/swift-sdk/build_ios.sh | 1 + 22 files changed, 179 insertions(+), 1357 deletions(-) create mode 100644 packages/rs-platform-wallet-ffi/build.rs delete mode 100644 packages/rs-platform-wallet-ffi/platform_wallet_ffi.h delete mode 100644 packages/rs-sdk-ffi/src/platform_wallet_types.rs delete mode 100644 packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/PlatformWalletFFI.swift diff --git a/Cargo.lock b/Cargo.lock index 62dc563addf..7aeab8b1aef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4881,9 +4881,10 @@ dependencies = [ name = "platform-wallet-ffi" version = "2.1.1" dependencies = [ - "dashcore", + "cbindgen 0.27.0", "dpp", "key-wallet", + "key-wallet-ffi", "lazy_static", "once_cell", "parking_lot", @@ -5876,7 +5877,6 @@ dependencies = [ "libc", "log", "once_cell", - "platform-wallet-ffi", "rand 0.8.5", "reqwest 0.12.28", "rs-sdk-trusted-context-provider", @@ -5915,6 +5915,7 @@ version = "3.1.0-dev.1" dependencies = [ "dash-spv-ffi", "key-wallet-ffi", + "platform-wallet-ffi", "rs-sdk-ffi", ] diff --git a/packages/rs-platform-wallet-ffi/Cargo.toml b/packages/rs-platform-wallet-ffi/Cargo.toml index bc4993d459f..8f91614cd8b 100644 --- a/packages/rs-platform-wallet-ffi/Cargo.toml +++ b/packages/rs-platform-wallet-ffi/Cargo.toml @@ -18,14 +18,16 @@ once_cell = "1.19" parking_lot = { version = "0.12", features = ["send_guard"] } lazy_static = "1.4" -# Core dependencies (for Network type) -dashcore = { workspace = true } key-wallet = { workspace = true } +key-wallet-ffi = { workspace = true } [dev-dependencies] tempfile = "3.8" dpp = { path = "../rs-dpp", features = ["fixtures-and-mocks"] } +[build-dependencies] +cbindgen = "0.27" + [features] default = [] mocks = [] diff --git a/packages/rs-platform-wallet-ffi/build.rs b/packages/rs-platform-wallet-ffi/build.rs new file mode 100644 index 00000000000..29549edbb55 --- /dev/null +++ b/packages/rs-platform-wallet-ffi/build.rs @@ -0,0 +1,32 @@ +use std::path::Path; +use std::{env, fs}; + +fn main() { + let crate_name = env::var("CARGO_PKG_NAME").unwrap(); + let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let out_dir = env::var("OUT_DIR").unwrap(); + + println!("cargo:rerun-if-changed=cbindgen.toml"); + println!("cargo:rerun-if-changed=src/"); + + let target_dir = Path::new(&out_dir) + .ancestors() + .nth(3) // This line moves up to the target/ directory + .expect("Failed to find target dir"); + + let include_dir = target_dir.join("include").join(&crate_name); + + fs::create_dir_all(&include_dir).unwrap(); + + let output_path = include_dir.join(format!("{}.h", &crate_name)); + + let config_path = Path::new(&crate_dir).join("cbindgen.toml"); + let config = cbindgen::Config::from_file(&config_path).expect("Failed to read cbindgen.toml"); + + cbindgen::Builder::new() + .with_crate(&crate_dir) + .with_config(config) + .generate() + .expect("Unable to generate bindings") + .write_to_file(&output_path); +} diff --git a/packages/rs-platform-wallet-ffi/cbindgen.toml b/packages/rs-platform-wallet-ffi/cbindgen.toml index 7468de66e9c..a6b9d49c5de 100644 --- a/packages/rs-platform-wallet-ffi/cbindgen.toml +++ b/packages/rs-platform-wallet-ffi/cbindgen.toml @@ -8,7 +8,7 @@ include_version = true namespaces = [] using_namespaces = [] sys_includes = ["stdint.h", "stdbool.h"] -includes = [] +includes = ["../key-wallet-ffi/key-wallet-ffi.h"] no_includes = false cpp_compat = true documentation = true @@ -22,11 +22,6 @@ exclude = [] prefix = "" item_types = ["enums", "structs", "unions", "typedefs", "opaque", "functions"] -[export.rename] -"Handle" = "platform_wallet_handle_t" -"PlatformWalletFFIError" = "platform_wallet_error_t" -"PlatformWalletFFIResult" = "platform_wallet_result_t" - [fn] args = "horizontal" rename_args = "snake_case" diff --git a/packages/rs-platform-wallet-ffi/platform_wallet_ffi.h b/packages/rs-platform-wallet-ffi/platform_wallet_ffi.h deleted file mode 100644 index e53d5a0e9ee..00000000000 --- a/packages/rs-platform-wallet-ffi/platform_wallet_ffi.h +++ /dev/null @@ -1,670 +0,0 @@ -/* - * Platform Wallet FFI - C Header File - * - * C-compatible FFI bindings for rs-platform-wallet - * Provides unified wallet management with Platform identity support - */ - -#ifndef PLATFORM_WALLET_FFI_H -#define PLATFORM_WALLET_FFI_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* ============================================================================ - * Types - * ========================================================================== */ - -typedef uint64_t Handle; -#define NULL_HANDLE 0 - -/* Network types */ -typedef enum { - NETWORK_TYPE_MAINNET = 0, - NETWORK_TYPE_TESTNET = 1, - NETWORK_TYPE_DEVNET = 2, - NETWORK_TYPE_REGTEST = 3, -} NetworkType; - -/* FFI Result codes */ -typedef enum { - PLATFORM_WALLET_FFI_SUCCESS = 0, - PLATFORM_WALLET_FFI_ERROR_INVALID_HANDLE = 1, - PLATFORM_WALLET_FFI_ERROR_INVALID_PARAMETER = 2, - PLATFORM_WALLET_FFI_ERROR_NULL_POINTER = 3, - PLATFORM_WALLET_FFI_ERROR_SERIALIZATION = 4, - PLATFORM_WALLET_FFI_ERROR_DESERIALIZATION = 5, - PLATFORM_WALLET_FFI_ERROR_WALLET_OPERATION = 6, - PLATFORM_WALLET_FFI_ERROR_IDENTITY_NOT_FOUND = 7, - PLATFORM_WALLET_FFI_ERROR_CONTACT_NOT_FOUND = 8, - PLATFORM_WALLET_FFI_ERROR_INVALID_NETWORK = 9, - PLATFORM_WALLET_FFI_ERROR_INVALID_IDENTIFIER = 10, - PLATFORM_WALLET_FFI_ERROR_MEMORY_ALLOCATION = 11, - PLATFORM_WALLET_FFI_ERROR_UTF8_CONVERSION = 12, - PLATFORM_WALLET_FFI_ERROR_UNKNOWN = 99, -} PlatformWalletFFIResult; - -/* Error information */ -typedef struct { - PlatformWalletFFIResult code; - char* message; -} PlatformWalletFFIError; - -/* Identifier (32 bytes) */ -typedef struct { - uint8_t bytes[32]; -} IdentifierBytes; - -/* Block time */ -typedef struct { - uint64_t height; - uint32_t core_height; - uint64_t timestamp; -} BlockTime; - -/* Contact request */ -typedef struct { - IdentifierBytes identity_id; - char* label; - uint64_t timestamp; -} ContactRequest; - -/* Established contact */ -typedef struct { - IdentifierBytes identity_id; - char* label; - uint64_t established_at; -} EstablishedContact; - -/* Array of identifiers */ -typedef struct { - IdentifierBytes* items; - size_t count; -} IdentifierArray; - -/* ============================================================================ - * Library Management - * ========================================================================== */ - -/** - * Initialize the FFI library - * Must be called before using any other functions - */ -void platform_wallet_ffi_init(void); - -/** - * Get the version of the platform wallet FFI library - * @return Version string (do not free) - */ -const char* platform_wallet_ffi_version(void); - -/* ============================================================================ - * Error Management - * ========================================================================== */ - -/** - * Free error message - * @param error Error to free - */ -void platform_wallet_ffi_error_free(PlatformWalletFFIError error); - -/* ============================================================================ - * PlatformWalletInfo Functions - * ========================================================================== */ - -/** - * Create a new PlatformWalletInfo from seed bytes - * @param seed_bytes Seed bytes (typically 64 bytes) - * @param seed_len Length of seed - * @param out_handle Output handle - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult platform_wallet_info_create_from_seed( - const uint8_t* seed_bytes, - size_t seed_len, - Handle* out_handle, - PlatformWalletFFIError* out_error -); - -/** - * Create a new PlatformWalletInfo from mnemonic - * @param mnemonic BIP39 mnemonic phrase - * @param passphrase Optional passphrase (can be NULL) - * @param out_handle Output handle - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult platform_wallet_info_create_from_mnemonic( - const char* mnemonic, - const char* passphrase, - Handle* out_handle, - PlatformWalletFFIError* out_error -); - -/** - * Get the identity manager for a specific network - * @param wallet_handle Wallet handle - * @param network Network type - * @param out_handle Output handle for identity manager - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult platform_wallet_info_get_identity_manager( - Handle wallet_handle, - NetworkType network, - Handle* out_handle, - PlatformWalletFFIError* out_error -); - -/** - * Set identity manager for a network - * @param wallet_handle Wallet handle - * @param network Network type - * @param manager_handle Identity manager handle - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult platform_wallet_info_set_identity_manager( - Handle wallet_handle, - NetworkType network, - Handle manager_handle, - PlatformWalletFFIError* out_error -); - -/** - * Serialize PlatformWalletInfo to JSON - * @param wallet_handle Wallet handle - * @param out_json Output JSON string (caller must free with platform_wallet_string_free) - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult platform_wallet_info_to_json( - Handle wallet_handle, - char** out_json, - PlatformWalletFFIError* out_error -); - -/** - * Destroy PlatformWalletInfo and free resources - * @param wallet_handle Wallet handle - * @return Result code - */ -PlatformWalletFFIResult platform_wallet_info_destroy(Handle wallet_handle); - -/* ============================================================================ - * IdentityManager Functions - * ========================================================================== */ - -/** - * Create a new empty IdentityManager - * @param out_handle Output handle - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult identity_manager_create( - Handle* out_handle, - PlatformWalletFFIError* out_error -); - -/** - * Add a managed identity to the manager - * @param manager_handle Manager handle - * @param identity_handle Identity handle - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult identity_manager_add_identity( - Handle manager_handle, - Handle identity_handle, - PlatformWalletFFIError* out_error -); - -/** - * Remove an identity from the manager - * @param manager_handle Manager handle - * @param identity_id Identity ID to remove - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult identity_manager_remove_identity( - Handle manager_handle, - IdentifierBytes identity_id, - PlatformWalletFFIError* out_error -); - -/** - * Get an identity by ID - * @param manager_handle Manager handle - * @param identity_id Identity ID - * @param out_handle Output handle for identity - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult identity_manager_get_identity( - Handle manager_handle, - IdentifierBytes identity_id, - Handle* out_handle, - PlatformWalletFFIError* out_error -); - -/** - * Get all identity IDs - * @param manager_handle Manager handle - * @param out_array Output array (caller must free with platform_wallet_identifier_array_free) - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult identity_manager_get_all_identity_ids( - Handle manager_handle, - IdentifierArray* out_array, - PlatformWalletFFIError* out_error -); - -/** - * Get the primary identity ID - * @param manager_handle Manager handle - * @param out_id Output identifier - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult identity_manager_get_primary_identity_id( - Handle manager_handle, - IdentifierBytes* out_id, - PlatformWalletFFIError* out_error -); - -/** - * Set the primary identity - * @param manager_handle Manager handle - * @param identity_id Identity ID to set as primary - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult identity_manager_set_primary_identity( - Handle manager_handle, - IdentifierBytes identity_id, - PlatformWalletFFIError* out_error -); - -/** - * Get the count of identities - * @param manager_handle Manager handle - * @param out_count Output count - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult identity_manager_get_identity_count( - Handle manager_handle, - size_t* out_count, - PlatformWalletFFIError* out_error -); - -/** - * Destroy IdentityManager and free resources - * @param manager_handle Manager handle - * @return Result code - */ -PlatformWalletFFIResult identity_manager_destroy(Handle manager_handle); - -/* ============================================================================ - * ManagedIdentity Functions - * ========================================================================== */ - -/** - * Create a new ManagedIdentity from DPP Identity bytes - * @param identity_bytes Serialized identity bytes - * @param identity_len Length of identity bytes - * @param out_handle Output handle - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_create_from_identity_bytes( - const uint8_t* identity_bytes, - size_t identity_len, - Handle* out_handle, - PlatformWalletFFIError* out_error -); - -/** - * Get the identity ID - * @param identity_handle Identity handle - * @param out_id Output identifier - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_get_id( - Handle identity_handle, - IdentifierBytes* out_id, - PlatformWalletFFIError* out_error -); - -/** - * Get the identity balance - * @param identity_handle Identity handle - * @param out_balance Output balance - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_get_balance( - Handle identity_handle, - uint64_t* out_balance, - PlatformWalletFFIError* out_error -); - -/** - * Get the label - * @param identity_handle Identity handle - * @param out_label Output label (caller must free with platform_wallet_string_free, NULL if no label) - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_get_label( - Handle identity_handle, - char** out_label, - PlatformWalletFFIError* out_error -); - -/** - * Set the label - * @param identity_handle Identity handle - * @param label Label string (NULL to clear) - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_set_label( - Handle identity_handle, - const char* label, - PlatformWalletFFIError* out_error -); - -/** - * Get last updated balance block time - * @param identity_handle Identity handle - * @param out_block_time Output block time (zeroed if not set) - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_get_last_updated_balance_block_time( - Handle identity_handle, - BlockTime* out_block_time, - PlatformWalletFFIError* out_error -); - -/** - * Set last updated balance block time - * @param identity_handle Identity handle - * @param block_time Block time to set - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_set_last_updated_balance_block_time( - Handle identity_handle, - BlockTime block_time, - PlatformWalletFFIError* out_error -); - -/** - * Get last synced keys block time - * @param identity_handle Identity handle - * @param out_block_time Output block time (zeroed if not set) - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_get_last_synced_keys_block_time( - Handle identity_handle, - BlockTime* out_block_time, - PlatformWalletFFIError* out_error -); - -/** - * Serialize ManagedIdentity to JSON - * @param identity_handle Identity handle - * @param out_json Output JSON string (caller must free with platform_wallet_string_free) - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_to_json( - Handle identity_handle, - char** out_json, - PlatformWalletFFIError* out_error -); - -/** - * Destroy ManagedIdentity and free resources - * @param identity_handle Identity handle - * @return Result code - */ -PlatformWalletFFIResult managed_identity_destroy(Handle identity_handle); - -/* ============================================================================ - * Contact Management Functions - * ========================================================================== */ - -/** - * Add a sent contact request - * @param identity_handle Identity handle - * @param contact_id Contact identity ID - * @param label Optional label (can be NULL) - * @param timestamp Request timestamp - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_add_sent_contact_request( - Handle identity_handle, - IdentifierBytes contact_id, - const char* label, - uint64_t timestamp, - PlatformWalletFFIError* out_error -); - -/** - * Add an incoming contact request - * @param identity_handle Identity handle - * @param contact_id Contact identity ID - * @param label Optional label (can be NULL) - * @param timestamp Request timestamp - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_add_incoming_contact_request( - Handle identity_handle, - IdentifierBytes contact_id, - const char* label, - uint64_t timestamp, - PlatformWalletFFIError* out_error -); - -/** - * Remove a sent contact request - * @param identity_handle Identity handle - * @param contact_id Contact identity ID - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_remove_sent_contact_request( - Handle identity_handle, - IdentifierBytes contact_id, - PlatformWalletFFIError* out_error -); - -/** - * Remove an incoming contact request - * @param identity_handle Identity handle - * @param contact_id Contact identity ID - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_remove_incoming_contact_request( - Handle identity_handle, - IdentifierBytes contact_id, - PlatformWalletFFIError* out_error -); - -/** - * Get all sent contact request IDs - * @param identity_handle Identity handle - * @param out_array Output array (caller must free with platform_wallet_identifier_array_free) - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_get_sent_contact_request_ids( - Handle identity_handle, - IdentifierArray* out_array, - PlatformWalletFFIError* out_error -); - -/** - * Get all incoming contact request IDs - * @param identity_handle Identity handle - * @param out_array Output array (caller must free with platform_wallet_identifier_array_free) - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_get_incoming_contact_request_ids( - Handle identity_handle, - IdentifierArray* out_array, - PlatformWalletFFIError* out_error -); - -/** - * Get all established contact IDs - * @param identity_handle Identity handle - * @param out_array Output array (caller must free with platform_wallet_identifier_array_free) - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_get_established_contact_ids( - Handle identity_handle, - IdentifierArray* out_array, - PlatformWalletFFIError* out_error -); - -/** - * Check if a contact is established - * @param identity_handle Identity handle - * @param contact_id Contact identity ID - * @param out_is_established Output boolean - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_is_contact_established( - Handle identity_handle, - IdentifierBytes contact_id, - bool* out_is_established, - PlatformWalletFFIError* out_error -); - -/** - * Remove an established contact - * @param identity_handle Identity handle - * @param contact_id Contact identity ID - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult managed_identity_remove_established_contact( - Handle identity_handle, - IdentifierBytes contact_id, - PlatformWalletFFIError* out_error -); - -/* ============================================================================ - * Utility Functions - * ========================================================================== */ - -/** - * Serialize JSON string to bytes - * @param json_string JSON string - * @param out_bytes Output bytes (caller must free with platform_wallet_bytes_free) - * @param out_len Output length - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult platform_wallet_serialize_to_json_bytes( - const char* json_string, - uint8_t** out_bytes, - size_t* out_len, - PlatformWalletFFIError* out_error -); - -/** - * Deserialize JSON bytes to string - * @param bytes Input bytes - * @param len Input length - * @param out_json_string Output JSON string (caller must free with platform_wallet_string_free) - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult platform_wallet_deserialize_from_json_bytes( - const uint8_t* bytes, - size_t len, - char** out_json_string, - PlatformWalletFFIError* out_error -); - -/** - * Generate random identifier - * @param out_id Output identifier - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult platform_wallet_generate_random_identifier( - IdentifierBytes* out_id, - PlatformWalletFFIError* out_error -); - -/** - * Convert identifier to hex string - * @param id Identifier - * @param out_hex Output hex string (caller must free with platform_wallet_string_free) - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult platform_wallet_identifier_to_hex( - IdentifierBytes id, - char** out_hex, - PlatformWalletFFIError* out_error -); - -/** - * Convert hex string to identifier - * @param hex Hex string - * @param out_id Output identifier - * @param out_error Optional error output - * @return Result code - */ -PlatformWalletFFIResult platform_wallet_identifier_from_hex( - const char* hex, - IdentifierBytes* out_id, - PlatformWalletFFIError* out_error -); - -/** - * Free identifier array - * @param array Array to free - */ -void platform_wallet_identifier_array_free(IdentifierArray array); - -/** - * Free a C string - * @param s String to free - */ -void platform_wallet_string_free(char* s); - -/** - * Free bytes allocated by FFI functions - * @param bytes Bytes to free - * @param len Length of bytes - */ -void platform_wallet_bytes_free(uint8_t* bytes, size_t len); - -#ifdef __cplusplus -} -#endif - -#endif /* PLATFORM_WALLET_FFI_H */ diff --git a/packages/rs-platform-wallet-ffi/src/platform_wallet_info.rs b/packages/rs-platform-wallet-ffi/src/platform_wallet_info.rs index 7ab10f30e01..bc9c7170d31 100644 --- a/packages/rs-platform-wallet-ffi/src/platform_wallet_info.rs +++ b/packages/rs-platform-wallet-ffi/src/platform_wallet_info.rs @@ -1,15 +1,15 @@ use crate::error::*; use crate::handle::*; -use crate::types::Network; use key_wallet::wallet::initialization::WalletAccountCreationOptions; use key_wallet::wallet::managed_wallet_info::wallet_info_interface::WalletInfoInterface; +use key_wallet_ffi::FFINetwork; use platform_wallet::platform_wallet_info::PlatformWalletInfo; use std::os::raw::{c_char, c_uchar}; /// Create a new PlatformWalletInfo from seed bytes #[no_mangle] pub unsafe extern "C" fn platform_wallet_info_create_from_seed( - network: Network, + network: FFINetwork, seed_bytes: *const c_uchar, seed_len: usize, out_handle: *mut Handle, @@ -49,7 +49,7 @@ pub unsafe extern "C" fn platform_wallet_info_create_from_seed( // Create wallet from seed let wallet = match key_wallet::Wallet::from_seed_bytes( seed_array, - network, + network.into(), WalletAccountCreationOptions::None, // No accounts initially ) { Ok(w) => w, @@ -79,7 +79,7 @@ pub unsafe extern "C" fn platform_wallet_info_create_from_seed( /// Create a new PlatformWalletInfo from mnemonic #[no_mangle] pub unsafe extern "C" fn platform_wallet_info_create_from_mnemonic( - network: Network, + network: FFINetwork, mnemonic: *const c_char, passphrase: *const c_char, out_handle: *mut Handle, @@ -152,7 +152,7 @@ pub unsafe extern "C" fn platform_wallet_info_create_from_mnemonic( match key_wallet::Wallet::from_mnemonic_with_passphrase( mnemonic_obj, pass.to_string(), - network, + network.into(), WalletAccountCreationOptions::None, // No accounts initially ) { Ok(w) => w, @@ -174,7 +174,7 @@ pub unsafe extern "C" fn platform_wallet_info_create_from_mnemonic( } else { match key_wallet::Wallet::from_mnemonic( mnemonic_obj, - network, + network.into(), WalletAccountCreationOptions::None, // No accounts initially ) { Ok(w) => w, @@ -340,7 +340,7 @@ mod tests { let mut error = PlatformWalletFFIError::success(); let result = platform_wallet_info_create_from_seed( - Network::Testnet, + FFINetwork::Testnet, seed.as_ptr(), seed.len(), &mut handle, @@ -366,7 +366,7 @@ mod tests { let mut error = PlatformWalletFFIError::success(); let result = platform_wallet_info_create_from_mnemonic( - Network::Testnet, + FFINetwork::Testnet, mnemonic.as_ptr(), std::ptr::null(), &mut handle, @@ -390,7 +390,7 @@ mod tests { let mut error = PlatformWalletFFIError::success(); platform_wallet_info_create_from_seed( - Network::Testnet, + FFINetwork::Testnet, seed.as_ptr(), seed.len(), &mut handle, diff --git a/packages/rs-platform-wallet-ffi/src/types.rs b/packages/rs-platform-wallet-ffi/src/types.rs index 9cd45395242..a240ea672a1 100644 --- a/packages/rs-platform-wallet-ffi/src/types.rs +++ b/packages/rs-platform-wallet-ffi/src/types.rs @@ -1,7 +1,5 @@ use std::os::raw::{c_char, c_uchar}; -pub use dashcore::Network; - /// Identifier (32 bytes) #[repr(C)] #[derive(Clone, Copy)] diff --git a/packages/rs-platform-wallet-ffi/tests/integration_tests.rs b/packages/rs-platform-wallet-ffi/tests/integration_tests.rs index 5d4a2cabd78..b2ce091aabd 100644 --- a/packages/rs-platform-wallet-ffi/tests/integration_tests.rs +++ b/packages/rs-platform-wallet-ffi/tests/integration_tests.rs @@ -1,4 +1,5 @@ use dpp::identity::accessors::IdentityGettersV0; +use key_wallet_ffi::FFINetwork; use platform_wallet_ffi::*; use std::ffi::CString; @@ -21,7 +22,7 @@ fn test_wallet_creation_and_destruction() { let mut error = PlatformWalletFFIError::success(); let result = platform_wallet_info_create_from_seed( - Network::Testnet, + FFINetwork::Testnet, seed.as_ptr(), seed.len(), &mut handle, @@ -51,7 +52,7 @@ fn test_wallet_from_mnemonic() { let mut error = PlatformWalletFFIError::success(); let result = platform_wallet_info_create_from_mnemonic( - Network::Testnet, + FFINetwork::Testnet, mnemonic.as_ptr(), std::ptr::null(), &mut handle, @@ -198,7 +199,7 @@ fn test_serialization() { let mut error = PlatformWalletFFIError::success(); platform_wallet_info_create_from_seed( - Network::Testnet, + FFINetwork::Testnet, seed.as_ptr(), seed.len(), &mut handle, @@ -265,7 +266,7 @@ fn test_error_handling() { // Try to create wallet with null pointer let result = platform_wallet_info_create_from_seed( - Network::Testnet, + FFINetwork::Testnet, std::ptr::null(), 0, std::ptr::null_mut(), @@ -291,7 +292,7 @@ fn test_full_workflow() { let mut wallet_handle: Handle = NULL_HANDLE; let result = platform_wallet_info_create_from_mnemonic( - Network::Testnet, + FFINetwork::Testnet, mnemonic.as_ptr(), std::ptr::null(), &mut wallet_handle, diff --git a/packages/rs-sdk-ffi/Cargo.toml b/packages/rs-sdk-ffi/Cargo.toml index f08cd028d40..190f9129412 100644 --- a/packages/rs-sdk-ffi/Cargo.toml +++ b/packages/rs-sdk-ffi/Cargo.toml @@ -23,10 +23,7 @@ rs-sdk-trusted-context-provider = { path = "../rs-sdk-trusted-context-provider", simple-signer = { path = "../simple-signer" } async-trait = { version = "0.1.83" } -# Platform Wallet integration for DashPay support -platform-wallet-ffi = { path = "../rs-platform-wallet-ffi" } - -# FFI and serialization +# Serialization serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" bincode = { version = "=2.0.1", features = ["serde"] } diff --git a/packages/rs-sdk-ffi/src/lib.rs b/packages/rs-sdk-ffi/src/lib.rs index 4f4bbc05e11..f44402ec455 100644 --- a/packages/rs-sdk-ffi/src/lib.rs +++ b/packages/rs-sdk-ffi/src/lib.rs @@ -20,7 +20,6 @@ mod evonode; mod group; mod identity; mod nullifier_sync; -mod platform_wallet_types; mod protocol_version; mod sdk; mod shielded; @@ -50,8 +49,6 @@ pub use evonode::*; pub use group::*; pub use identity::*; pub use nullifier_sync::*; -#[allow(unused_imports)] -pub use platform_wallet_types::*; pub use protocol_version::*; pub use sdk::*; pub use shielded::*; @@ -63,89 +60,6 @@ pub use types::*; pub use utils::*; pub use voting::*; -// Re-export Platform Wallet FFI functions and types for DashPay support -// Note: We re-export selectively to avoid conflicts with rs-sdk-ffi's own modules -pub use platform_wallet_ffi::{ - // Contact request functions - contact_request_create, - contact_request_destroy, - contact_request_get_account_reference, - contact_request_get_created_at, - contact_request_get_encrypted_public_key, - contact_request_get_recipient_id, - contact_request_get_recipient_key_index, - contact_request_get_sender_id, - contact_request_get_sender_key_index, - established_contact_clear_alias, - established_contact_clear_note, - established_contact_destroy, - established_contact_get_alias, - // Established contact functions - established_contact_get_contact_identity_id, - established_contact_get_note, - established_contact_hide, - established_contact_is_hidden, - established_contact_set_alias, - established_contact_set_note, - established_contact_unhide, - identity_manager_add_identity, - // IdentityManager functions - identity_manager_create, - identity_manager_destroy, - identity_manager_get_all_identity_ids, - identity_manager_get_identity, - identity_manager_get_identity_count, - identity_manager_get_primary_identity_id, - identity_manager_remove_identity, - identity_manager_set_primary_identity, - managed_identity_accept_contact_request, - // ManagedIdentity functions - managed_identity_create_from_identity_bytes, - managed_identity_destroy, - managed_identity_get_balance, - managed_identity_get_established_contact, - managed_identity_get_established_contact_ids, - managed_identity_get_id, - managed_identity_get_incoming_contact_request, - managed_identity_get_incoming_contact_request_ids, - managed_identity_get_label, - managed_identity_get_last_synced_keys_block_time, - managed_identity_get_last_updated_balance_block_time, - managed_identity_get_sent_contact_request, - // Contact management functions - managed_identity_get_sent_contact_request_ids, - managed_identity_is_contact_established, - managed_identity_reject_contact_request, - managed_identity_send_contact_request, - managed_identity_set_label, - managed_identity_set_last_updated_balance_block_time, - platform_wallet_bytes_free, - platform_wallet_ffi_error_free, - // Core functions - platform_wallet_ffi_init, - platform_wallet_ffi_version, - // Utility functions - platform_wallet_generate_random_identifier, - platform_wallet_identifier_array_free, - platform_wallet_identifier_from_hex, - platform_wallet_identifier_to_hex, - platform_wallet_info_create_from_mnemonic, - // PlatformWalletInfo functions - platform_wallet_info_create_from_seed, - platform_wallet_info_destroy, - platform_wallet_info_get_identity_manager, - platform_wallet_info_set_identity_manager, - platform_wallet_string_free, - BlockTime, - // Types - Handle, - IdentifierArray, - IdentifierBytes, - PlatformWalletFFIError, - PlatformWalletFFIResult, - NULL_HANDLE, -}; - /// Initialize the FFI library. /// This should be called once at app startup before using any other functions. #[no_mangle] diff --git a/packages/rs-sdk-ffi/src/platform_wallet_types.rs b/packages/rs-sdk-ffi/src/platform_wallet_types.rs deleted file mode 100644 index ef37be7400b..00000000000 --- a/packages/rs-sdk-ffi/src/platform_wallet_types.rs +++ /dev/null @@ -1,7 +0,0 @@ -// Re-export Platform Wallet FFI types for cbindgen to pick up - -#[allow(unused_imports)] -pub use platform_wallet_ffi::{ - BlockTime, Handle, IdentifierArray, IdentifierBytes, PlatformWalletFFIError, - PlatformWalletFFIResult, NULL_HANDLE, -}; diff --git a/packages/rs-unified-sdk-ffi/Cargo.toml b/packages/rs-unified-sdk-ffi/Cargo.toml index e774e067ba5..ca49b101a91 100644 --- a/packages/rs-unified-sdk-ffi/Cargo.toml +++ b/packages/rs-unified-sdk-ffi/Cargo.toml @@ -10,4 +10,5 @@ crate-type = ["staticlib", "cdylib"] [dependencies] dash-spv-ffi = { workspace = true } key-wallet-ffi = { workspace = true } +platform-wallet-ffi = { path = "../rs-platform-wallet-ffi" } rs-sdk-ffi = { path = "../rs-sdk-ffi" } \ No newline at end of file diff --git a/packages/rs-unified-sdk-ffi/src/lib.rs b/packages/rs-unified-sdk-ffi/src/lib.rs index 59bdd1fac8a..b9e1d56797e 100644 --- a/packages/rs-unified-sdk-ffi/src/lib.rs +++ b/packages/rs-unified-sdk-ffi/src/lib.rs @@ -1,3 +1,4 @@ pub use dash_spv_ffi; pub use key_wallet_ffi; +pub use platform_wallet_ffi; pub use rs_sdk_ffi; diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/ContactRequest.swift b/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/ContactRequest.swift index 041e3f541d1..3474839f8ef 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/ContactRequest.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/ContactRequest.swift @@ -10,7 +10,7 @@ public class ContactRequest { } deinit { - contact_request_destroy(handle) + _ = contact_request_destroy(handle) } /// Create a new contact request @@ -21,6 +21,7 @@ public class ContactRequest { recipientKeyIndex: UInt32, accountReference: UInt32, encryptedPublicKey: Data, + coreHeightCreatedAt: UInt32, createdAt: UInt64 ) throws -> ContactRequest { var handle: Handle = NULL_HANDLE @@ -36,7 +37,8 @@ public class ContactRequest { recipientKeyIndex, accountReference, keyPtr.baseAddress?.assumingMemoryBound(to: UInt8.self), - encryptedPublicKey.count, + UInt(encryptedPublicKey.count), + coreHeightCreatedAt, createdAt, &handle, &error @@ -118,7 +120,7 @@ public class ContactRequest { /// Get the encrypted public key public func getEncryptedPublicKey() throws -> Data { var bytesPtr: UnsafeMutablePointer? = nil - var length: Int = 0 + var length: UInt = 0 var error = PlatformWalletFFIError() let result = contact_request_get_encrypted_public_key(handle, &bytesPtr, &length, &error) @@ -128,7 +130,7 @@ public class ContactRequest { defer { if let ptr = bytesPtr { - platform_wallet_bytes_free(ptr) + platform_wallet_bytes_free(ptr, length) } } @@ -136,7 +138,7 @@ public class ContactRequest { throw PlatformWalletError.nullPointer } - return Data(bytes: ptr, count: length) + return Data(bytes: ptr, count: Int(length)) } /// Get the creation timestamp diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/DashPayService.swift b/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/DashPayService.swift index 47623c7f533..cdf4fad323d 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/DashPayService.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/DashPayService.swift @@ -124,24 +124,31 @@ public final class DashPayService: Sendable { /// - identity: The identity sending the request /// - recipientId: The recipient's identity ID /// - encryptedPublicKey: Encrypted public key for secure communication + /// - coreHeightCreatedAt: Core chain height when the request was created + /// - createdAt: Creation timestamp (ms since epoch) /// - Throws: Error if sending fails public func sendContactRequest( from identity: ManagedIdentity, to recipientId: Identifier, - encryptedPublicKey: Data + encryptedPublicKey: Data, + coreHeightCreatedAt: UInt32 = 0, + createdAt: UInt64 = UInt64(Date().timeIntervalSince1970 * 1000) ) throws { - // In a real implementation, you would: - // 1. Derive the appropriate keys - // 2. Encrypt your public key with recipient's key - // 3. Create and broadcast the contact request - - try identity.sendContactRequest( + // Build the contact request object, then hand it off to the FFI layer. + // Real callers should derive key indices from the identity/recipient. + let senderId = try identity.getId() + let request = try ContactRequest.create( + senderId: senderId, recipientId: recipientId, - senderKeyIndex: 0, // Should be derived from identity keys - recipientKeyIndex: 0, // Should be looked up from recipient + senderKeyIndex: 0, // Should be derived from identity keys + recipientKeyIndex: 0, // Should be looked up from recipient accountReference: 0, - encryptedPublicKey: encryptedPublicKey + encryptedPublicKey: encryptedPublicKey, + coreHeightCreatedAt: coreHeightCreatedAt, + createdAt: createdAt ) + + try identity.sendContactRequest(request) } /// Accept a contact request @@ -150,7 +157,10 @@ public final class DashPayService: Sendable { /// - senderId: The sender's identity ID /// - Throws: Error if acceptance fails public func acceptContactRequest(identity: ManagedIdentity, from senderId: Identifier) throws { - try identity.acceptContactRequest(senderId: senderId) + guard let request = try identity.getIncomingContactRequest(senderId: senderId) else { + throw PlatformWalletError.contactNotFound + } + try identity.acceptContactRequest(request) } /// Reject a contact request diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/EstablishedContact.swift b/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/EstablishedContact.swift index 12e068850c7..70cef8f71bb 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/EstablishedContact.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/EstablishedContact.swift @@ -10,7 +10,7 @@ public class EstablishedContact { } deinit { - established_contact_destroy(handle) + _ = established_contact_destroy(handle) } /// Get the contact's identity ID diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/IdentityManager.swift b/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/IdentityManager.swift index cd53dbb1902..b7bdbc65825 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/IdentityManager.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/IdentityManager.swift @@ -10,7 +10,7 @@ public class IdentityManager { } deinit { - identity_manager_destroy(handle) + _ = identity_manager_destroy(handle) } /// Create a new empty Identity Manager @@ -80,9 +80,8 @@ public class IdentityManager { } var identifiers: [Identifier] = [] - for i in 0.. Int { - var count: Int = 0 + var count: UInt = 0 var error = PlatformWalletFFIError() let result = identity_manager_get_identity_count(handle, &count, &error) @@ -127,6 +126,6 @@ public class IdentityManager { throw PlatformWalletError(result: result, error: error) } - return count + return Int(count) } } diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/ManagedIdentity.swift b/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/ManagedIdentity.swift index 6cc591bd2a7..4b825e5ebd9 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/ManagedIdentity.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/ManagedIdentity.swift @@ -10,7 +10,7 @@ public class ManagedIdentity { } deinit { - managed_identity_destroy(handle) + _ = managed_identity_destroy(handle) } /// Create a ManagedIdentity from identity bytes @@ -21,7 +21,7 @@ public class ManagedIdentity { let result = bytes.withUnsafeBytes { bytesPtr in managed_identity_create_from_identity_bytes( bytesPtr.baseAddress?.assumingMemoryBound(to: UInt8.self), - bytes.count, + UInt(bytes.count), &handle, &error ) @@ -44,7 +44,7 @@ public class ManagedIdentity { throw PlatformWalletError(result: result, error: error) } - return identifierFromFFI( ffiId) + return identifierFromFFI(ffiId) } /// Get the identity balance @@ -100,8 +100,8 @@ public class ManagedIdentity { } /// Get the last updated balance block time - public func getLastUpdatedBalanceBlockTime() throws -> BlockTime? { - var ffiBlockTime = FFIBlockTime(height: 0, core_height: 0, timestamp: 0) + public func getLastUpdatedBalanceBlockTime() throws -> PlatformBlockTime? { + var ffiBlockTime = BlockTime(height: 0, core_height: 0, timestamp: 0) var error = PlatformWalletFFIError() let result = managed_identity_get_last_updated_balance_block_time(handle, &ffiBlockTime, &error) @@ -114,11 +114,11 @@ public class ManagedIdentity { throw PlatformWalletError(result: result, error: error) } - return BlockTime(ffiBlockTime: ffiBlockTime) + return PlatformBlockTime(ffi: ffiBlockTime) } /// Set the last updated balance block time - public func setLastUpdatedBalanceBlockTime(_ blockTime: BlockTime) throws { + public func setLastUpdatedBalanceBlockTime(_ blockTime: PlatformBlockTime) throws { var error = PlatformWalletFFIError() let ffiBlockTime = blockTime.ffiValue @@ -129,8 +129,8 @@ public class ManagedIdentity { } /// Get the last synced keys block time - public func getLastSyncedKeysBlockTime() throws -> BlockTime? { - var ffiBlockTime = FFIBlockTime(height: 0, core_height: 0, timestamp: 0) + public func getLastSyncedKeysBlockTime() throws -> PlatformBlockTime? { + var ffiBlockTime = BlockTime(height: 0, core_height: 0, timestamp: 0) var error = PlatformWalletFFIError() let result = managed_identity_get_last_synced_keys_block_time(handle, &ffiBlockTime, &error) @@ -143,7 +143,7 @@ public class ManagedIdentity { throw PlatformWalletError(result: result, error: error) } - return BlockTime(ffiBlockTime: ffiBlockTime) + return PlatformBlockTime(ffi: ffiBlockTime) } // MARK: - Contact Request Management @@ -167,9 +167,8 @@ public class ManagedIdentity { } var identifiers: [Identifier] = [] - for i in 0.. PlatformWallet { + public static func fromSeed(_ seed: Data, network: PlatformNetwork = .testnet) throws -> PlatformWallet { guard seed.count == 64 else { throw PlatformWalletError.invalidParameter } @@ -25,8 +25,9 @@ public class PlatformWallet { let result = seed.withUnsafeBytes { seedPtr in platform_wallet_info_create_from_seed( + network.ffiValue, seedPtr.baseAddress?.assumingMemoryBound(to: UInt8.self), - seed.count, + UInt(seed.count), &handle, &error ) @@ -40,7 +41,11 @@ public class PlatformWallet { } /// Create a new Platform Wallet from a BIP39 mnemonic phrase - public static func fromMnemonic(_ mnemonic: String, passphrase: String? = nil) throws -> PlatformWallet { + public static func fromMnemonic( + _ mnemonic: String, + passphrase: String? = nil, + network: PlatformNetwork = .testnet + ) throws -> PlatformWallet { var handle: Handle = NULL_HANDLE var error = PlatformWalletFFIError() @@ -48,6 +53,7 @@ public class PlatformWallet { let passphraseCStr = passphrase != nil ? (passphrase! as NSString).utf8String : nil let result = platform_wallet_info_create_from_mnemonic( + network.ffiValue, mnemonicCStr, passphraseCStr, &handle, @@ -73,7 +79,6 @@ public class PlatformWallet { let result = platform_wallet_info_get_identity_manager( handle, - network.ffiValue, &managerHandle, &error ) @@ -93,7 +98,6 @@ public class PlatformWallet { let result = platform_wallet_info_set_identity_manager( handle, - network.ffiValue, manager.handle, &error ) diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/PlatformWalletFFI.swift b/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/PlatformWalletFFI.swift deleted file mode 100644 index e0b0215c14a..00000000000 --- a/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/PlatformWalletFFI.swift +++ /dev/null @@ -1,403 +0,0 @@ -// Platform Wallet FFI function declarations -// Since these aren't in the C header, we declare them with @_silgen_name - -import Foundation - -// MARK: - PlatformWalletInfo Functions - -@_silgen_name("platform_wallet_info_create_from_seed") -func platform_wallet_info_create_from_seed( - _ seed: UnsafePointer?, - _ seed_len: Int, - _ out_handle: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("platform_wallet_info_create_from_mnemonic") -func platform_wallet_info_create_from_mnemonic( - _ mnemonic: UnsafePointer?, - _ passphrase: UnsafePointer?, - _ out_handle: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("platform_wallet_info_get_identity_manager") -func platform_wallet_info_get_identity_manager( - _ wallet_handle: Handle, - _ network: NetworkType, - _ out_manager_handle: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("platform_wallet_info_set_identity_manager") -func platform_wallet_info_set_identity_manager( - _ wallet_handle: Handle, - _ network: NetworkType, - _ manager_handle: Handle, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("platform_wallet_info_destroy") -func platform_wallet_info_destroy(_ handle: Handle) - -// MARK: - IdentityManager Functions - -@_silgen_name("identity_manager_create") -func identity_manager_create( - _ out_handle: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("identity_manager_add_identity") -func identity_manager_add_identity( - _ manager_handle: Handle, - _ identity_handle: Handle, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("identity_manager_remove_identity") -func identity_manager_remove_identity( - _ manager_handle: Handle, - _ identity_id: IdentifierBytes, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("identity_manager_get_identity") -func identity_manager_get_identity( - _ manager_handle: Handle, - _ identity_id: IdentifierBytes, - _ out_identity_handle: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("identity_manager_get_all_identity_ids") -func identity_manager_get_all_identity_ids( - _ manager_handle: Handle, - _ out_array: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("identity_manager_get_primary_identity_id") -func identity_manager_get_primary_identity_id( - _ manager_handle: Handle, - _ out_id: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("identity_manager_set_primary_identity") -func identity_manager_set_primary_identity( - _ manager_handle: Handle, - _ identity_id: IdentifierBytes, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("identity_manager_get_identity_count") -func identity_manager_get_identity_count( - _ manager_handle: Handle, - _ out_count: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("identity_manager_destroy") -func identity_manager_destroy(_ handle: Handle) - -// MARK: - ManagedIdentity Functions - -@_silgen_name("managed_identity_create_from_identity_bytes") -func managed_identity_create_from_identity_bytes( - _ bytes: UnsafePointer?, - _ bytes_len: Int, - _ out_handle: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_get_id") -func managed_identity_get_id( - _ identity_handle: Handle, - _ out_id: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_get_balance") -func managed_identity_get_balance( - _ identity_handle: Handle, - _ out_balance: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_get_label") -func managed_identity_get_label( - _ identity_handle: Handle, - _ out_label: UnsafeMutablePointer?>, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_set_label") -func managed_identity_set_label( - _ identity_handle: Handle, - _ label: UnsafePointer?, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_get_last_updated_balance_block_time") -func managed_identity_get_last_updated_balance_block_time( - _ identity_handle: Handle, - _ out_block_time: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_set_last_updated_balance_block_time") -func managed_identity_set_last_updated_balance_block_time( - _ identity_handle: Handle, - _ block_time: FFIBlockTime, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_get_last_synced_keys_block_time") -func managed_identity_get_last_synced_keys_block_time( - _ identity_handle: Handle, - _ out_block_time: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_get_sent_contact_request_ids") -func managed_identity_get_sent_contact_request_ids( - _ identity_handle: Handle, - _ out_array: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_get_incoming_contact_request_ids") -func managed_identity_get_incoming_contact_request_ids( - _ identity_handle: Handle, - _ out_array: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_get_established_contact_ids") -func managed_identity_get_established_contact_ids( - _ identity_handle: Handle, - _ out_array: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_get_sent_contact_request") -func managed_identity_get_sent_contact_request( - _ identity_handle: Handle, - _ recipient_id: IdentifierBytes, - _ out_request_handle: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_get_incoming_contact_request") -func managed_identity_get_incoming_contact_request( - _ identity_handle: Handle, - _ sender_id: IdentifierBytes, - _ out_request_handle: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_get_established_contact") -func managed_identity_get_established_contact( - _ identity_handle: Handle, - _ contact_id: IdentifierBytes, - _ out_contact_handle: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_is_contact_established") -func managed_identity_is_contact_established( - _ identity_handle: Handle, - _ contact_id: IdentifierBytes, - _ out_is_established: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_send_contact_request") -func managed_identity_send_contact_request( - _ identity_handle: Handle, - _ recipient_id: IdentifierBytes, - _ sender_key_index: UInt32, - _ recipient_key_index: UInt32, - _ account_reference: UInt32, - _ encrypted_public_key: UnsafePointer?, - _ encrypted_public_key_len: Int, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_accept_contact_request") -func managed_identity_accept_contact_request( - _ identity_handle: Handle, - _ sender_id: IdentifierBytes, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_reject_contact_request") -func managed_identity_reject_contact_request( - _ identity_handle: Handle, - _ sender_id: IdentifierBytes, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("managed_identity_destroy") -func managed_identity_destroy(_ handle: Handle) - -// MARK: - ContactRequest Functions - -@_silgen_name("contact_request_create") -func contact_request_create( - _ sender_id: IdentifierBytes, - _ recipient_id: IdentifierBytes, - _ sender_key_index: UInt32, - _ recipient_key_index: UInt32, - _ account_reference: UInt32, - _ encrypted_public_key: UnsafePointer?, - _ encrypted_public_key_len: Int, - _ created_at: UInt64, - _ out_handle: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("contact_request_get_sender_id") -func contact_request_get_sender_id( - _ request_handle: Handle, - _ out_id: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("contact_request_get_recipient_id") -func contact_request_get_recipient_id( - _ request_handle: Handle, - _ out_id: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("contact_request_get_sender_key_index") -func contact_request_get_sender_key_index( - _ request_handle: Handle, - _ out_index: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("contact_request_get_recipient_key_index") -func contact_request_get_recipient_key_index( - _ request_handle: Handle, - _ out_index: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("contact_request_get_account_reference") -func contact_request_get_account_reference( - _ request_handle: Handle, - _ out_reference: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("contact_request_get_encrypted_public_key") -func contact_request_get_encrypted_public_key( - _ request_handle: Handle, - _ out_bytes: UnsafeMutablePointer?>, - _ out_len: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("contact_request_get_created_at") -func contact_request_get_created_at( - _ request_handle: Handle, - _ out_timestamp: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("contact_request_destroy") -func contact_request_destroy(_ handle: Handle) - -// MARK: - EstablishedContact Functions - -@_silgen_name("established_contact_get_contact_identity_id") -func established_contact_get_contact_identity_id( - _ contact_handle: Handle, - _ out_id: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("established_contact_get_alias") -func established_contact_get_alias( - _ contact_handle: Handle, - _ out_alias: UnsafeMutablePointer?>, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("established_contact_set_alias") -func established_contact_set_alias( - _ contact_handle: Handle, - _ alias: UnsafePointer?, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("established_contact_clear_alias") -func established_contact_clear_alias( - _ contact_handle: Handle, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("established_contact_get_note") -func established_contact_get_note( - _ contact_handle: Handle, - _ out_note: UnsafeMutablePointer?>, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("established_contact_set_note") -func established_contact_set_note( - _ contact_handle: Handle, - _ note: UnsafePointer?, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("established_contact_clear_note") -func established_contact_clear_note( - _ contact_handle: Handle, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("established_contact_is_hidden") -func established_contact_is_hidden( - _ contact_handle: Handle, - _ out_is_hidden: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("established_contact_hide") -func established_contact_hide( - _ contact_handle: Handle, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("established_contact_unhide") -func established_contact_unhide( - _ contact_handle: Handle, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("established_contact_destroy") -func established_contact_destroy(_ handle: Handle) - -// MARK: - Utility Functions - -@_silgen_name("platform_wallet_generate_random_identifier") -func platform_wallet_generate_random_identifier( - _ out_id: UnsafeMutablePointer, - _ out_error: UnsafeMutablePointer -) -> PlatformWalletFFIResult - -@_silgen_name("platform_wallet_identifier_array_free") -func platform_wallet_identifier_array_free(_ array: IdentifierArray) - -@_silgen_name("platform_wallet_string_free") -func platform_wallet_string_free(_ string: UnsafeMutablePointer) - -@_silgen_name("platform_wallet_bytes_free") -func platform_wallet_bytes_free(_ bytes: UnsafeMutablePointer) - -@_silgen_name("platform_wallet_ffi_error_free") -func platform_wallet_ffi_error_free(_ error: PlatformWalletFFIError) diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/PlatformWalletTypes.swift b/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/PlatformWalletTypes.swift index 44062256899..c6c2aaf1221 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/PlatformWalletTypes.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/PlatformWalletTypes.swift @@ -1,51 +1,24 @@ import Foundation import DashSDKFFI -// FFI types from platform-wallet-ffi (not in C header, so we define them here) -// These match the Rust definitions in rs-platform-wallet-ffi - -typealias Handle = UInt64 let NULL_HANDLE: Handle = 0 -struct IdentifierBytes { - var bytes: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, - UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, - UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, - UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) -} - -struct IdentifierArray { - var items: UnsafeMutablePointer? - var count: Int -} - -typealias NetworkType = UInt32 - -typealias PlatformWalletFFIResult = Int32 - -struct PlatformWalletFFIError { - var message: UnsafePointer? -} - -struct FFIBlockTime { - var height: UInt32 - var core_height: UInt32 - var timestamp: UInt64 -} -// Error result codes (must match Rust enum values) -let Success: PlatformWalletFFIResult = 0 -let ErrorNullPointer: PlatformWalletFFIResult = 1 -let ErrorInvalidHandle: PlatformWalletFFIResult = 2 -let ErrorInvalidParameter: PlatformWalletFFIResult = 3 -let ErrorInvalidIdentifier: PlatformWalletFFIResult = 4 -let ErrorInvalidNetwork: PlatformWalletFFIResult = 5 -let ErrorWalletOperation: PlatformWalletFFIResult = 6 -let ErrorIdentityNotFound: PlatformWalletFFIResult = 7 -let ErrorContactNotFound: PlatformWalletFFIResult = 8 -let ErrorUtf8Conversion: PlatformWalletFFIResult = 9 -let ErrorSerialization: PlatformWalletFFIResult = 10 -let ErrorDeserialization: PlatformWalletFFIResult = 11 +// Friendly aliases for the C enum cases that call sites compare against. +let Success: PlatformWalletFFIResult = PLATFORM_WALLET_FFI_RESULT_SUCCESS +let ErrorInvalidHandle: PlatformWalletFFIResult = PLATFORM_WALLET_FFI_RESULT_ERROR_INVALID_HANDLE +let ErrorInvalidParameter: PlatformWalletFFIResult = PLATFORM_WALLET_FFI_RESULT_ERROR_INVALID_PARAMETER +let ErrorNullPointer: PlatformWalletFFIResult = PLATFORM_WALLET_FFI_RESULT_ERROR_NULL_POINTER +let ErrorSerialization: PlatformWalletFFIResult = PLATFORM_WALLET_FFI_RESULT_ERROR_SERIALIZATION +let ErrorDeserialization: PlatformWalletFFIResult = PLATFORM_WALLET_FFI_RESULT_ERROR_DESERIALIZATION +let ErrorWalletOperation: PlatformWalletFFIResult = PLATFORM_WALLET_FFI_RESULT_ERROR_WALLET_OPERATION +let ErrorIdentityNotFound: PlatformWalletFFIResult = PLATFORM_WALLET_FFI_RESULT_ERROR_IDENTITY_NOT_FOUND +let ErrorContactNotFound: PlatformWalletFFIResult = PLATFORM_WALLET_FFI_RESULT_ERROR_CONTACT_NOT_FOUND +let ErrorInvalidNetwork: PlatformWalletFFIResult = PLATFORM_WALLET_FFI_RESULT_ERROR_INVALID_NETWORK +let ErrorInvalidIdentifier: PlatformWalletFFIResult = PLATFORM_WALLET_FFI_RESULT_ERROR_INVALID_IDENTIFIER +let ErrorMemoryAllocation: PlatformWalletFFIResult = PLATFORM_WALLET_FFI_RESULT_ERROR_MEMORY_ALLOCATION +let ErrorUtf8Conversion: PlatformWalletFFIResult = PLATFORM_WALLET_FFI_RESULT_ERROR_UTF8_CONVERSION +let ErrorUnknown: PlatformWalletFFIResult = PLATFORM_WALLET_FFI_RESULT_ERROR_UNKNOWN /// Platform Wallet error types public enum PlatformWalletError: Error { @@ -60,72 +33,77 @@ public enum PlatformWalletError: Error { case utf8Conversion case serialization case deserialization + case memoryAllocation case unknown(String) init(result: PlatformWalletFFIResult, error: PlatformWalletFFIError) { let message = error.message != nil ? String(cString: error.message!) : "Unknown error" switch result { - case ErrorNullPointer: + case PLATFORM_WALLET_FFI_RESULT_ERROR_NULL_POINTER: self = .nullPointer - case ErrorInvalidHandle: + case PLATFORM_WALLET_FFI_RESULT_ERROR_INVALID_HANDLE: self = .invalidHandle - case ErrorInvalidParameter: + case PLATFORM_WALLET_FFI_RESULT_ERROR_INVALID_PARAMETER: self = .invalidParameter - case ErrorInvalidIdentifier: + case PLATFORM_WALLET_FFI_RESULT_ERROR_INVALID_IDENTIFIER: self = .invalidIdentifier - case ErrorInvalidNetwork: + case PLATFORM_WALLET_FFI_RESULT_ERROR_INVALID_NETWORK: self = .invalidNetwork - case ErrorWalletOperation: + case PLATFORM_WALLET_FFI_RESULT_ERROR_WALLET_OPERATION: self = .walletOperation(message) - case ErrorIdentityNotFound: + case PLATFORM_WALLET_FFI_RESULT_ERROR_IDENTITY_NOT_FOUND: self = .identityNotFound - case ErrorContactNotFound: + case PLATFORM_WALLET_FFI_RESULT_ERROR_CONTACT_NOT_FOUND: self = .contactNotFound - case ErrorUtf8Conversion: + case PLATFORM_WALLET_FFI_RESULT_ERROR_UTF8_CONVERSION: self = .utf8Conversion - case ErrorSerialization: + case PLATFORM_WALLET_FFI_RESULT_ERROR_SERIALIZATION: self = .serialization - case ErrorDeserialization: + case PLATFORM_WALLET_FFI_RESULT_ERROR_DESERIALIZATION: self = .deserialization + case PLATFORM_WALLET_FFI_RESULT_ERROR_MEMORY_ALLOCATION: + self = .memoryAllocation + case PLATFORM_WALLET_FFI_RESULT_ERROR_UNKNOWN: + self = .unknown(message) + case PLATFORM_WALLET_FFI_RESULT_SUCCESS: + assertionFailure("Error initialized from a success result") + self = .unknown("Error initialized from a success result") default: self = .unknown(message) } } } -/// Network type for Platform wallet +/// Network type used by the Swift-facing Platform wallet API. +/// Raw values match the `FFINetwork` C enum from key-wallet-ffi. public enum PlatformNetwork: UInt32 { case mainnet = 0 case testnet = 1 - case devnet = 2 - case local = 3 + case regtest = 2 + case devnet = 3 - var ffiValue: NetworkType { - NetworkType(self.rawValue) + /// Value to pass to FFI calls that expect `FFINetwork`. + var ffiValue: FFINetwork { + FFINetwork(rawValue: self.rawValue) } } -/// Block time information -public struct BlockTime { - public let height: UInt32 +/// Swift-friendly block time. Wraps the C `BlockTime` struct (fields are +/// UInt64/UInt32/UInt64 there — we keep the same widths). +public struct PlatformBlockTime { + public let height: UInt64 public let coreHeight: UInt32 public let timestamp: UInt64 - public init(height: UInt32, coreHeight: UInt32, timestamp: UInt64) { - self.height = height - self.coreHeight = coreHeight - self.timestamp = timestamp + init(ffi: BlockTime) { + self.height = ffi.height + self.coreHeight = ffi.core_height + self.timestamp = ffi.timestamp } - init(ffiBlockTime: FFIBlockTime) { - self.height = ffiBlockTime.height - self.coreHeight = ffiBlockTime.core_height - self.timestamp = ffiBlockTime.timestamp - } - - var ffiValue: FFIBlockTime { - FFIBlockTime( + var ffiValue: BlockTime { + BlockTime( height: self.height, core_height: self.coreHeight, timestamp: self.timestamp @@ -154,19 +132,6 @@ func identifierFromFFI(_ ffiIdentifier: IdentifierBytes) -> Identifier { return withUnsafeBytes(of: &bytesArray) { Data($0) } } -/// Generate a random identifier -public func generateRandomIdentifier() throws -> Identifier { - var ffiId = IdentifierBytes(bytes: (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)) - var error = PlatformWalletFFIError() - - let result = platform_wallet_generate_random_identifier(&ffiId, &error) - guard result == Success else { - throw PlatformWalletError(result: result, error: error) - } - - return identifierFromFFI(ffiId) -} - extension Data { public init?(hexString: String) { let len = hexString.count / 2 diff --git a/packages/swift-sdk/build_ios.sh b/packages/swift-sdk/build_ios.sh index 540bdf9ba14..ebe6a5f9118 100755 --- a/packages/swift-sdk/build_ios.sh +++ b/packages/swift-sdk/build_ios.sh @@ -131,6 +131,7 @@ inject_modulemap() { // key-wallet-ffi defines FFINetwork used by dash-spv-ffi, so must come first #include "key-wallet-ffi/key-wallet-ffi.h" #include "dash-spv-ffi/dash-spv-ffi.h" +#include "platform-wallet-ffi/platform-wallet-ffi.h" #include "rs-sdk-ffi/rs-sdk-ffi.h" #endif