From 629a3d1ef646e1004cee25d7be1e9d31244eba91 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Mon, 2 Feb 2026 18:48:15 -0300 Subject: [PATCH 01/11] scaffolding --- Cargo.lock | 1 + wallet-ffi/Cargo.toml | 5 +++- wallet-ffi/tests/ffi.rs | 65 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 wallet-ffi/tests/ffi.rs diff --git a/Cargo.lock b/Cargo.lock index 8cd4da9a..21fd7798 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6738,6 +6738,7 @@ dependencies = [ "cbindgen", "common", "nssa", + "tempfile", "tokio", "wallet", ] diff --git a/wallet-ffi/Cargo.toml b/wallet-ffi/Cargo.toml index bc989fea..c02e58ee 100644 --- a/wallet-ffi/Cargo.toml +++ b/wallet-ffi/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [lib] -crate-type = ["cdylib", "staticlib"] +crate-type = ["rlib", "cdylib", "staticlib"] [dependencies] wallet.workspace = true @@ -14,3 +14,6 @@ tokio.workspace = true [build-dependencies] cbindgen = "0.26" + +[dev-dependencies] +tempfile = "3" diff --git a/wallet-ffi/tests/ffi.rs b/wallet-ffi/tests/ffi.rs new file mode 100644 index 00000000..43d22063 --- /dev/null +++ b/wallet-ffi/tests/ffi.rs @@ -0,0 +1,65 @@ +use std::ffi::{c_char, CString}; + +use wallet::WalletCore; +use wallet_ffi::{error, FfiBytes32, FfiError, WalletHandle}; + +extern "C" { + fn wallet_ffi_init_runtime() -> error::WalletFfiError; + + fn wallet_ffi_destroy(handle: *mut WalletHandle); + + fn wallet_ffi_create_account_public( + handle: *mut WalletHandle, + out_account_id: *mut FfiBytes32, + ) -> error::WalletFfiError; + + fn wallet_ffi_create_new( + config_path: *const c_char, + storage_path: *const c_char, + password: *const c_char, + ) -> *mut WalletHandle; + + fn wallet_ffi_save(handle: *mut WalletHandle) -> error::WalletFfiError; +} + +use tempfile::tempdir; + +#[test] +fn test() { + unsafe { + let result = wallet_ffi_init_runtime(); + println!("wallet init runtim result: {:?}", result); + } + + let tempdir = tempdir().unwrap(); + let config_path = tempdir.path().join("wallet_config.json"); + let storage_path = tempdir.path().join("storage.json"); + let config_path_c = CString::new(config_path.to_str().unwrap()).unwrap(); + let storage_path_c = CString::new(storage_path.to_str().unwrap()).unwrap(); + let password = CString::new("").unwrap(); + + unsafe { + let wallet_handle = wallet_ffi_create_new( + config_path_c.as_ptr(), + storage_path_c.as_ptr(), + password.as_ptr(), + ); + + let mut out_account_id = FfiBytes32::from_bytes([0; 32]); + + let result = wallet_ffi_create_account_public( + wallet_handle, + (&mut out_account_id) as *mut FfiBytes32, + ); + println!("{:?}", out_account_id.data); + println!("create result: {:?}", result); + + let result = wallet_ffi_save(wallet_handle); + println!("save result: {:?}", result); + + wallet_ffi_destroy(wallet_handle); + } + // let mut wallet_core = WalletCore::new_update_chain(config_path.to_path_buf(), + // storage_path.to_path_buf(), None).unwrap(); let (account_id, _) = + // wallet_core.create_new_account_public(None); println!("{:?}", account_id); +} From 35b469d7380a4c0b487b144bb5dd88e2ceef9d4d Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Tue, 3 Feb 2026 10:43:05 -0300 Subject: [PATCH 02/11] add tests --- wallet-ffi/src/account.rs | 1 + wallet-ffi/tests/ffi.rs | 138 ++++++++++++++++++++++++++++---------- 2 files changed, 102 insertions(+), 37 deletions(-) diff --git a/wallet-ffi/src/account.rs b/wallet-ffi/src/account.rs index b99d10cf..e5fa84b0 100644 --- a/wallet-ffi/src/account.rs +++ b/wallet-ffi/src/account.rs @@ -101,6 +101,7 @@ pub unsafe extern "C" fn wallet_ffi_create_account_private( }; let (account_id, _chain_index) = wallet.create_new_account_private(None); + println!("_chain_index: {_chain_index}"); unsafe { (*out_account_id).data = *account_id.value(); diff --git a/wallet-ffi/tests/ffi.rs b/wallet-ffi/tests/ffi.rs index 43d22063..70a82874 100644 --- a/wallet-ffi/tests/ffi.rs +++ b/wallet-ffi/tests/ffi.rs @@ -1,18 +1,23 @@ -use std::ffi::{c_char, CString}; +use std::{ + ffi::{c_char, CString}, + path::Path, +}; +use tokio::runtime::Handle; use wallet::WalletCore; use wallet_ffi::{error, FfiBytes32, FfiError, WalletHandle}; extern "C" { - fn wallet_ffi_init_runtime() -> error::WalletFfiError; - - fn wallet_ffi_destroy(handle: *mut WalletHandle); - fn wallet_ffi_create_account_public( handle: *mut WalletHandle, out_account_id: *mut FfiBytes32, ) -> error::WalletFfiError; + fn wallet_ffi_create_account_private( + handle: *mut WalletHandle, + out_account_id: *mut FfiBytes32, + ) -> error::WalletFfiError; + fn wallet_ffi_create_new( config_path: *const c_char, storage_path: *const c_char, @@ -24,42 +29,101 @@ extern "C" { use tempfile::tempdir; -#[test] -fn test() { - unsafe { - let result = wallet_ffi_init_runtime(); - println!("wallet init runtim result: {:?}", result); - } - +unsafe fn new_wallet_ffi_for_tests(password: &str) -> *mut WalletHandle { let tempdir = tempdir().unwrap(); let config_path = tempdir.path().join("wallet_config.json"); let storage_path = tempdir.path().join("storage.json"); let config_path_c = CString::new(config_path.to_str().unwrap()).unwrap(); let storage_path_c = CString::new(storage_path.to_str().unwrap()).unwrap(); - let password = CString::new("").unwrap(); + let password = CString::new(password).unwrap(); - unsafe { - let wallet_handle = wallet_ffi_create_new( - config_path_c.as_ptr(), - storage_path_c.as_ptr(), - password.as_ptr(), - ); - - let mut out_account_id = FfiBytes32::from_bytes([0; 32]); - - let result = wallet_ffi_create_account_public( - wallet_handle, - (&mut out_account_id) as *mut FfiBytes32, - ); - println!("{:?}", out_account_id.data); - println!("create result: {:?}", result); - - let result = wallet_ffi_save(wallet_handle); - println!("save result: {:?}", result); - - wallet_ffi_destroy(wallet_handle); - } - // let mut wallet_core = WalletCore::new_update_chain(config_path.to_path_buf(), - // storage_path.to_path_buf(), None).unwrap(); let (account_id, _) = - // wallet_core.create_new_account_public(None); println!("{:?}", account_id); + wallet_ffi_create_new( + config_path_c.as_ptr(), + storage_path_c.as_ptr(), + password.as_ptr(), + ) +} + +fn new_wallet_rust_for_tests(password: &str) -> WalletCore { + let tempdir = tempdir().unwrap(); + let config_path = tempdir.path().join("wallet_config.json"); + let storage_path = tempdir.path().join("storage.json"); + + WalletCore::new_init_storage( + config_path.to_path_buf(), + storage_path.to_path_buf(), + None, + password.to_string(), + ) + .unwrap() +} + +#[test] +fn test_create_public_accounts() { + let password = "password_for_tests"; + let n_accounts = 10; + // First `n_accounts` public accounts created with Rust wallet + let new_public_account_ids_rust = { + let mut account_ids = Vec::new(); + + let mut wallet_rust = new_wallet_rust_for_tests(password); + for _ in 0..n_accounts { + let account_id = wallet_rust.create_new_account_public(None).0; + account_ids.push(*account_id.value()); + } + account_ids + }; + + // First `n_accounts` public accounts created with wallet FFI + let new_public_account_ids_ffi = unsafe { + let mut account_ids = Vec::new(); + + let wallet_ffi_handle = new_wallet_ffi_for_tests(password); + for _ in 0..n_accounts { + let mut out_account_id = FfiBytes32::from_bytes([0; 32]); + wallet_ffi_create_account_public( + wallet_ffi_handle, + (&mut out_account_id) as *mut FfiBytes32, + ); + account_ids.push(out_account_id.data); + } + account_ids + }; + + assert_eq!(new_public_account_ids_ffi, new_public_account_ids_rust) +} + +#[test] +fn test_create_private_accounts() { + let password = "password_for_tests"; + let n_accounts = 10; + // First `n_accounts` private accounts created with Rust wallet + let new_private_account_ids_rust = { + let mut account_ids = Vec::new(); + + let mut wallet_rust = new_wallet_rust_for_tests(password); + for _ in 0..n_accounts { + let account_id = wallet_rust.create_new_account_private(None).0; + account_ids.push(*account_id.value()); + } + account_ids + }; + + // First `n_accounts` private accounts created with wallet FFI + let new_private_account_ids_ffi = unsafe { + let mut account_ids = Vec::new(); + + let wallet_ffi_handle = new_wallet_ffi_for_tests(password); + for _ in 0..n_accounts { + let mut out_account_id = FfiBytes32::from_bytes([0; 32]); + wallet_ffi_create_account_private( + wallet_ffi_handle, + (&mut out_account_id) as *mut FfiBytes32, + ); + account_ids.push(out_account_id.data); + } + account_ids + }; + + assert_eq!(new_private_account_ids_ffi, new_private_account_ids_rust) } From 50b253fa000f0c507bc34c0870586d2a835816bb Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Tue, 3 Feb 2026 19:04:41 -0300 Subject: [PATCH 03/11] move ffi tests to integration tests --- Cargo.lock | 663 +++++++++++++------------- integration_tests/Cargo.toml | 2 + integration_tests/src/lib.rs | 23 +- integration_tests/tests/wallet_ffi.rs | 285 +++++++++++ wallet-ffi/tests/ffi.rs | 129 ----- wallet/src/config.rs | 2 +- wallet/src/lib.rs | 17 +- 7 files changed, 666 insertions(+), 455 deletions(-) create mode 100644 integration_tests/tests/wallet_ffi.rs delete mode 100644 wallet-ffi/tests/ffi.rs diff --git a/Cargo.lock b/Cargo.lock index 21fd7798..11f0cb7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -73,7 +73,7 @@ dependencies = [ "bitflags 2.10.0", "bytes", "bytestring", - "derive_more 2.1.0", + "derive_more 2.1.1", "encoding_rs", "foldhash", "futures-core", @@ -102,7 +102,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -215,7 +215,7 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -226,7 +226,7 @@ checksum = "b6ac1e58cded18cb28ddc17143c4dea5345b3ad575e14f32f66e4054a56eb271" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -270,7 +270,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "once_cell", "version_check", ] @@ -447,7 +447,7 @@ checksum = "e7e89fe77d1f0f4fe5b96dfc940923d88d17b6a773808124f21e764dfb063c6a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -545,7 +545,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -571,7 +571,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -717,7 +717,7 @@ checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -801,7 +801,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -812,7 +812,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -866,7 +866,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper", "tokio", - "tower 0.5.2", + "tower 0.5.3", "tower-layer", "tower-service", "tracing", @@ -929,9 +929,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.1" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e050f626429857a27ddccb31e0aca21356bfa709c04041aefddac081a8f068a" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bedrock_client" @@ -972,7 +972,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1054,7 +1054,7 @@ dependencies = [ "maybe-async", "reqwest", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -1077,7 +1077,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1097,9 +1097,9 @@ checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "bytemuck" -version = "1.24.0" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" dependencies = [ "bytemuck_derive", ] @@ -1112,7 +1112,7 @@ checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1178,7 +1178,7 @@ dependencies = [ "semver", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -1202,9 +1202,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.49" +version = "1.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" dependencies = [ "find-msvc-tools", "jobserver", @@ -1247,7 +1247,7 @@ checksum = "45565fc9416b9896014f5732ac776f810ee53a66730c17e4020c3ec064a8f88f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1263,9 +1263,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" dependencies = [ "iana-time-zone", "js-sys", @@ -1313,9 +1313,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.53" +version = "4.5.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +checksum = "a75ca66430e33a14957acc24c5077b503e7d374151b2b4b3a10c83b4ceb4be0e" dependencies = [ "clap_builder", "clap_derive", @@ -1323,26 +1323,26 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.53" +version = "4.5.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +checksum = "793207c7fa6300a0608d1080b858e5fdbe713cdc1c8db9fb17777d8a13e63df0" dependencies = [ "anstream", "anstyle", - "clap_lex 0.7.6", + "clap_lex 0.7.7", "strsim 0.11.1", ] [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.5.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1356,9 +1356,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" [[package]] name = "cobs" @@ -1366,7 +1366,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" dependencies = [ - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -1401,7 +1401,7 @@ dependencies = [ "serde", "serde_json", "sha2", - "thiserror 2.0.17", + "thiserror 2.0.18", "url", ] @@ -1599,7 +1599,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1633,7 +1633,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1647,7 +1647,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1658,7 +1658,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1669,7 +1669,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core 0.21.3", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1687,15 +1687,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" +checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" [[package]] name = "data-encoding-macro" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47ce6c96ea0102f01122a185683611bd5ac8d99e62bc59dd12e6bda344ee673d" +checksum = "8142a83c17aa9461d637e649271eae18bf2edd00e91f2e105df36c3c16355bdb" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -1703,12 +1703,12 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" +checksum = "7ab67060fc6b8ef687992d439ca0fa36e7ed17e9a0b16b25b601e8757df720de" dependencies = [ "data-encoding", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1761,7 +1761,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1771,7 +1771,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1784,29 +1784,29 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] name = "derive_more" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ "convert_case 0.10.0", "proc-macro2", "quote", "rustc_version", - "syn 2.0.111", + "syn 2.0.114", "unicode-xid", ] @@ -1851,7 +1851,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -1932,7 +1932,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -2012,7 +2012,7 @@ checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -2085,9 +2085,9 @@ checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "find-msvc-tools" -version = "0.1.5" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "fnv" @@ -2128,7 +2128,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -2218,7 +2218,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -2285,9 +2285,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "js-sys", @@ -2415,7 +2415,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.12.1", + "indexmap 2.13.0", "slab", "tokio", "tokio-util", @@ -2434,7 +2434,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.4.0", - "indexmap 2.12.1", + "indexmap 2.13.0", "slab", "tokio", "tokio-util", @@ -2561,9 +2561,9 @@ dependencies = [ [[package]] name = "hmac-sha512" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89e8d20b3799fa526152a5301a771eaaad80857f83e01b23216ceaafb2d9280" +checksum = "e9c4d256181c136fe596b5e8cf23adf99c58f71bb54e98058cfa976caf8cc5c2" [[package]] name = "http" @@ -2702,7 +2702,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.1", + "socket2 0.6.2", "system-configuration", "tokio", "tower-service", @@ -2712,9 +2712,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.64" +version = "0.1.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2871,7 +2871,7 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "clap 4.5.53", + "clap 4.5.56", "env_logger", "indexer_service_protocol", "indexer_service_rpc", @@ -2917,9 +2917,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -2969,10 +2969,12 @@ dependencies = [ "nssa_core", "sequencer_core", "sequencer_runner", + "serde_json", "tempfile", "tokio", "url", "wallet", + "wallet-ffi", ] [[package]] @@ -2983,9 +2985,9 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "iri-string" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" dependencies = [ "memchr", "serde", @@ -3037,9 +3039,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jf-crhf" @@ -3100,9 +3102,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" dependencies = [ "once_cell", "wasm-bindgen", @@ -3143,7 +3145,7 @@ dependencies = [ "rustls-pki-types", "rustls-platform-verifier", "soketto", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tokio-rustls", "tokio-util", @@ -3171,10 +3173,10 @@ dependencies = [ "rustc-hash", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tokio-stream", - "tower 0.5.2", + "tower 0.5.3", "tracing", "wasm-bindgen-futures", ] @@ -3196,9 +3198,9 @@ dependencies = [ "rustls-platform-verifier", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", - "tower 0.5.2", + "tower 0.5.3", "url", ] @@ -3212,7 +3214,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -3234,11 +3236,11 @@ dependencies = [ "serde", "serde_json", "soketto", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tokio-stream", "tokio-util", - "tower 0.5.2", + "tower 0.5.3", "tracing", ] @@ -3251,7 +3253,7 @@ dependencies = [ "http 1.4.0", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -3263,7 +3265,7 @@ dependencies = [ "jsonrpsee-client-transport", "jsonrpsee-core", "jsonrpsee-types", - "tower 0.5.2", + "tower 0.5.3", ] [[package]] @@ -3276,7 +3278,7 @@ dependencies = [ "jsonrpsee-client-transport", "jsonrpsee-core", "jsonrpsee-types", - "tower 0.5.2", + "tower 0.5.3", "url", ] @@ -3322,7 +3324,7 @@ dependencies = [ "rand 0.8.5", "serde", "sha2", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -3333,9 +3335,9 @@ checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" [[package]] name = "lazy-regex" -version = "3.4.2" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "191898e17ddee19e60bccb3945aa02339e81edd4a8c50e21fd4d48cdecda7b29" +checksum = "c5c13b6857ade4c8ee05c3c3dc97d2ab5415d691213825b90d3211c425c1f907" dependencies = [ "lazy-regex-proc_macros", "once_cell", @@ -3344,14 +3346,14 @@ dependencies = [ [[package]] name = "lazy-regex-proc_macros" -version = "3.4.2" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c35dc8b0da83d1a9507e12122c80dea71a9c7c613014347392483a83ea593e04" +checksum = "32a95c68db5d41694cea563c86a4ba4dc02141c16ef64814108cb23def4d5438" dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -3365,9 +3367,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.178" +version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" [[package]] name = "libloading" @@ -3381,9 +3383,9 @@ dependencies = [ [[package]] name = "libm" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libp2p-identity" @@ -3395,15 +3397,15 @@ dependencies = [ "hkdf", "multihash", "sha2", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", ] [[package]] name = "libredox" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ "bitflags 2.10.0", "libc", @@ -3492,7 +3494,7 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "logos-blockchain-blend-crypto" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "blake2", "logos-blockchain-groth16", @@ -3506,7 +3508,7 @@ dependencies = [ [[package]] name = "logos-blockchain-blend-message" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "blake2", "derivative", @@ -3528,7 +3530,7 @@ dependencies = [ [[package]] name = "logos-blockchain-blend-proofs" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "ed25519-dalek", "generic-array 1.3.5", @@ -3543,7 +3545,7 @@ dependencies = [ [[package]] name = "logos-blockchain-chain-broadcast-service" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "async-trait", "derivative", @@ -3559,7 +3561,7 @@ dependencies = [ [[package]] name = "logos-blockchain-chain-service" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "async-trait", "bytes", @@ -3589,7 +3591,7 @@ dependencies = [ [[package]] name = "logos-blockchain-circuits-prover" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "logos-blockchain-circuits-utils", "tempfile", @@ -3598,7 +3600,7 @@ dependencies = [ [[package]] name = "logos-blockchain-circuits-utils" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "dirs", ] @@ -3606,7 +3608,7 @@ dependencies = [ [[package]] name = "logos-blockchain-common-http-client" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "futures", "logos-blockchain-chain-broadcast-service", @@ -3623,7 +3625,7 @@ dependencies = [ [[package]] name = "logos-blockchain-core" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "ark-ff 0.4.2", "bincode", @@ -3631,15 +3633,16 @@ dependencies = [ "bytes", "const-hex", "futures", - "generic-array 1.3.5", "hex", "logos-blockchain-blend-proofs", "logos-blockchain-cryptarchia-engine", "logos-blockchain-groth16", "logos-blockchain-key-management-system-keys", + "logos-blockchain-poc", "logos-blockchain-pol", "logos-blockchain-poseidon2", "logos-blockchain-utils", + "logos-blockchain-utxotree", "multiaddr", "nom 8.0.0", "num-bigint", @@ -3652,7 +3655,7 @@ dependencies = [ [[package]] name = "logos-blockchain-cryptarchia-engine" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "cfg_eval", "logos-blockchain-utils", @@ -3667,7 +3670,7 @@ dependencies = [ [[package]] name = "logos-blockchain-cryptarchia-sync" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "bytes", "futures", @@ -3684,7 +3687,7 @@ dependencies = [ [[package]] name = "logos-blockchain-groth16" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "ark-bn254 0.4.0", "ark-ec 0.4.2", @@ -3696,13 +3699,13 @@ dependencies = [ "num-bigint", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] name = "logos-blockchain-http-api-common" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "axum", "governor", @@ -3717,7 +3720,7 @@ dependencies = [ [[package]] name = "logos-blockchain-key-management-system-keys" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "async-trait", "bytes", @@ -3733,7 +3736,7 @@ dependencies = [ "rand_core 0.6.4", "serde", "subtle", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", "x25519-dalek", @@ -3743,24 +3746,24 @@ dependencies = [ [[package]] name = "logos-blockchain-key-management-system-macros" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] name = "logos-blockchain-key-management-system-service" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "async-trait", "log", "logos-blockchain-key-management-system-keys", "overwatch", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", ] @@ -3768,7 +3771,7 @@ dependencies = [ [[package]] name = "logos-blockchain-ledger" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "derivative", "logos-blockchain-blend-crypto", @@ -3778,7 +3781,7 @@ dependencies = [ "logos-blockchain-cryptarchia-engine", "logos-blockchain-groth16", "logos-blockchain-key-management-system-keys", - "logos-blockchain-mmr", + "logos-blockchain-pol", "logos-blockchain-utils", "logos-blockchain-utxotree", "num-bigint", @@ -3789,22 +3792,10 @@ dependencies = [ "tracing", ] -[[package]] -name = "logos-blockchain-mmr" -version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" -dependencies = [ - "ark-ff 0.4.2", - "logos-blockchain-groth16", - "logos-blockchain-poseidon2", - "rpds", - "serde", -] - [[package]] name = "logos-blockchain-network-service" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "async-trait", "futures", @@ -3817,10 +3808,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "logos-blockchain-poc" +version = "0.1.0" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" +dependencies = [ + "logos-blockchain-circuits-prover", + "logos-blockchain-circuits-utils", + "logos-blockchain-groth16", + "logos-blockchain-witness-generator", + "num-bigint", + "serde", + "serde_json", + "thiserror 2.0.18", +] + [[package]] name = "logos-blockchain-pol" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "logos-blockchain-circuits-prover", "logos-blockchain-circuits-utils", @@ -3830,13 +3836,13 @@ dependencies = [ "num-traits", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] name = "logos-blockchain-poq" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "logos-blockchain-circuits-prover", "logos-blockchain-circuits-utils", @@ -3846,13 +3852,13 @@ dependencies = [ "num-bigint", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] name = "logos-blockchain-poseidon2" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "ark-bn254 0.4.0", "ark-ff 0.4.2", @@ -3863,7 +3869,7 @@ dependencies = [ [[package]] name = "logos-blockchain-services-utils" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "async-trait", "futures", @@ -3878,7 +3884,7 @@ dependencies = [ [[package]] name = "logos-blockchain-storage-service" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "async-trait", "bytes", @@ -3895,7 +3901,7 @@ dependencies = [ [[package]] name = "logos-blockchain-time-service" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "async-trait", "futures", @@ -3903,7 +3909,7 @@ dependencies = [ "logos-blockchain-cryptarchia-engine", "overwatch", "sntpc", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", "tokio", "tokio-stream", @@ -3913,7 +3919,7 @@ dependencies = [ [[package]] name = "logos-blockchain-utils" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "async-trait", "blake2", @@ -3930,10 +3936,9 @@ dependencies = [ [[package]] name = "logos-blockchain-utxotree" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "ark-ff 0.4.2", - "logos-blockchain-core", "logos-blockchain-groth16", "logos-blockchain-poseidon2", "num-bigint", @@ -3945,7 +3950,7 @@ dependencies = [ [[package]] name = "logos-blockchain-witness-generator" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "tempfile", ] @@ -3953,7 +3958,7 @@ dependencies = [ [[package]] name = "logos-blockchain-zksign" version = "0.1.0" -source = "git+https://github.com/logos-blockchain/logos-blockchain.git#451df112f8574aea2840d04fffb7e16e76d24f42" +source = "git+https://github.com/logos-blockchain/logos-blockchain.git#ea98ac1ad09ac29fe8350614a260c20d8de12bfe" dependencies = [ "logos-blockchain-circuits-prover", "logos-blockchain-circuits-utils", @@ -3963,7 +3968,7 @@ dependencies = [ "num-bigint", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -3983,13 +3988,13 @@ dependencies = [ [[package]] name = "match-lookup" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1265724d8cb29dbbc2b0f06fffb8bf1a8c0cf73a78eede9ba73a4a66c52a981e" +checksum = "757aee279b8bdbb9f9e676796fd459e4207a1f986e87886700abf589f5abf771" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.114", ] [[package]] @@ -4006,7 +4011,7 @@ checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -4211,7 +4216,7 @@ dependencies = [ "sha2", "test-case", "test_program_methods", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -4227,7 +4232,7 @@ dependencies = [ "risc0-zkvm", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -4258,9 +4263,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num-integer" @@ -4310,7 +4315,7 @@ checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -4363,7 +4368,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -4398,7 +4403,7 @@ checksum = "969ccca8ffc4fb105bd131a228107d5c9dd89d9d627edf3295cbe979156f9712" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -4421,7 +4426,7 @@ dependencies = [ "async-trait", "futures", "overwatch-derive", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tokio-stream", "tokio-util", @@ -4437,7 +4442,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -4501,7 +4506,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -4557,9 +4562,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "postcard" @@ -4625,14 +4630,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -4645,7 +4650,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", "version_check", ] @@ -4653,7 +4658,7 @@ dependencies = [ name = "program_deployment" version = "0.1.0" dependencies = [ - "clap 4.5.53", + "clap 4.5.56", "nssa", "nssa_core", "tokio", @@ -4710,7 +4715,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -4741,8 +4746,8 @@ dependencies = [ "quinn-udp", "rustc-hash", "rustls", - "socket2 0.6.1", - "thiserror 2.0.17", + "socket2 0.6.2", + "thiserror 2.0.18", "tokio", "tracing", "web-time", @@ -4763,7 +4768,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.17", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -4778,16 +4783,16 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.1", + "socket2 0.6.2", "tracing", "windows-sys 0.60.2", ] [[package]] name = "quote" -version = "1.0.42" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] @@ -4816,7 +4821,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -4836,7 +4841,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -4845,14 +4850,14 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] name = "rand_core" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ "getrandom 0.3.4", ] @@ -4863,7 +4868,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" dependencies = [ - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -4890,9 +4895,9 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "libredox", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -4912,7 +4917,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -4952,9 +4957,9 @@ checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "reqwest" -version = "0.12.26" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64", "bytes", @@ -4987,7 +4992,7 @@ dependencies = [ "tokio-native-tls", "tokio-rustls", "tokio-util", - "tower 0.5.2", + "tower 0.5.3", "tower-http", "tower-service", "url", @@ -5016,7 +5021,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.17", "libc", "untrusted", "windows-sys 0.52.0", @@ -5031,7 +5036,7 @@ dependencies = [ "anyhow", "borsh", "bytemuck", - "derive_more 2.1.0", + "derive_more 2.1.1", "elf", "lazy_static", "postcard", @@ -5108,7 +5113,7 @@ dependencies = [ "anyhow", "bit-vec", "bytemuck", - "derive_more 2.1.0", + "derive_more 2.1.1", "paste", "risc0-binfmt", "risc0-core", @@ -5124,7 +5129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80f2723fedace48c6c5a505bd8f97ac4e1712bc4cb769083e10536d862b66987" dependencies = [ "bytemuck", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -5175,7 +5180,7 @@ dependencies = [ "hex-literal 0.4.1", "metal", "paste", - "rand_core 0.9.3", + "rand_core 0.9.5", "risc0-core", "risc0-zkvm-platform", "serde", @@ -5196,7 +5201,7 @@ dependencies = [ "borsh", "bytemuck", "bytes", - "derive_more 2.1.0", + "derive_more 2.1.1", "hex", "lazy-regex", "prost", @@ -5228,7 +5233,7 @@ checksum = "cfaa10feba15828c788837ddde84b994393936d8f5715228627cfe8625122a40" dependencies = [ "bytemuck", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.17", "getrandom 0.3.4", "libm", "num_enum", @@ -5286,16 +5291,16 @@ dependencies = [ "quote", "rand 0.9.2", "syn 1.0.109", - "thiserror 2.0.17", + "thiserror 2.0.18", "tiny-keccak", "tokio", ] [[package]] name = "rsa" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a0376c50d0358279d9d643e4bf7b7be212f1f4ff1da9070a7b54d22ef75c88" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" dependencies = [ "const-oid", "digest", @@ -5313,9 +5318,9 @@ dependencies = [ [[package]] name = "ruint" -version = "1.17.0" +version = "1.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a68df0380e5c9d20ce49534f292a36a7514ae21350726efe1865bdb1fa91d278" +checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" dependencies = [ "borsh", "proptest", @@ -5350,9 +5355,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ "bitflags 2.10.0", "errno", @@ -5363,9 +5368,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.35" +version = "0.23.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" dependencies = [ "log", "once_cell", @@ -5390,9 +5395,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ "web-time", "zeroize", @@ -5416,7 +5421,7 @@ dependencies = [ "security-framework 3.5.1", "security-framework-sys", "webpki-root-certs 0.26.11", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5427,9 +5432,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.8" +version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ "ring", "rustls-pki-types", @@ -5444,9 +5449,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" [[package]] name = "rzup" @@ -5462,7 +5467,7 @@ dependencies = [ "sha2", "strum", "tempfile", - "thiserror 2.0.17", + "thiserror 2.0.18", "toml 0.8.23", "yaml-rust2", ] @@ -5519,7 +5524,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -5672,7 +5677,7 @@ dependencies = [ "actix", "actix-web", "anyhow", - "clap 4.5.53", + "clap 4.5.56", "common", "env_logger", "log", @@ -5717,7 +5722,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -5728,20 +5733,20 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] @@ -5786,7 +5791,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.12.1", + "indexmap 2.13.0", "schemars 0.9.0", "schemars 1.2.0", "serde_core", @@ -5804,7 +5809,7 @@ dependencies = [ "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -5847,10 +5852,11 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.7" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] @@ -5866,9 +5872,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" @@ -5908,9 +5914,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" dependencies = [ "libc", "windows-sys 0.60.2", @@ -5964,7 +5970,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d904e7009df136af5297832a3ace3370cd14ff1546a232f4f185036c2736fcac" dependencies = [ "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -5987,7 +5993,7 @@ dependencies = [ "common", "nssa", "rocksdb", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -6020,7 +6026,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -6042,9 +6048,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.111" +version = "2.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" dependencies = [ "proc-macro2", "quote", @@ -6068,25 +6074,25 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] name = "system-configuration" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", "core-foundation 0.9.4", "system-configuration-sys", ] [[package]] name = "system-configuration-sys" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" dependencies = [ "core-foundation-sys", "libc", @@ -6094,9 +6100,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.23.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", "getrandom 0.3.4", @@ -6132,7 +6138,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -6143,7 +6149,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", "test-case-core", ] @@ -6179,11 +6185,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.18", ] [[package]] @@ -6194,46 +6200,46 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] name = "time" -version = "0.3.44" +version = "0.3.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +checksum = "9da98b7d9b7dad93488a84b8248efc35352b0b2657397d4167e7ad67e5d535e5" dependencies = [ "deranged", "itoa", "num-conv", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.24" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +checksum = "78cc610bac2dcee56805c99642447d4c5dbde4d01f752ffea0199aee1f601dc4" dependencies = [ "num-conv", "time-core", @@ -6275,9 +6281,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.48.0" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ "bytes", "libc", @@ -6285,7 +6291,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.1", + "socket2 0.6.2", "tokio-macros", "windows-sys 0.61.2", ] @@ -6298,7 +6304,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -6390,9 +6396,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.4+spec-1.0.0" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3cea6b2aa3b910092f6abd4053ea464fab5f9c170ba5e9a6aead16ec4af2b6" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] @@ -6403,7 +6409,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.12.1", + "indexmap 2.13.0", "serde", "serde_spanned", "toml_datetime 0.6.11", @@ -6417,17 +6423,17 @@ version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ - "indexmap 2.12.1", - "toml_datetime 0.7.4+spec-1.0.0", + "indexmap 2.13.0", + "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "winnow", ] [[package]] name = "toml_parser" -version = "1.0.5+spec-1.0.0" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c03bee5ce3696f31250db0bbaff18bc43301ce0e8db2ed1f07cbb2acf89984c" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ "winnow", ] @@ -6451,9 +6457,9 @@ dependencies = [ [[package]] name = "tower" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", @@ -6478,7 +6484,7 @@ dependencies = [ "http-body", "iri-string", "pin-project-lite", - "tower 0.5.2", + "tower 0.5.3", "tower-layer", "tower-service", ] @@ -6513,9 +6519,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -6531,14 +6537,14 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -6650,14 +6656,15 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.7" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", "serde", + "serde_derive", ] [[package]] @@ -6710,7 +6717,7 @@ dependencies = [ "base64", "borsh", "bytemuck", - "clap 4.5.53", + "clap 4.5.56", "common", "env_logger", "futures", @@ -6760,18 +6767,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.1+wasi-0.2.4" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" dependencies = [ "cfg-if", "once_cell", @@ -6782,11 +6789,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.56" +version = "0.4.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" dependencies = [ "cfg-if", + "futures-util", "js-sys", "once_cell", "wasm-bindgen", @@ -6795,9 +6803,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6805,22 +6813,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" dependencies = [ "unicode-ident", ] @@ -6840,9 +6848,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.83" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" dependencies = [ "js-sys", "wasm-bindgen", @@ -6878,9 +6886,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" +checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" dependencies = [ "rustls-pki-types", ] @@ -6937,7 +6945,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -6948,7 +6956,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -7004,6 +7012,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.60.2" @@ -7219,9 +7236,9 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" [[package]] name = "writeable" @@ -7271,28 +7288,28 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.31" +version = "0.8.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" +checksum = "7456cf00f0685ad319c5b1693f291a650eaf345e941d082fc4e03df8a03996ac" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.31" +version = "0.8.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" +checksum = "1328722bbf2115db7e19d69ebcc15e795719e2d66b60827c6a69a117365e37a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -7312,7 +7329,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", "synstructure", ] @@ -7327,13 +7344,13 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] [[package]] @@ -7366,5 +7383,11 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.111", + "syn 2.0.114", ] + +[[package]] +name = "zmij" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1966f8ac2c1f76987d69a74d0e0f929241c10e78136434e3be70ff7f58f64214" diff --git a/integration_tests/Cargo.toml b/integration_tests/Cargo.toml index b7ca13dd..b96f983b 100644 --- a/integration_tests/Cargo.toml +++ b/integration_tests/Cargo.toml @@ -13,6 +13,8 @@ common.workspace = true key_protocol.workspace = true indexer_core.workspace = true url.workspace = true +wallet-ffi.workspace = true +serde_json.workspace = true anyhow.workspace = true env_logger.workspace = true diff --git a/integration_tests/src/lib.rs b/integration_tests/src/lib.rs index 21e1ca81..334912e5 100644 --- a/integration_tests/src/lib.rs +++ b/integration_tests/src/lib.rs @@ -44,6 +44,7 @@ pub struct TestContext { indexer_loop_handle: Option>>, sequencer_client: SequencerClient, wallet: WalletCore, + wallet_password: String, _temp_sequencer_dir: TempDir, _temp_wallet_dir: TempDir, } @@ -62,6 +63,12 @@ impl TestContext { Self::new_with_sequencer_and_maybe_indexer_configs(sequencer_config, None).await } + pub fn new_blocking() -> Result { + tokio::runtime::Runtime::new() + .unwrap() + .block_on(Self::new()) + } + /// Create new test context in local bedrock node attached mode. pub async fn new_bedrock_local_attached() -> Result { let manifest_dir = env!("CARGO_MANIFEST_DIR"); @@ -114,7 +121,7 @@ impl TestContext { format!("http://{sequencer_addr}") }; - let (wallet, temp_wallet_dir) = Self::setup_wallet(sequencer_addr.clone()) + let (wallet, temp_wallet_dir, wallet_password) = Self::setup_wallet(sequencer_addr.clone()) .await .context("Failed to setup wallet")?; @@ -142,6 +149,7 @@ impl TestContext { wallet, _temp_sequencer_dir: temp_sequencer_dir, _temp_wallet_dir: temp_wallet_dir, + wallet_password, }) } else { Ok(Self { @@ -153,6 +161,7 @@ impl TestContext { wallet, _temp_sequencer_dir: temp_sequencer_dir, _temp_wallet_dir: temp_wallet_dir, + wallet_password, }) } } @@ -193,7 +202,7 @@ impl TestContext { )) } - async fn setup_wallet(sequencer_addr: String) -> Result<(WalletCore, TempDir)> { + async fn setup_wallet(sequencer_addr: String) -> Result<(WalletCore, TempDir, String)> { let manifest_dir = env!("CARGO_MANIFEST_DIR"); let wallet_config_source_path = PathBuf::from(manifest_dir).join("configs/wallet/wallet_config.json"); @@ -211,11 +220,12 @@ impl TestContext { ..Default::default() }; + let wallet_password = "test_pass".to_owned(); let wallet = WalletCore::new_init_storage( config_path, storage_path, Some(config_overrides), - "test_pass".to_owned(), + wallet_password.clone(), ) .context("Failed to init wallet")?; wallet @@ -223,7 +233,7 @@ impl TestContext { .await .context("Failed to store wallet persistent data")?; - Ok((wallet, temp_wallet_dir)) + Ok((wallet, temp_wallet_dir, wallet_password)) } /// Get reference to the wallet. @@ -231,6 +241,10 @@ impl TestContext { &self.wallet } + pub fn wallet_password(&self) -> &str { + &self.wallet_password + } + /// Get mutable reference to the wallet. pub fn wallet_mut(&mut self) -> &mut WalletCore { &mut self.wallet @@ -255,6 +269,7 @@ impl Drop for TestContext { wallet: _, _temp_sequencer_dir, _temp_wallet_dir, + wallet_password: _, } = self; sequencer_loop_handle.abort(); diff --git a/integration_tests/tests/wallet_ffi.rs b/integration_tests/tests/wallet_ffi.rs new file mode 100644 index 00000000..90a3feaa --- /dev/null +++ b/integration_tests/tests/wallet_ffi.rs @@ -0,0 +1,285 @@ +use std::{ + collections::HashSet, + ffi::{CString, c_char}, + io::Write, +}; + +use anyhow::Result; +use integration_tests::{ACC_SENDER, TestContext}; +use nssa::AccountId; +use tempfile::tempdir; +use wallet::WalletCore; +use wallet_ffi::{FfiAccountList, FfiBytes32, WalletHandle, error}; + +unsafe extern "C" { + fn wallet_ffi_create_new( + config_path: *const c_char, + storage_path: *const c_char, + password: *const c_char, + ) -> *mut WalletHandle; + + fn wallet_ffi_create_account_public( + handle: *mut WalletHandle, + out_account_id: *mut FfiBytes32, + ) -> error::WalletFfiError; + + fn wallet_ffi_create_account_private( + handle: *mut WalletHandle, + out_account_id: *mut FfiBytes32, + ) -> error::WalletFfiError; + + fn wallet_ffi_list_accounts( + handle: *mut WalletHandle, + out_list: *mut FfiAccountList, + ) -> error::WalletFfiError; + + fn wallet_ffi_free_account_list(list: *mut FfiAccountList); + + fn wallet_ffi_get_balance( + handle: *mut WalletHandle, + account_id: *const FfiBytes32, + is_public: bool, + out_balance: *mut [u8; 16], + ) -> error::WalletFfiError; +} + +fn new_wallet_from_test_context(ctx: &TestContext) -> *mut WalletHandle { + let tempdir = tempfile::tempdir().unwrap(); + let temp_config_path = tempdir.path().join("wallet_config.json"); + let mut config = ctx.wallet().config().to_owned(); + if let Some(config_overrides) = ctx.wallet().config_overrides().clone() { + config.apply_overrides(config_overrides); + } + let mut file = std::fs::OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(&temp_config_path) + .unwrap(); + + let config_with_overrides_serialized = serde_json::to_vec_pretty(&config).unwrap(); + + file.write_all(&config_with_overrides_serialized).unwrap(); + + let config_path = CString::new(temp_config_path.to_str().unwrap()).unwrap(); + let storage_path = CString::new(ctx.wallet().storage_path().to_str().unwrap()).unwrap(); + let password = CString::new(ctx.wallet_password()).unwrap(); + + unsafe { + wallet_ffi_create_new( + config_path.as_ptr(), + storage_path.as_ptr(), + password.as_ptr(), + ) + } +} + +fn new_wallet_ffi_on_tempdir_for_tests(password: &str) -> *mut WalletHandle { + let tempdir = tempdir().unwrap(); + let config_path = tempdir.path().join("wallet_config.json"); + let storage_path = tempdir.path().join("storage.json"); + let config_path_c = CString::new(config_path.to_str().unwrap()).unwrap(); + let storage_path_c = CString::new(storage_path.to_str().unwrap()).unwrap(); + let password = CString::new(password).unwrap(); + + unsafe { + wallet_ffi_create_new( + config_path_c.as_ptr(), + storage_path_c.as_ptr(), + password.as_ptr(), + ) + } +} + +fn new_wallet_rust_for_tests(password: &str) -> WalletCore { + let tempdir = tempdir().unwrap(); + let config_path = tempdir.path().join("wallet_config.json"); + let storage_path = tempdir.path().join("storage.json"); + + WalletCore::new_init_storage( + config_path.to_path_buf(), + storage_path.to_path_buf(), + None, + password.to_string(), + ) + .unwrap() +} + +#[test] +fn test_create_public_accounts() { + let password = "password_for_tests"; + let n_accounts = 10; + // First `n_accounts` public accounts created with Rust wallet + let new_public_account_ids_rust = { + let mut account_ids = Vec::new(); + + let mut wallet_rust = new_wallet_rust_for_tests(password); + for _ in 0..n_accounts { + let account_id = wallet_rust.create_new_account_public(None).0; + account_ids.push(*account_id.value()); + } + account_ids + }; + + // First `n_accounts` public accounts created with wallet FFI + let new_public_account_ids_ffi = unsafe { + let mut account_ids = Vec::new(); + + let wallet_ffi_handle = new_wallet_ffi_on_tempdir_for_tests(password); + for _ in 0..n_accounts { + let mut out_account_id = FfiBytes32::from_bytes([0; 32]); + wallet_ffi_create_account_public( + wallet_ffi_handle, + (&mut out_account_id) as *mut FfiBytes32, + ); + account_ids.push(out_account_id.data); + } + account_ids + }; + + assert_eq!(new_public_account_ids_ffi, new_public_account_ids_rust) +} + +#[test] +fn test_create_private_accounts() { + let password = "password_for_tests"; + let n_accounts = 10; + // First `n_accounts` private accounts created with Rust wallet + let new_private_account_ids_rust = { + let mut account_ids = Vec::new(); + + let mut wallet_rust = new_wallet_rust_for_tests(password); + for _ in 0..n_accounts { + let account_id = wallet_rust.create_new_account_private(None).0; + account_ids.push(*account_id.value()); + } + account_ids + }; + + // First `n_accounts` private accounts created with wallet FFI + let new_private_account_ids_ffi = unsafe { + let mut account_ids = Vec::new(); + + let wallet_ffi_handle = new_wallet_ffi_on_tempdir_for_tests(password); + for _ in 0..n_accounts { + let mut out_account_id = FfiBytes32::from_bytes([0; 32]); + wallet_ffi_create_account_private( + wallet_ffi_handle, + (&mut out_account_id) as *mut FfiBytes32, + ); + account_ids.push(out_account_id.data); + } + account_ids + }; + + assert_eq!(new_private_account_ids_ffi, new_private_account_ids_rust) +} + +#[test] +fn test_list_accounts() { + let password = "password_for_tests"; + + // Create the wallet FFI + let wallet_ffi_handle = unsafe { + let handle = new_wallet_ffi_on_tempdir_for_tests(password); + // Create 5 public accounts and 5 private accounts + for _ in 0..5 { + let mut out_account_id = FfiBytes32::from_bytes([0; 32]); + wallet_ffi_create_account_public(handle, (&mut out_account_id) as *mut FfiBytes32); + wallet_ffi_create_account_private(handle, (&mut out_account_id) as *mut FfiBytes32); + } + + handle + }; + + // Create the wallet Rust + let wallet_rust = { + let mut wallet = new_wallet_rust_for_tests(password); + // Create 5 public accounts and 5 private accounts + for _ in 0..5 { + wallet.create_new_account_public(None); + wallet.create_new_account_private(None); + } + wallet + }; + + // Get the account list with FFI method + let mut wallet_ffi_account_list = unsafe { + let mut out_list = FfiAccountList::default(); + wallet_ffi_list_accounts(wallet_ffi_handle, (&mut out_list) as *mut FfiAccountList); + out_list + }; + + let wallet_rust_account_ids = wallet_rust + .storage() + .user_data + .account_ids() + .collect::>(); + + // Assert same number of elements between Rust and FFI result + assert_eq!(wallet_rust_account_ids.len(), wallet_ffi_account_list.count); + + let wallet_ffi_account_list_slice = unsafe { + core::slice::from_raw_parts( + wallet_ffi_account_list.entries, + wallet_ffi_account_list.count, + ) + }; + + // Assert same account ids between Rust and FFI result + assert_eq!( + wallet_rust_account_ids + .iter() + .map(|id| id.value()) + .collect::>(), + wallet_ffi_account_list_slice + .iter() + .map(|entry| &entry.account_id.data) + .collect::>() + ); + + // Assert `is_pub` flag is correct in the FFI result + for entry in wallet_ffi_account_list_slice.iter() { + let account_id = AccountId::new(entry.account_id.data); + let is_pub_default_in_rust_wallet = wallet_rust + .storage() + .user_data + .default_pub_account_signing_keys + .contains_key(&account_id); + let is_pub_key_tree_wallet_rust = wallet_rust + .storage() + .user_data + .public_key_tree + .account_id_map + .contains_key(&account_id); + + let is_public_in_rust_wallet = is_pub_default_in_rust_wallet || is_pub_key_tree_wallet_rust; + + assert_eq!(entry.is_public, is_public_in_rust_wallet); + } + + unsafe { wallet_ffi_free_account_list((&mut wallet_ffi_account_list) as *mut FfiAccountList) }; +} + +#[test] +fn test_wallet_ffi_get_balance_public() -> Result<()> { + let ctx = TestContext::new_blocking()?; + let account_id: AccountId = ACC_SENDER.parse().unwrap(); + let wallet_ffi_handle = new_wallet_from_test_context(&ctx); + + let balance = unsafe { + let mut out_balance: [u8; 16] = [0; 16]; + let ffi_account_id = FfiBytes32::from_bytes(*account_id.value()); + let result = wallet_ffi_get_balance( + wallet_ffi_handle, + (&ffi_account_id) as *const FfiBytes32, + true, + (&mut out_balance) as *mut [u8; 16], + ); + println!("result: {:?}", result); + out_balance + }; + println!("balance: {balance:?}"); + + Ok(()) +} diff --git a/wallet-ffi/tests/ffi.rs b/wallet-ffi/tests/ffi.rs deleted file mode 100644 index 70a82874..00000000 --- a/wallet-ffi/tests/ffi.rs +++ /dev/null @@ -1,129 +0,0 @@ -use std::{ - ffi::{c_char, CString}, - path::Path, -}; - -use tokio::runtime::Handle; -use wallet::WalletCore; -use wallet_ffi::{error, FfiBytes32, FfiError, WalletHandle}; - -extern "C" { - fn wallet_ffi_create_account_public( - handle: *mut WalletHandle, - out_account_id: *mut FfiBytes32, - ) -> error::WalletFfiError; - - fn wallet_ffi_create_account_private( - handle: *mut WalletHandle, - out_account_id: *mut FfiBytes32, - ) -> error::WalletFfiError; - - fn wallet_ffi_create_new( - config_path: *const c_char, - storage_path: *const c_char, - password: *const c_char, - ) -> *mut WalletHandle; - - fn wallet_ffi_save(handle: *mut WalletHandle) -> error::WalletFfiError; -} - -use tempfile::tempdir; - -unsafe fn new_wallet_ffi_for_tests(password: &str) -> *mut WalletHandle { - let tempdir = tempdir().unwrap(); - let config_path = tempdir.path().join("wallet_config.json"); - let storage_path = tempdir.path().join("storage.json"); - let config_path_c = CString::new(config_path.to_str().unwrap()).unwrap(); - let storage_path_c = CString::new(storage_path.to_str().unwrap()).unwrap(); - let password = CString::new(password).unwrap(); - - wallet_ffi_create_new( - config_path_c.as_ptr(), - storage_path_c.as_ptr(), - password.as_ptr(), - ) -} - -fn new_wallet_rust_for_tests(password: &str) -> WalletCore { - let tempdir = tempdir().unwrap(); - let config_path = tempdir.path().join("wallet_config.json"); - let storage_path = tempdir.path().join("storage.json"); - - WalletCore::new_init_storage( - config_path.to_path_buf(), - storage_path.to_path_buf(), - None, - password.to_string(), - ) - .unwrap() -} - -#[test] -fn test_create_public_accounts() { - let password = "password_for_tests"; - let n_accounts = 10; - // First `n_accounts` public accounts created with Rust wallet - let new_public_account_ids_rust = { - let mut account_ids = Vec::new(); - - let mut wallet_rust = new_wallet_rust_for_tests(password); - for _ in 0..n_accounts { - let account_id = wallet_rust.create_new_account_public(None).0; - account_ids.push(*account_id.value()); - } - account_ids - }; - - // First `n_accounts` public accounts created with wallet FFI - let new_public_account_ids_ffi = unsafe { - let mut account_ids = Vec::new(); - - let wallet_ffi_handle = new_wallet_ffi_for_tests(password); - for _ in 0..n_accounts { - let mut out_account_id = FfiBytes32::from_bytes([0; 32]); - wallet_ffi_create_account_public( - wallet_ffi_handle, - (&mut out_account_id) as *mut FfiBytes32, - ); - account_ids.push(out_account_id.data); - } - account_ids - }; - - assert_eq!(new_public_account_ids_ffi, new_public_account_ids_rust) -} - -#[test] -fn test_create_private_accounts() { - let password = "password_for_tests"; - let n_accounts = 10; - // First `n_accounts` private accounts created with Rust wallet - let new_private_account_ids_rust = { - let mut account_ids = Vec::new(); - - let mut wallet_rust = new_wallet_rust_for_tests(password); - for _ in 0..n_accounts { - let account_id = wallet_rust.create_new_account_private(None).0; - account_ids.push(*account_id.value()); - } - account_ids - }; - - // First `n_accounts` private accounts created with wallet FFI - let new_private_account_ids_ffi = unsafe { - let mut account_ids = Vec::new(); - - let wallet_ffi_handle = new_wallet_ffi_for_tests(password); - for _ in 0..n_accounts { - let mut out_account_id = FfiBytes32::from_bytes([0; 32]); - wallet_ffi_create_account_private( - wallet_ffi_handle, - (&mut out_account_id) as *mut FfiBytes32, - ); - account_ids.push(out_account_id.data); - } - account_ids - }; - - assert_eq!(new_private_account_ids_ffi, new_private_account_ids_rust) -} diff --git a/wallet/src/config.rs b/wallet/src/config.rs index 0f39c581..9f07cb34 100644 --- a/wallet/src/config.rs +++ b/wallet/src/config.rs @@ -175,7 +175,7 @@ pub struct GasConfig { pub gas_limit_runtime: u64, } -#[optfield::optfield(pub WalletConfigOverrides, rewrap, attrs = (derive(Debug, Default)))] +#[optfield::optfield(pub WalletConfigOverrides, rewrap, attrs = (derive(Debug, Default, Clone)))] #[derive(Debug, Clone, Serialize, Deserialize)] pub struct WalletConfig { /// Override rust log (env var logging level) diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index 58ef47ba..cdefd380 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -124,6 +124,7 @@ impl TokenHolding { pub struct WalletCore { config_path: PathBuf, + config_overrides: Option, storage: WalletChainStore, storage_path: PathBuf, poller: TxPoller, @@ -186,10 +187,11 @@ impl WalletCore { ) -> Result { let mut config = WalletConfig::from_path_or_initialize_default(&config_path) .with_context(|| format!("Failed to deserialize wallet config at {config_path:#?}"))?; - if let Some(config_overrides) = config_overrides { + if let Some(config_overrides) = config_overrides.clone() { config.apply_overrides(config_overrides); } + println!("sequencer url: {}", config.sequencer_addr); let sequencer_client = Arc::new(SequencerClient::new_with_auth( Url::parse(&config.sequencer_addr)?, config.basic_auth.clone(), @@ -205,6 +207,7 @@ impl WalletCore { poller: tx_poller, sequencer_client, last_synced_block, + config_overrides, }) } @@ -543,4 +546,16 @@ impl WalletCore { .insert_private_account_data(affected_account_id, new_acc); } } + pub fn config_path(&self) -> &PathBuf { + &self.config_path + } + + pub fn storage_path(&self) -> &PathBuf { + &self.storage_path + } + + pub fn config_overrides(&self) -> &Option { + &self.config_overrides + } + } From 5ac9953488b4878f70b8c21b774a61a4e13775db Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Wed, 4 Feb 2026 11:20:01 -0300 Subject: [PATCH 04/11] add ffi get account test --- integration_tests/tests/wallet_ffi.rs | 92 ++++++++++++++++++++------- nssa/src/lib.rs | 2 +- wallet-ffi/src/account.rs | 24 +------ wallet-ffi/src/error.rs | 2 + wallet-ffi/src/types.rs | 55 +++++++++++++++- wallet-ffi/wallet_ffi.h | 4 ++ wallet/src/lib.rs | 1 - 7 files changed, 132 insertions(+), 48 deletions(-) diff --git a/integration_tests/tests/wallet_ffi.rs b/integration_tests/tests/wallet_ffi.rs index 90a3feaa..a95ab319 100644 --- a/integration_tests/tests/wallet_ffi.rs +++ b/integration_tests/tests/wallet_ffi.rs @@ -6,10 +6,11 @@ use std::{ use anyhow::Result; use integration_tests::{ACC_SENDER, TestContext}; -use nssa::AccountId; +use log::info; +use nssa::{Account, AccountId, program::Program}; use tempfile::tempdir; use wallet::WalletCore; -use wallet_ffi::{FfiAccountList, FfiBytes32, WalletHandle, error}; +use wallet_ffi::{FfiAccount, FfiAccountList, FfiBytes32, WalletHandle, error}; unsafe extern "C" { fn wallet_ffi_create_new( @@ -41,11 +42,20 @@ unsafe extern "C" { is_public: bool, out_balance: *mut [u8; 16], ) -> error::WalletFfiError; + + fn wallet_ffi_get_account_public( + handle: *mut WalletHandle, + account_id: *const FfiBytes32, + out_account: *mut FfiAccount, + ) -> error::WalletFfiError; + + fn wallet_ffi_free_account_data(account: *mut FfiAccount); } -fn new_wallet_from_test_context(ctx: &TestContext) -> *mut WalletHandle { +fn new_wallet_ffi_with_test_context_config(ctx: &TestContext) -> *mut WalletHandle { let tempdir = tempfile::tempdir().unwrap(); - let temp_config_path = tempdir.path().join("wallet_config.json"); + let config_path = tempdir.path().join("wallet_config.json"); + let storage_path = tempdir.path().join("storage.json"); let mut config = ctx.wallet().config().to_owned(); if let Some(config_overrides) = ctx.wallet().config_overrides().clone() { config.apply_overrides(config_overrides); @@ -54,15 +64,15 @@ fn new_wallet_from_test_context(ctx: &TestContext) -> *mut WalletHandle { .write(true) .create(true) .truncate(true) - .open(&temp_config_path) + .open(&config_path) .unwrap(); let config_with_overrides_serialized = serde_json::to_vec_pretty(&config).unwrap(); file.write_all(&config_with_overrides_serialized).unwrap(); - let config_path = CString::new(temp_config_path.to_str().unwrap()).unwrap(); - let storage_path = CString::new(ctx.wallet().storage_path().to_str().unwrap()).unwrap(); + let config_path = CString::new(config_path.to_str().unwrap()).unwrap(); + let storage_path = CString::new(storage_path.to_str().unwrap()).unwrap(); let password = CString::new(ctx.wallet_password()).unwrap(); unsafe { @@ -74,7 +84,7 @@ fn new_wallet_from_test_context(ctx: &TestContext) -> *mut WalletHandle { } } -fn new_wallet_ffi_on_tempdir_for_tests(password: &str) -> *mut WalletHandle { +fn new_wallet_ffi_with_default_config(password: &str) -> *mut WalletHandle { let tempdir = tempdir().unwrap(); let config_path = tempdir.path().join("wallet_config.json"); let storage_path = tempdir.path().join("storage.json"); @@ -91,7 +101,7 @@ fn new_wallet_ffi_on_tempdir_for_tests(password: &str) -> *mut WalletHandle { } } -fn new_wallet_rust_for_tests(password: &str) -> WalletCore { +fn new_wallet_rust_with_default_config(password: &str) -> WalletCore { let tempdir = tempdir().unwrap(); let config_path = tempdir.path().join("wallet_config.json"); let storage_path = tempdir.path().join("storage.json"); @@ -106,14 +116,14 @@ fn new_wallet_rust_for_tests(password: &str) -> WalletCore { } #[test] -fn test_create_public_accounts() { +fn test_wallet_ffi_create_public_accounts() { let password = "password_for_tests"; let n_accounts = 10; // First `n_accounts` public accounts created with Rust wallet let new_public_account_ids_rust = { let mut account_ids = Vec::new(); - let mut wallet_rust = new_wallet_rust_for_tests(password); + let mut wallet_rust = new_wallet_rust_with_default_config(password); for _ in 0..n_accounts { let account_id = wallet_rust.create_new_account_public(None).0; account_ids.push(*account_id.value()); @@ -125,7 +135,7 @@ fn test_create_public_accounts() { let new_public_account_ids_ffi = unsafe { let mut account_ids = Vec::new(); - let wallet_ffi_handle = new_wallet_ffi_on_tempdir_for_tests(password); + let wallet_ffi_handle = new_wallet_ffi_with_default_config(password); for _ in 0..n_accounts { let mut out_account_id = FfiBytes32::from_bytes([0; 32]); wallet_ffi_create_account_public( @@ -141,14 +151,14 @@ fn test_create_public_accounts() { } #[test] -fn test_create_private_accounts() { +fn test_wallet_ffi_create_private_accounts() { let password = "password_for_tests"; let n_accounts = 10; // First `n_accounts` private accounts created with Rust wallet let new_private_account_ids_rust = { let mut account_ids = Vec::new(); - let mut wallet_rust = new_wallet_rust_for_tests(password); + let mut wallet_rust = new_wallet_rust_with_default_config(password); for _ in 0..n_accounts { let account_id = wallet_rust.create_new_account_private(None).0; account_ids.push(*account_id.value()); @@ -160,7 +170,7 @@ fn test_create_private_accounts() { let new_private_account_ids_ffi = unsafe { let mut account_ids = Vec::new(); - let wallet_ffi_handle = new_wallet_ffi_on_tempdir_for_tests(password); + let wallet_ffi_handle = new_wallet_ffi_with_default_config(password); for _ in 0..n_accounts { let mut out_account_id = FfiBytes32::from_bytes([0; 32]); wallet_ffi_create_account_private( @@ -176,12 +186,12 @@ fn test_create_private_accounts() { } #[test] -fn test_list_accounts() { +fn test_wallet_ffi_list_accounts() { let password = "password_for_tests"; // Create the wallet FFI let wallet_ffi_handle = unsafe { - let handle = new_wallet_ffi_on_tempdir_for_tests(password); + let handle = new_wallet_ffi_with_default_config(password); // Create 5 public accounts and 5 private accounts for _ in 0..5 { let mut out_account_id = FfiBytes32::from_bytes([0; 32]); @@ -194,7 +204,7 @@ fn test_list_accounts() { // Create the wallet Rust let wallet_rust = { - let mut wallet = new_wallet_rust_for_tests(password); + let mut wallet = new_wallet_rust_with_default_config(password); // Create 5 public accounts and 5 private accounts for _ in 0..5 { wallet.create_new_account_public(None); @@ -265,21 +275,57 @@ fn test_list_accounts() { fn test_wallet_ffi_get_balance_public() -> Result<()> { let ctx = TestContext::new_blocking()?; let account_id: AccountId = ACC_SENDER.parse().unwrap(); - let wallet_ffi_handle = new_wallet_from_test_context(&ctx); + let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx); let balance = unsafe { let mut out_balance: [u8; 16] = [0; 16]; - let ffi_account_id = FfiBytes32::from_bytes(*account_id.value()); - let result = wallet_ffi_get_balance( + let ffi_account_id = FfiBytes32::from(&account_id); + let _result = wallet_ffi_get_balance( wallet_ffi_handle, (&ffi_account_id) as *const FfiBytes32, true, (&mut out_balance) as *mut [u8; 16], ); - println!("result: {:?}", result); out_balance }; - println!("balance: {balance:?}"); + let balance = u128::from_le_bytes(balance); + assert_eq!(balance, 10000); + + info!("Successfully retrieved account balance"); + + Ok(()) +} + +#[test] +fn test_wallet_ffi_get_account_public() -> Result<()> { + let ctx = TestContext::new_blocking()?; + let account_id: AccountId = ACC_SENDER.parse().unwrap(); + let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx); + let mut out_account = FfiAccount::default(); + + let account: Account = unsafe { + let ffi_account_id = FfiBytes32::from(&account_id); + let _result = wallet_ffi_get_account_public( + wallet_ffi_handle, + (&ffi_account_id) as *const FfiBytes32, + (&mut out_account) as *mut FfiAccount, + ); + (&out_account).try_into().unwrap() + }; + + assert_eq!( + account.program_owner, + Program::authenticated_transfer_program().id() + ); + assert_eq!(account.balance, 10000); + assert!(account.data.is_empty()); + assert_eq!(account.nonce, 0); + + unsafe { + wallet_ffi_free_account_data((&mut out_account) as *mut FfiAccount); + } + + info!("Successfully retrieved account with correct details"); Ok(()) } diff --git a/nssa/src/lib.rs b/nssa/src/lib.rs index de4b65b2..47a0eadb 100644 --- a/nssa/src/lib.rs +++ b/nssa/src/lib.rs @@ -14,7 +14,7 @@ mod state; pub use nssa_core::{ SharedSecretKey, - account::{Account, AccountId}, + account::{Account, AccountId, Data}, encryption::EphemeralPublicKey, program::ProgramId, }; diff --git a/wallet-ffi/src/account.rs b/wallet-ffi/src/account.rs index e5fa84b0..d96369d0 100644 --- a/wallet-ffi/src/account.rs +++ b/wallet-ffi/src/account.rs @@ -7,9 +7,7 @@ use nssa::AccountId; use crate::{ block_on, error::{print_error, WalletFfiError}, - types::{ - FfiAccount, FfiAccountList, FfiAccountListEntry, FfiBytes32, FfiProgramId, WalletHandle, - }, + types::{FfiAccount, FfiAccountList, FfiAccountListEntry, FfiBytes32, WalletHandle}, wallet::get_wallet, }; @@ -350,26 +348,8 @@ pub unsafe extern "C" fn wallet_ffi_get_account_public( Err(e) => return e, }; - // Convert account data to FFI type - let data_vec: Vec = account.data.into(); - let data_len = data_vec.len(); - let data_ptr = if data_len > 0 { - let data_boxed = data_vec.into_boxed_slice(); - Box::into_raw(data_boxed) as *const u8 - } else { - ptr::null() - }; - - let program_owner = FfiProgramId { - data: account.program_owner, - }; - unsafe { - (*out_account).program_owner = program_owner; - (*out_account).balance = account.balance.to_le_bytes(); - (*out_account).nonce = account.nonce.to_le_bytes(); - (*out_account).data = data_ptr; - (*out_account).data_len = data_len; + *out_account = account.into(); } WalletFfiError::Success diff --git a/wallet-ffi/src/error.rs b/wallet-ffi/src/error.rs index ea366475..c57505a8 100644 --- a/wallet-ffi/src/error.rs +++ b/wallet-ffi/src/error.rs @@ -36,6 +36,8 @@ pub enum WalletFfiError { SyncError = 13, /// Serialization/deserialization error SerializationError = 14, + /// Found invalid data for account + InvalidAccountData, /// Internal error (catch-all) InternalError = 99, } diff --git a/wallet-ffi/src/types.rs b/wallet-ffi/src/types.rs index 3bcfd9fd..e7629afc 100644 --- a/wallet-ffi/src/types.rs +++ b/wallet-ffi/src/types.rs @@ -1,6 +1,11 @@ //! C-compatible type definitions for the FFI layer. -use std::ffi::c_char; +use core::slice; +use std::{ffi::c_char, ptr}; + +use nssa::{Account, Data}; + +use crate::error::WalletFfiError; /// Opaque pointer to the Wallet instance. /// @@ -149,3 +154,51 @@ impl From for nssa::AccountId { nssa::AccountId::new(bytes.data) } } + +impl From for FfiAccount { + fn from(value: nssa::Account) -> Self { + // Convert account data to FFI type + let data_vec: Vec = value.data.into(); + let data_len = data_vec.len(); + let data = if data_len > 0 { + let data_boxed = data_vec.into_boxed_slice(); + Box::into_raw(data_boxed) as *const u8 + } else { + ptr::null() + }; + + let program_owner = FfiProgramId { + data: value.program_owner, + }; + FfiAccount { + program_owner, + balance: value.balance.to_le_bytes(), + data, + data_len, + nonce: value.nonce.to_le_bytes(), + } + } +} + +impl TryFrom<&FfiAccount> for nssa::Account { + type Error = WalletFfiError; + + fn try_from(value: &FfiAccount) -> Result { + let data = if value.data_len > 0 { + unsafe { + let slice = slice::from_raw_parts(value.data, value.data_len); + Data::try_from(slice.to_vec()).map_err(|_| WalletFfiError::InvalidAccountData)? + } + } else { + Data::default() + }; + let balance = u128::from_le_bytes(value.balance); + let nonce = u128::from_le_bytes(value.nonce); + Ok(Account { + program_owner: value.program_owner.data, + balance, + data, + nonce, + }) + } +} diff --git a/wallet-ffi/wallet_ffi.h b/wallet-ffi/wallet_ffi.h index 70229e96..9b1850d8 100644 --- a/wallet-ffi/wallet_ffi.h +++ b/wallet-ffi/wallet_ffi.h @@ -95,6 +95,10 @@ typedef enum WalletFfiError { * Serialization/deserialization error */ SERIALIZATION_ERROR = 14, + /** + * Found invalid data for account + */ + INVALID_ACCOUNT_DATA, /** * Internal error (catch-all) */ diff --git a/wallet/src/lib.rs b/wallet/src/lib.rs index cdefd380..22e3be08 100644 --- a/wallet/src/lib.rs +++ b/wallet/src/lib.rs @@ -191,7 +191,6 @@ impl WalletCore { config.apply_overrides(config_overrides); } - println!("sequencer url: {}", config.sequencer_addr); let sequencer_client = Arc::new(SequencerClient::new_with_auth( Url::parse(&config.sequencer_addr)?, config.basic_auth.clone(), From fdeb1f971ca2fc83acbb72597218c2cc2b4852cd Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Wed, 4 Feb 2026 12:11:43 -0300 Subject: [PATCH 05/11] add get account keys test --- integration_tests/tests/wallet_ffi.rs | 44 +++++++++++++++++++++++++-- wallet-ffi/src/error.rs | 4 +-- wallet-ffi/src/keys.rs | 2 +- wallet-ffi/src/types.rs | 20 +++++++++++- wallet-ffi/wallet_ffi.h | 4 +-- 5 files changed, 66 insertions(+), 8 deletions(-) diff --git a/integration_tests/tests/wallet_ffi.rs b/integration_tests/tests/wallet_ffi.rs index a95ab319..03c6acb9 100644 --- a/integration_tests/tests/wallet_ffi.rs +++ b/integration_tests/tests/wallet_ffi.rs @@ -7,10 +7,12 @@ use std::{ use anyhow::Result; use integration_tests::{ACC_SENDER, TestContext}; use log::info; -use nssa::{Account, AccountId, program::Program}; +use nssa::{Account, AccountId, PublicKey, program::Program}; use tempfile::tempdir; use wallet::WalletCore; -use wallet_ffi::{FfiAccount, FfiAccountList, FfiBytes32, WalletHandle, error}; +use wallet_ffi::{ + FfiAccount, FfiAccountList, FfiBytes32, FfiPublicAccountKey, WalletHandle, error, +}; unsafe extern "C" { fn wallet_ffi_create_new( @@ -50,6 +52,12 @@ unsafe extern "C" { ) -> error::WalletFfiError; fn wallet_ffi_free_account_data(account: *mut FfiAccount); + + fn wallet_ffi_get_public_account_key( + handle: *mut WalletHandle, + account_id: *const FfiBytes32, + out_public_key: *mut FfiPublicAccountKey, + ) -> error::WalletFfiError; } fn new_wallet_ffi_with_test_context_config(ctx: &TestContext) -> *mut WalletHandle { @@ -329,3 +337,35 @@ fn test_wallet_ffi_get_account_public() -> Result<()> { Ok(()) } + +#[test] +fn test_wallet_ffi_get_public_account_keys() -> Result<()> { + let ctx = TestContext::new_blocking()?; + let account_id: AccountId = ACC_SENDER.parse().unwrap(); + let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx); + let mut out_key = FfiPublicAccountKey::default(); + + let key: PublicKey = unsafe { + let ffi_account_id = FfiBytes32::from(&account_id); + let _result = wallet_ffi_get_public_account_key( + wallet_ffi_handle, + (&ffi_account_id) as *const FfiBytes32, + (&mut out_key) as *mut FfiPublicAccountKey, + ); + (&out_key).try_into().unwrap() + }; + + let expected_key = { + let private_key = ctx + .wallet() + .get_account_public_signing_key(&account_id) + .unwrap(); + PublicKey::new_from_private_key(private_key) + }; + + assert_eq!(key, expected_key); + + info!("Successfully retrieved account key"); + + Ok(()) +} diff --git a/wallet-ffi/src/error.rs b/wallet-ffi/src/error.rs index c57505a8..3cae2f25 100644 --- a/wallet-ffi/src/error.rs +++ b/wallet-ffi/src/error.rs @@ -36,8 +36,8 @@ pub enum WalletFfiError { SyncError = 13, /// Serialization/deserialization error SerializationError = 14, - /// Found invalid data for account - InvalidAccountData, + /// Invalid conversion from FFI types to NSSA types + InvalidTypeConversion, /// Internal error (catch-all) InternalError = 99, } diff --git a/wallet-ffi/src/keys.rs b/wallet-ffi/src/keys.rs index e8309a81..08661a50 100644 --- a/wallet-ffi/src/keys.rs +++ b/wallet-ffi/src/keys.rs @@ -65,7 +65,7 @@ pub unsafe extern "C" fn wallet_ffi_get_public_account_key( let public_key = PublicKey::new_from_private_key(private_key); unsafe { - (*out_public_key).public_key.data = *public_key.value(); + *out_public_key = public_key.into(); } WalletFfiError::Success diff --git a/wallet-ffi/src/types.rs b/wallet-ffi/src/types.rs index e7629afc..0078e09f 100644 --- a/wallet-ffi/src/types.rs +++ b/wallet-ffi/src/types.rs @@ -187,7 +187,7 @@ impl TryFrom<&FfiAccount> for nssa::Account { let data = if value.data_len > 0 { unsafe { let slice = slice::from_raw_parts(value.data, value.data_len); - Data::try_from(slice.to_vec()).map_err(|_| WalletFfiError::InvalidAccountData)? + Data::try_from(slice.to_vec()).map_err(|_| WalletFfiError::InvalidTypeConversion)? } } else { Data::default() @@ -202,3 +202,21 @@ impl TryFrom<&FfiAccount> for nssa::Account { }) } } + +impl From for FfiPublicAccountKey { + fn from(value: nssa::PublicKey) -> Self { + Self { + public_key: FfiBytes32::from_bytes(*value.value()), + } + } +} + +impl TryFrom<&FfiPublicAccountKey> for nssa::PublicKey { + type Error = WalletFfiError; + + fn try_from(value: &FfiPublicAccountKey) -> Result { + let public_key = nssa::PublicKey::try_new(value.public_key.data) + .map_err(|_| WalletFfiError::InvalidTypeConversion)?; + Ok(public_key) + } +} diff --git a/wallet-ffi/wallet_ffi.h b/wallet-ffi/wallet_ffi.h index 9b1850d8..fae24a4d 100644 --- a/wallet-ffi/wallet_ffi.h +++ b/wallet-ffi/wallet_ffi.h @@ -96,9 +96,9 @@ typedef enum WalletFfiError { */ SERIALIZATION_ERROR = 14, /** - * Found invalid data for account + * Invalid conversion from FFI types to NSSA types */ - INVALID_ACCOUNT_DATA, + INVALID_TYPE_CONVERSION, /** * Internal error (catch-all) */ From 70d3b3a3e6912fb1c787cbe14e5fc930df4079ec Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Wed, 4 Feb 2026 14:53:54 -0300 Subject: [PATCH 06/11] add FfiU128 struct --- integration_tests/tests/wallet_ffi.rs | 41 ++++++++++++++++++++++++++- wallet-ffi/src/types.rs | 39 ++++++++++++++++++------- wallet-ffi/wallet_ffi.h | 11 +++++-- 3 files changed, 78 insertions(+), 13 deletions(-) diff --git a/integration_tests/tests/wallet_ffi.rs b/integration_tests/tests/wallet_ffi.rs index 03c6acb9..4599a79e 100644 --- a/integration_tests/tests/wallet_ffi.rs +++ b/integration_tests/tests/wallet_ffi.rs @@ -11,7 +11,8 @@ use nssa::{Account, AccountId, PublicKey, program::Program}; use tempfile::tempdir; use wallet::WalletCore; use wallet_ffi::{ - FfiAccount, FfiAccountList, FfiBytes32, FfiPublicAccountKey, WalletHandle, error, + FfiAccount, FfiAccountList, FfiBytes32, FfiPrivateAccountKeys, FfiPublicAccountKey, + WalletHandle, error, }; unsafe extern "C" { @@ -58,6 +59,12 @@ unsafe extern "C" { account_id: *const FfiBytes32, out_public_key: *mut FfiPublicAccountKey, ) -> error::WalletFfiError; + + fn wallet_ffi_get_private_account_keys( + handle: *mut WalletHandle, + account_id: *const FfiBytes32, + out_keys: *mut FfiPrivateAccountKeys, + ) -> error::WalletFfiError; } fn new_wallet_ffi_with_test_context_config(ctx: &TestContext) -> *mut WalletHandle { @@ -369,3 +376,35 @@ fn test_wallet_ffi_get_public_account_keys() -> Result<()> { Ok(()) } + +// #[test] +// fn test_wallet_ffi_get_private_account_keys() -> Result<()> { +// let ctx = TestContext::new_blocking()?; +// let account_id: AccountId = ACC_SENDER.parse().unwrap(); +// let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx); +// let mut out_key = FfiPrivateAccountKeys::default(); +// +// let key: PublicKey = unsafe { +// let ffi_account_id = FfiBytes32::from(&account_id); +// let _result = wallet_ffi_get_private_account_keys( +// wallet_ffi_handle, +// (&ffi_account_id) as *const FfiBytes32, +// (&mut out_key) as *mut FfiPublicAccountKey, +// ); +// (&out_key).try_into().unwrap() +// }; +// +// let expected_key = { +// let private_key = ctx +// .wallet() +// .get_account_public_signing_key(&account_id) +// .unwrap(); +// PublicKey::new_from_private_key(private_key) +// }; +// +// assert_eq!(key, expected_key); +// +// info!("Successfully retrieved account key"); +// +// Ok(()) +// } diff --git a/wallet-ffi/src/types.rs b/wallet-ffi/src/types.rs index 0078e09f..dea1ac94 100644 --- a/wallet-ffi/src/types.rs +++ b/wallet-ffi/src/types.rs @@ -30,6 +30,13 @@ pub struct FfiProgramId { pub data: [u32; 8], } +/// U128 - 16 bytes little endian +#[repr(C)] +#[derive(Clone, Copy, Default)] +pub struct FfiU128 { + pub data: [u8; 16], +} + /// Account data structure - C-compatible version of nssa Account. /// /// Note: `balance` and `nonce` are u128 values represented as little-endian @@ -38,23 +45,23 @@ pub struct FfiProgramId { pub struct FfiAccount { pub program_owner: FfiProgramId, /// Balance as little-endian [u8; 16] - pub balance: [u8; 16], + pub balance: FfiU128, /// Pointer to account data bytes pub data: *const u8, /// Length of account data pub data_len: usize, /// Nonce as little-endian [u8; 16] - pub nonce: [u8; 16], + pub nonce: FfiU128, } impl Default for FfiAccount { fn default() -> Self { Self { program_owner: FfiProgramId::default(), - balance: [0u8; 16], + balance: FfiU128::default(), data: std::ptr::null(), data_len: 0, - nonce: [0u8; 16], + nonce: FfiU128::default(), } } } @@ -143,6 +150,20 @@ impl FfiBytes32 { } } +impl From for FfiU128 { + fn from(value: u128) -> Self { + Self { + data: value.to_le_bytes(), + } + } +} + +impl From for u128 { + fn from(value: FfiU128) -> Self { + u128::from_le_bytes(value.data) + } +} + impl From<&nssa::AccountId> for FfiBytes32 { fn from(id: &nssa::AccountId) -> Self { Self::from_account_id(id) @@ -172,10 +193,10 @@ impl From for FfiAccount { }; FfiAccount { program_owner, - balance: value.balance.to_le_bytes(), + balance: value.balance.into(), data, data_len, - nonce: value.nonce.to_le_bytes(), + nonce: value.nonce.into(), } } } @@ -192,13 +213,11 @@ impl TryFrom<&FfiAccount> for nssa::Account { } else { Data::default() }; - let balance = u128::from_le_bytes(value.balance); - let nonce = u128::from_le_bytes(value.nonce); Ok(Account { program_owner: value.program_owner.data, - balance, + balance: value.balance.into(), data, - nonce, + nonce: value.nonce.into(), }) } } diff --git a/wallet-ffi/wallet_ffi.h b/wallet-ffi/wallet_ffi.h index fae24a4d..e731db79 100644 --- a/wallet-ffi/wallet_ffi.h +++ b/wallet-ffi/wallet_ffi.h @@ -145,6 +145,13 @@ typedef struct FfiProgramId { uint32_t data[8]; } FfiProgramId; +/** + * U128 - 16 bytes little endian + */ +typedef struct FfiU128 { + uint8_t data[16]; +} FfiU128; + /** * Account data structure - C-compatible version of nssa Account. * @@ -156,7 +163,7 @@ typedef struct FfiAccount { /** * Balance as little-endian [u8; 16] */ - uint8_t balance[16]; + struct FfiU128 balance; /** * Pointer to account data bytes */ @@ -168,7 +175,7 @@ typedef struct FfiAccount { /** * Nonce as little-endian [u8; 16] */ - uint8_t nonce[16]; + struct FfiU128 nonce; } FfiAccount; /** From 7c3182d903fb997e7a5c71e21ab3efc4ad780dee Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Wed, 4 Feb 2026 15:27:39 -0300 Subject: [PATCH 07/11] add wallet ffi get private keys test --- Cargo.lock | 1 + integration_tests/tests/wallet_ffi.rs | 73 +++++++++++++++------------ wallet-ffi/Cargo.toml | 1 + wallet-ffi/src/error.rs | 2 + wallet-ffi/src/types.rs | 21 ++++++++ wallet-ffi/wallet_ffi.h | 4 ++ 6 files changed, 70 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 11f0cb7e..9204fc28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6745,6 +6745,7 @@ dependencies = [ "cbindgen", "common", "nssa", + "nssa_core", "tempfile", "tokio", "wallet", diff --git a/integration_tests/tests/wallet_ffi.rs b/integration_tests/tests/wallet_ffi.rs index 4599a79e..51cb31bb 100644 --- a/integration_tests/tests/wallet_ffi.rs +++ b/integration_tests/tests/wallet_ffi.rs @@ -5,7 +5,7 @@ use std::{ }; use anyhow::Result; -use integration_tests::{ACC_SENDER, TestContext}; +use integration_tests::{ACC_SENDER, ACC_SENDER_PRIVATE, TestContext}; use log::info; use nssa::{Account, AccountId, PublicKey, program::Program}; use tempfile::tempdir; @@ -65,6 +65,8 @@ unsafe extern "C" { account_id: *const FfiBytes32, out_keys: *mut FfiPrivateAccountKeys, ) -> error::WalletFfiError; + + fn wallet_ffi_free_private_account_keys(keys: *mut FfiPrivateAccountKeys); } fn new_wallet_ffi_with_test_context_config(ctx: &TestContext) -> *mut WalletHandle { @@ -377,34 +379,41 @@ fn test_wallet_ffi_get_public_account_keys() -> Result<()> { Ok(()) } -// #[test] -// fn test_wallet_ffi_get_private_account_keys() -> Result<()> { -// let ctx = TestContext::new_blocking()?; -// let account_id: AccountId = ACC_SENDER.parse().unwrap(); -// let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx); -// let mut out_key = FfiPrivateAccountKeys::default(); -// -// let key: PublicKey = unsafe { -// let ffi_account_id = FfiBytes32::from(&account_id); -// let _result = wallet_ffi_get_private_account_keys( -// wallet_ffi_handle, -// (&ffi_account_id) as *const FfiBytes32, -// (&mut out_key) as *mut FfiPublicAccountKey, -// ); -// (&out_key).try_into().unwrap() -// }; -// -// let expected_key = { -// let private_key = ctx -// .wallet() -// .get_account_public_signing_key(&account_id) -// .unwrap(); -// PublicKey::new_from_private_key(private_key) -// }; -// -// assert_eq!(key, expected_key); -// -// info!("Successfully retrieved account key"); -// -// Ok(()) -// } +#[test] +fn test_wallet_ffi_get_private_account_keys() -> Result<()> { + let ctx = TestContext::new_blocking()?; + let account_id: AccountId = ACC_SENDER_PRIVATE.parse().unwrap(); + let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx); + let mut keys = FfiPrivateAccountKeys::default(); + + unsafe { + let ffi_account_id = FfiBytes32::from(&account_id); + let _result = wallet_ffi_get_private_account_keys( + wallet_ffi_handle, + (&ffi_account_id) as *const FfiBytes32, + (&mut keys) as *mut FfiPrivateAccountKeys, + ); + }; + + let key_chain = &ctx + .wallet() + .storage() + .user_data + .get_private_account(&account_id) + .unwrap() + .0; + + let expected_npk = &key_chain.nullifer_public_key; + let expected_ivk = &key_chain.incoming_viewing_public_key; + + assert_eq!(&keys.npk(), expected_npk); + assert_eq!(&keys.ivk().unwrap(), expected_ivk); + + unsafe { + wallet_ffi_free_private_account_keys((&mut keys) as *mut FfiPrivateAccountKeys); + } + + info!("Successfully retrieved account keys"); + + Ok(()) +} diff --git a/wallet-ffi/Cargo.toml b/wallet-ffi/Cargo.toml index c02e58ee..109d9e5b 100644 --- a/wallet-ffi/Cargo.toml +++ b/wallet-ffi/Cargo.toml @@ -10,6 +10,7 @@ crate-type = ["rlib", "cdylib", "staticlib"] wallet.workspace = true nssa.workspace = true common.workspace = true +nssa_core.workspace = true tokio.workspace = true [build-dependencies] diff --git a/wallet-ffi/src/error.rs b/wallet-ffi/src/error.rs index 3cae2f25..d2f615c3 100644 --- a/wallet-ffi/src/error.rs +++ b/wallet-ffi/src/error.rs @@ -38,6 +38,8 @@ pub enum WalletFfiError { SerializationError = 14, /// Invalid conversion from FFI types to NSSA types InvalidTypeConversion, + /// Invalid Key value + InvalidKeyValue, /// Internal error (catch-all) InternalError = 99, } diff --git a/wallet-ffi/src/types.rs b/wallet-ffi/src/types.rs index dea1ac94..a1d70181 100644 --- a/wallet-ffi/src/types.rs +++ b/wallet-ffi/src/types.rs @@ -4,6 +4,7 @@ use core::slice; use std::{ffi::c_char, ptr}; use nssa::{Account, Data}; +use nssa_core::encryption::shared_key_derivation::Secp256k1Point; use crate::error::WalletFfiError; @@ -150,6 +151,26 @@ impl FfiBytes32 { } } +impl FfiPrivateAccountKeys { + pub fn npk(&self) -> nssa_core::NullifierPublicKey { + nssa_core::NullifierPublicKey(self.nullifier_public_key.data) + } + + pub fn ivk(&self) -> Result { + if self.incoming_viewing_public_key_len == 33 { + let slice = unsafe { + slice::from_raw_parts( + self.incoming_viewing_public_key, + self.incoming_viewing_public_key_len, + ) + }; + Ok(Secp256k1Point(slice.to_vec())) + } else { + Err(WalletFfiError::InvalidKeyValue) + } + } +} + impl From for FfiU128 { fn from(value: u128) -> Self { Self { diff --git a/wallet-ffi/wallet_ffi.h b/wallet-ffi/wallet_ffi.h index e731db79..afab46e1 100644 --- a/wallet-ffi/wallet_ffi.h +++ b/wallet-ffi/wallet_ffi.h @@ -99,6 +99,10 @@ typedef enum WalletFfiError { * Invalid conversion from FFI types to NSSA types */ INVALID_TYPE_CONVERSION, + /** + * Invalid Key value + */ + INVALID_KEY_VALUE, /** * Internal error (catch-all) */ From 4b50676ebcf81a410c3f1075a3e00ddf6ead3768 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Wed, 4 Feb 2026 16:08:04 -0300 Subject: [PATCH 08/11] add wallet ffi base58 conversion tests --- integration_tests/tests/wallet_ffi.rs | 45 ++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/integration_tests/tests/wallet_ffi.rs b/integration_tests/tests/wallet_ffi.rs index 51cb31bb..bd606c2d 100644 --- a/integration_tests/tests/wallet_ffi.rs +++ b/integration_tests/tests/wallet_ffi.rs @@ -1,6 +1,6 @@ use std::{ collections::HashSet, - ffi::{CString, c_char}, + ffi::{CStr, CString, c_char}, io::Write, }; @@ -67,6 +67,15 @@ unsafe extern "C" { ) -> error::WalletFfiError; fn wallet_ffi_free_private_account_keys(keys: *mut FfiPrivateAccountKeys); + + fn wallet_ffi_account_id_to_base58(account_id: *const FfiBytes32) -> *mut std::ffi::c_char; + + fn wallet_ffi_free_string(ptr: *mut c_char); + + fn wallet_ffi_account_id_from_base58( + base58_str: *const std::ffi::c_char, + out_account_id: *mut FfiBytes32, + ) -> error::WalletFfiError; } fn new_wallet_ffi_with_test_context_config(ctx: &TestContext) -> *mut WalletHandle { @@ -417,3 +426,37 @@ fn test_wallet_ffi_get_private_account_keys() -> Result<()> { Ok(()) } + +#[test] +fn test_wallet_ffi_account_id_to_base58() { + let account_id_str = ACC_SENDER; + let account_id: AccountId = account_id_str.parse().unwrap(); + let ffi_bytes: FfiBytes32 = (&account_id).into(); + let ptr = unsafe { wallet_ffi_account_id_to_base58((&ffi_bytes) as *const FfiBytes32) }; + + let ffi_result = unsafe { CStr::from_ptr(ptr).to_str().unwrap() }; + + assert_eq!(account_id_str, ffi_result); + + unsafe { + wallet_ffi_free_string(ptr); + } +} + +#[test] +fn test_wallet_ffi_base58_to_account_id() { + let account_id_str = ACC_SENDER; + let account_id_c_str = CString::new(account_id_str).unwrap(); + let account_id: AccountId = unsafe { + let mut out_account_id_bytes = FfiBytes32::default(); + wallet_ffi_account_id_from_base58( + account_id_c_str.as_ptr(), + (&mut out_account_id_bytes) as *mut FfiBytes32, + ); + out_account_id_bytes.into() + }; + + let expected_account_id = account_id_str.parse().unwrap(); + + assert_eq!(account_id, expected_account_id); +} From b1840ca68abdd7ae137a773543eb47c560be2f39 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Wed, 4 Feb 2026 20:12:55 -0300 Subject: [PATCH 09/11] add test wallet ffi auth-transfer init call --- integration_tests/src/lib.rs | 19 ++- integration_tests/tests/wallet_ffi.rs | 161 ++++++++++++++++++++++++-- 2 files changed, 162 insertions(+), 18 deletions(-) diff --git a/integration_tests/src/lib.rs b/integration_tests/src/lib.rs index 334912e5..78632eb5 100644 --- a/integration_tests/src/lib.rs +++ b/integration_tests/src/lib.rs @@ -63,12 +63,6 @@ impl TestContext { Self::new_with_sequencer_and_maybe_indexer_configs(sequencer_config, None).await } - pub fn new_blocking() -> Result { - tokio::runtime::Runtime::new() - .unwrap() - .block_on(Self::new()) - } - /// Create new test context in local bedrock node attached mode. pub async fn new_bedrock_local_attached() -> Result { let manifest_dir = env!("CARGO_MANIFEST_DIR"); @@ -283,6 +277,19 @@ impl Drop for TestContext { } } +pub struct BlockingTestContext { + pub ctx: TestContext, + pub runtime: tokio::runtime::Runtime, +} + +impl BlockingTestContext { + pub fn new() -> Result { + let runtime = tokio::runtime::Runtime::new().unwrap(); + let ctx = runtime.block_on(TestContext::new())?; + Ok(Self { ctx, runtime }) + } +} + pub fn format_public_account_id(account_id: &str) -> String { format!("Public/{account_id}") } diff --git a/integration_tests/tests/wallet_ffi.rs b/integration_tests/tests/wallet_ffi.rs index bd606c2d..6be64af5 100644 --- a/integration_tests/tests/wallet_ffi.rs +++ b/integration_tests/tests/wallet_ffi.rs @@ -2,17 +2,22 @@ use std::{ collections::HashSet, ffi::{CStr, CString, c_char}, io::Write, + time::Duration, }; use anyhow::Result; -use integration_tests::{ACC_SENDER, ACC_SENDER_PRIVATE, TestContext}; +use integration_tests::{ + ACC_RECEIVER, ACC_SENDER, ACC_SENDER_PRIVATE, BlockingTestContext, + TIME_TO_WAIT_FOR_BLOCK_SECONDS, +}; use log::info; use nssa::{Account, AccountId, PublicKey, program::Program}; +use nssa_core::program::DEFAULT_PROGRAM_ID; use tempfile::tempdir; use wallet::WalletCore; use wallet_ffi::{ FfiAccount, FfiAccountList, FfiBytes32, FfiPrivateAccountKeys, FfiPublicAccountKey, - WalletHandle, error, + FfiTransferResult, WalletHandle, error, }; unsafe extern "C" { @@ -76,14 +81,30 @@ unsafe extern "C" { base58_str: *const std::ffi::c_char, out_account_id: *mut FfiBytes32, ) -> error::WalletFfiError; + + fn wallet_ffi_transfer_public( + handle: *mut WalletHandle, + from: *const FfiBytes32, + to: *const FfiBytes32, + amount: *const [u8; 16], + out_result: *mut FfiTransferResult, + ) -> error::WalletFfiError; + + fn wallet_ffi_free_transfer_result(result: *mut FfiTransferResult); + + fn wallet_ffi_register_public_account( + handle: *mut WalletHandle, + account_id: *const FfiBytes32, + out_result: *mut FfiTransferResult, + ) -> error::WalletFfiError; } -fn new_wallet_ffi_with_test_context_config(ctx: &TestContext) -> *mut WalletHandle { +fn new_wallet_ffi_with_test_context_config(ctx: &BlockingTestContext) -> *mut WalletHandle { let tempdir = tempfile::tempdir().unwrap(); let config_path = tempdir.path().join("wallet_config.json"); let storage_path = tempdir.path().join("storage.json"); - let mut config = ctx.wallet().config().to_owned(); - if let Some(config_overrides) = ctx.wallet().config_overrides().clone() { + let mut config = ctx.ctx.wallet().config().to_owned(); + if let Some(config_overrides) = ctx.ctx.wallet().config_overrides().clone() { config.apply_overrides(config_overrides); } let mut file = std::fs::OpenOptions::new() @@ -99,7 +120,7 @@ fn new_wallet_ffi_with_test_context_config(ctx: &TestContext) -> *mut WalletHand let config_path = CString::new(config_path.to_str().unwrap()).unwrap(); let storage_path = CString::new(storage_path.to_str().unwrap()).unwrap(); - let password = CString::new(ctx.wallet_password()).unwrap(); + let password = CString::new(ctx.ctx.wallet_password()).unwrap(); unsafe { wallet_ffi_create_new( @@ -299,7 +320,7 @@ fn test_wallet_ffi_list_accounts() { #[test] fn test_wallet_ffi_get_balance_public() -> Result<()> { - let ctx = TestContext::new_blocking()?; + let ctx = BlockingTestContext::new()?; let account_id: AccountId = ACC_SENDER.parse().unwrap(); let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx); @@ -312,9 +333,8 @@ fn test_wallet_ffi_get_balance_public() -> Result<()> { true, (&mut out_balance) as *mut [u8; 16], ); - out_balance + u128::from_le_bytes(out_balance) }; - let balance = u128::from_le_bytes(balance); assert_eq!(balance, 10000); info!("Successfully retrieved account balance"); @@ -324,7 +344,7 @@ fn test_wallet_ffi_get_balance_public() -> Result<()> { #[test] fn test_wallet_ffi_get_account_public() -> Result<()> { - let ctx = TestContext::new_blocking()?; + let ctx = BlockingTestContext::new()?; let account_id: AccountId = ACC_SENDER.parse().unwrap(); let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx); let mut out_account = FfiAccount::default(); @@ -358,7 +378,7 @@ fn test_wallet_ffi_get_account_public() -> Result<()> { #[test] fn test_wallet_ffi_get_public_account_keys() -> Result<()> { - let ctx = TestContext::new_blocking()?; + let ctx = BlockingTestContext::new()?; let account_id: AccountId = ACC_SENDER.parse().unwrap(); let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx); let mut out_key = FfiPublicAccountKey::default(); @@ -375,6 +395,7 @@ fn test_wallet_ffi_get_public_account_keys() -> Result<()> { let expected_key = { let private_key = ctx + .ctx .wallet() .get_account_public_signing_key(&account_id) .unwrap(); @@ -390,7 +411,7 @@ fn test_wallet_ffi_get_public_account_keys() -> Result<()> { #[test] fn test_wallet_ffi_get_private_account_keys() -> Result<()> { - let ctx = TestContext::new_blocking()?; + let ctx = BlockingTestContext::new()?; let account_id: AccountId = ACC_SENDER_PRIVATE.parse().unwrap(); let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx); let mut keys = FfiPrivateAccountKeys::default(); @@ -405,6 +426,7 @@ fn test_wallet_ffi_get_private_account_keys() -> Result<()> { }; let key_chain = &ctx + .ctx .wallet() .storage() .user_data @@ -460,3 +482,118 @@ fn test_wallet_ffi_base58_to_account_id() { assert_eq!(account_id, expected_account_id); } + +#[test] +fn test_wallet_ffi_init_public_account_auth_transfer() -> Result<()> { + let ctx = BlockingTestContext::new().unwrap(); + let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx); + + // Create a new uninitialized public account + let mut out_account_id = FfiBytes32::from_bytes([0; 32]); + unsafe { + wallet_ffi_create_account_public( + wallet_ffi_handle, + (&mut out_account_id) as *mut FfiBytes32, + ); + } + + // Check its program owner is the default program id + let account: Account = unsafe { + let mut out_account = FfiAccount::default(); + let _result = wallet_ffi_get_account_public( + wallet_ffi_handle, + (&out_account_id) as *const FfiBytes32, + (&mut out_account) as *mut FfiAccount, + ); + (&out_account).try_into().unwrap() + }; + assert_eq!(account.program_owner, DEFAULT_PROGRAM_ID); + + // Call the init funciton + let mut transfer_result = FfiTransferResult::default(); + unsafe { + wallet_ffi_register_public_account( + wallet_ffi_handle, + (&out_account_id) as *const FfiBytes32, + (&mut transfer_result) as *mut FfiTransferResult, + ); + } + + info!("Waiting for next block creation"); + std::thread::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)); + + // Check that the program owner is now the authenticated transfer program + let account: Account = unsafe { + let mut out_account = FfiAccount::default(); + let _result = wallet_ffi_get_account_public( + wallet_ffi_handle, + (&out_account_id) as *const FfiBytes32, + (&mut out_account) as *mut FfiAccount, + ); + (&out_account).try_into().unwrap() + }; + assert_eq!( + account.program_owner, + Program::authenticated_transfer_program().id() + ); + + unsafe { + wallet_ffi_free_transfer_result((&mut transfer_result) as *mut FfiTransferResult); + } + + Ok(()) +} + +#[test] +fn test_wallet_ffi_transfer_public() -> Result<()> { + let ctx = BlockingTestContext::new().unwrap(); + let wallet_ffi_handle = new_wallet_ffi_with_test_context_config(&ctx); + let from: FfiBytes32 = (&ACC_SENDER.parse::().unwrap()).into(); + let to: FfiBytes32 = (&ACC_RECEIVER.parse::().unwrap()).into(); + let amount: [u8; 16] = 100u128.to_le_bytes(); + + let mut transfer_result = FfiTransferResult::default(); + unsafe { + wallet_ffi_transfer_public( + wallet_ffi_handle, + (&from) as *const FfiBytes32, + (&to) as *const FfiBytes32, + (&amount) as *const [u8; 16], + (&mut transfer_result) as *mut FfiTransferResult, + ); + } + + info!("Waiting for next block creation"); + std::thread::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)); + + let from_balance = unsafe { + let mut out_balance: [u8; 16] = [0; 16]; + let _result = wallet_ffi_get_balance( + wallet_ffi_handle, + (&from) as *const FfiBytes32, + true, + (&mut out_balance) as *mut [u8; 16], + ); + u128::from_le_bytes(out_balance) + }; + + let to_balance = unsafe { + let mut out_balance: [u8; 16] = [0; 16]; + let _result = wallet_ffi_get_balance( + wallet_ffi_handle, + (&to) as *const FfiBytes32, + true, + (&mut out_balance) as *mut [u8; 16], + ); + u128::from_le_bytes(out_balance) + }; + + assert_eq!(from_balance, 9900); + assert_eq!(to_balance, 20100); + + unsafe { + wallet_ffi_free_transfer_result((&mut transfer_result) as *mut FfiTransferResult); + } + + Ok(()) +} From 709f189aa12af4fd1697d1e878af8c201e22e0a3 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Thu, 5 Feb 2026 12:14:32 -0300 Subject: [PATCH 10/11] remove print line --- wallet-ffi/src/account.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/wallet-ffi/src/account.rs b/wallet-ffi/src/account.rs index d96369d0..cf237276 100644 --- a/wallet-ffi/src/account.rs +++ b/wallet-ffi/src/account.rs @@ -99,7 +99,6 @@ pub unsafe extern "C" fn wallet_ffi_create_account_private( }; let (account_id, _chain_index) = wallet.create_new_account_private(None); - println!("_chain_index: {_chain_index}"); unsafe { (*out_account_id).data = *account_id.value(); From e0caa7838dd15b3d3531354901a641c2ccba3382 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Thu, 5 Feb 2026 12:25:21 -0300 Subject: [PATCH 11/11] destroy wallet in tests and add variant numbers to the error enum --- integration_tests/tests/wallet_ffi.rs | 23 +++++++++++++++++++++-- wallet-ffi/src/error.rs | 4 ++-- wallet-ffi/wallet_ffi.h | 4 ++-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/integration_tests/tests/wallet_ffi.rs b/integration_tests/tests/wallet_ffi.rs index 6be64af5..bb6b9805 100644 --- a/integration_tests/tests/wallet_ffi.rs +++ b/integration_tests/tests/wallet_ffi.rs @@ -27,6 +27,8 @@ unsafe extern "C" { password: *const c_char, ) -> *mut WalletHandle; + fn wallet_ffi_destroy(handle: *mut WalletHandle); + fn wallet_ffi_create_account_public( handle: *mut WalletHandle, out_account_id: *mut FfiBytes32, @@ -191,10 +193,11 @@ fn test_wallet_ffi_create_public_accounts() { ); account_ids.push(out_account_id.data); } + wallet_ffi_destroy(wallet_ffi_handle); account_ids }; - assert_eq!(new_public_account_ids_ffi, new_public_account_ids_rust) + assert_eq!(new_public_account_ids_ffi, new_public_account_ids_rust); } #[test] @@ -226,6 +229,7 @@ fn test_wallet_ffi_create_private_accounts() { ); account_ids.push(out_account_id.data); } + wallet_ffi_destroy(wallet_ffi_handle); account_ids }; @@ -315,7 +319,10 @@ fn test_wallet_ffi_list_accounts() { assert_eq!(entry.is_public, is_public_in_rust_wallet); } - unsafe { wallet_ffi_free_account_list((&mut wallet_ffi_account_list) as *mut FfiAccountList) }; + unsafe { + wallet_ffi_free_account_list((&mut wallet_ffi_account_list) as *mut FfiAccountList); + wallet_ffi_destroy(wallet_ffi_handle); + } } #[test] @@ -339,6 +346,10 @@ fn test_wallet_ffi_get_balance_public() -> Result<()> { info!("Successfully retrieved account balance"); + unsafe { + wallet_ffi_destroy(wallet_ffi_handle); + } + Ok(()) } @@ -369,6 +380,7 @@ fn test_wallet_ffi_get_account_public() -> Result<()> { unsafe { wallet_ffi_free_account_data((&mut out_account) as *mut FfiAccount); + wallet_ffi_destroy(wallet_ffi_handle); } info!("Successfully retrieved account with correct details"); @@ -406,6 +418,10 @@ fn test_wallet_ffi_get_public_account_keys() -> Result<()> { info!("Successfully retrieved account key"); + unsafe { + wallet_ffi_destroy(wallet_ffi_handle); + } + Ok(()) } @@ -442,6 +458,7 @@ fn test_wallet_ffi_get_private_account_keys() -> Result<()> { unsafe { wallet_ffi_free_private_account_keys((&mut keys) as *mut FfiPrivateAccountKeys); + wallet_ffi_destroy(wallet_ffi_handle); } info!("Successfully retrieved account keys"); @@ -539,6 +556,7 @@ fn test_wallet_ffi_init_public_account_auth_transfer() -> Result<()> { unsafe { wallet_ffi_free_transfer_result((&mut transfer_result) as *mut FfiTransferResult); + wallet_ffi_destroy(wallet_ffi_handle); } Ok(()) @@ -593,6 +611,7 @@ fn test_wallet_ffi_transfer_public() -> Result<()> { unsafe { wallet_ffi_free_transfer_result((&mut transfer_result) as *mut FfiTransferResult); + wallet_ffi_destroy(wallet_ffi_handle); } Ok(()) diff --git a/wallet-ffi/src/error.rs b/wallet-ffi/src/error.rs index d2f615c3..ab9ce6dd 100644 --- a/wallet-ffi/src/error.rs +++ b/wallet-ffi/src/error.rs @@ -37,9 +37,9 @@ pub enum WalletFfiError { /// Serialization/deserialization error SerializationError = 14, /// Invalid conversion from FFI types to NSSA types - InvalidTypeConversion, + InvalidTypeConversion = 15, /// Invalid Key value - InvalidKeyValue, + InvalidKeyValue = 16, /// Internal error (catch-all) InternalError = 99, } diff --git a/wallet-ffi/wallet_ffi.h b/wallet-ffi/wallet_ffi.h index 339a2427..4d282221 100644 --- a/wallet-ffi/wallet_ffi.h +++ b/wallet-ffi/wallet_ffi.h @@ -98,11 +98,11 @@ typedef enum WalletFfiError { /** * Invalid conversion from FFI types to NSSA types */ - INVALID_TYPE_CONVERSION, + INVALID_TYPE_CONVERSION = 15, /** * Invalid Key value */ - INVALID_KEY_VALUE, + INVALID_KEY_VALUE = 16, /** * Internal error (catch-all) */