From aac3aa9a6227c3bcad5da1034a1e13362e8f2b89 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 7 May 2026 22:47:51 +0700 Subject: [PATCH 1/2] chore(deps): bump rust-dashcore to v0.42-dev (428b60d) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switches from the diverged v0.42-platform-nightly branch (fe247661) to v0.42-dev HEAD (428b60d). The nightly branch had accumulated parallel work that's been superseded by clean upstream merges; v0.42-dev is now the canonical line. Adopts these upstream PRs in addition to the dep bump: - dashpay/rust-dashcore#742 — wire ManagedCoreKeysAccount into the collection: ManagedAccountCollection now stores funds-bearing and keys-only accounts in separate fields and spanning accessors return ManagedAccountRef<'a> (a borrowed enum). Funds-only operations require an explicit as_funds() unwrap. - dashpay/rust-dashcore#727 — tx building / signing logic moved into key-wallet and key-wallet-manager. next_receive_address / next_change_address now return Option
instead of Result, and AccountTypePreference is a 2-variant enum. - dashpay/rust-dashcore#710 — wallet_create_managed_wallet FFI removed. The proper construction path is via WalletManager. - dashpay/rust-dashcore#733 — keep-finalized-transactions Cargo feature (replaces the nightly's keep_txs_in_memory toggle). - dashpay/rust-dashcore#729 / #708 — serde tolerance for ContentDeserializer's HR-quirk on OutPoint and Hash types. - dashpay/rust-dashcore#738 / #739 / #737 / #736 / #721 / #724 / #697 — internal dash-spv refactors / docs / tests / seed refresh; no platform-side changes required. Platform-side adaptations: * `transactions` field on ManagedCoreFundsAccount is now the trait method `transactions()` returning `&BTreeMap`. Migrated 5 sites in rs-platform-wallet/src/wallet/asset_lock to use the accessor (added `ManagedAccountTrait` imports where needed). * `managed_account_type` is now an accessor method on the trait. Updated the dashpay_receival_accounts walk in wallet/identity/network/contacts.rs. * `insert_funds` renamed to `insert_funds_bearing_account` on ManagedAccountCollection — 2 sites in contacts.rs. * `address_derivation_path` lives on ManagedAccountTrait, not on the ref-enum. broadcast.rs and payments.rs now go through `account.keys_account().address_derivation_path(...)` since address pools live on the keys variant after the split. * `next_address` resolves through the trait — added imports in payments.rs and asset_lock/build.rs. * The two `transactions_iter()` callers in manager/accessors.rs switch to `transactions().values()` (clippy-preferred). * Comments referencing the nightly's `keep_txs_in_memory` toggle renamed to upstream's `keep-finalized-transactions`. * Removed the orphaned Swift `ManagedWallet` class (KeyWallet/ManagedWallet.swift) and the KeyWalletManagedWallet typealias. Its only public init called the upstream-removed `wallet_create_managed_wallet`, and no production code constructed it. Per the swift-sdk CLAUDE.md ownership rules, managed-wallet construction is reached via WalletManager rather than a state-empty Swift-side wrapper. Adds a forwarded `keep-finalized-transactions` feature on platform-wallet (off by default). When enabled, it forwards to key-wallet/key-wallet-manager's same feature so the in-memory transactions map retains chainlocked records (useful for debug surfaces). Default off matches the production model where tx history is delivered through the event channel. What's lost from the nightly branch (deferred, not blocking): - `feat(dash-spv-ffi): expose addresses_derived on Wallet event callbacks` — confirmed unused in this repo (platform consumes addresses_derived through key-wallet-manager WalletEvent in changeset/core_bridge.rs, not via dash-spv-ffi callbacks). Can be re-PR'd upstream when an FFI consumer needs it. - `review(key-wallet-manager): per-record derivations, observability, real dedup test` and `drop redundant derivation_path from DerivedAddress` — refinements that didn't make it into v0.42-dev's #725 merge; can be re-PR'd as follow-ups. Verification: - cargo check --workspace --all-targets: clean - cargo check -p platform-wallet --features keep-finalized-transactions: clean - cargo clippy --workspace --all-targets: clean (3 pre-existing warnings unrelated to this change) - cargo test -p platform-wallet --lib: 115/115 pass - iOS xcframework build (sim, dev profile): in progress at commit time Co-Authored-By: Claude Opus 4.7 (1M context) --- Cargo.lock | 126 ++--- Cargo.toml | 18 +- packages/rs-platform-wallet/Cargo.toml | 12 + .../src/changeset/core_bridge.rs | 10 +- .../src/manager/accessors.rs | 38 +- .../src/wallet/asset_lock/build.rs | 1 + .../src/wallet/asset_lock/sync/proof.rs | 9 +- .../src/wallet/asset_lock/sync/recovery.rs | 3 +- .../src/wallet/core/broadcast.rs | 11 +- .../src/wallet/identity/network/contacts.rs | 11 +- .../src/wallet/identity/network/payments.rs | 11 +- .../SwiftDashSDK/KeyWallet/KeyWallet.swift | 5 - .../KeyWallet/ManagedWallet.swift | 430 ------------------ 13 files changed, 104 insertions(+), 581 deletions(-) delete mode 100644 packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedWallet.swift diff --git a/Cargo.lock b/Cargo.lock index f5703840374..006f3ca1cfa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -120,7 +120,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -131,7 +131,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1138,7 +1138,7 @@ version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -1568,7 +1568,7 @@ dependencies = [ [[package]] name = "dash-network" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=fe2476611fcf72d6f36f1154a39a2f9af3b6a248#fe2476611fcf72d6f36f1154a39a2f9af3b6a248" +source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" dependencies = [ "bincode", "bincode_derive", @@ -1579,7 +1579,7 @@ dependencies = [ [[package]] name = "dash-network-seeds" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=fe2476611fcf72d6f36f1154a39a2f9af3b6a248#fe2476611fcf72d6f36f1154a39a2f9af3b6a248" +source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" dependencies = [ "dash-network", ] @@ -1656,7 +1656,7 @@ dependencies = [ [[package]] name = "dash-spv" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=fe2476611fcf72d6f36f1154a39a2f9af3b6a248#fe2476611fcf72d6f36f1154a39a2f9af3b6a248" +source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" dependencies = [ "async-trait", "chrono", @@ -1684,7 +1684,7 @@ dependencies = [ [[package]] name = "dash-spv-ffi" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=fe2476611fcf72d6f36f1154a39a2f9af3b6a248#fe2476611fcf72d6f36f1154a39a2f9af3b6a248" +source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" dependencies = [ "cbindgen 0.29.2", "clap", @@ -1703,7 +1703,7 @@ dependencies = [ [[package]] name = "dashcore" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=fe2476611fcf72d6f36f1154a39a2f9af3b6a248#fe2476611fcf72d6f36f1154a39a2f9af3b6a248" +source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" dependencies = [ "anyhow", "base64-compat", @@ -1729,12 +1729,12 @@ dependencies = [ [[package]] name = "dashcore-private" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=fe2476611fcf72d6f36f1154a39a2f9af3b6a248#fe2476611fcf72d6f36f1154a39a2f9af3b6a248" +source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" [[package]] name = "dashcore-rpc" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=fe2476611fcf72d6f36f1154a39a2f9af3b6a248#fe2476611fcf72d6f36f1154a39a2f9af3b6a248" +source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" dependencies = [ "dashcore-rpc-json", "hex", @@ -1747,7 +1747,7 @@ dependencies = [ [[package]] name = "dashcore-rpc-json" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=fe2476611fcf72d6f36f1154a39a2f9af3b6a248#fe2476611fcf72d6f36f1154a39a2f9af3b6a248" +source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" dependencies = [ "bincode", "dashcore", @@ -1762,7 +1762,7 @@ dependencies = [ [[package]] name = "dashcore_hashes" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=fe2476611fcf72d6f36f1154a39a2f9af3b6a248#fe2476611fcf72d6f36f1154a39a2f9af3b6a248" +source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" dependencies = [ "bincode", "dashcore-private", @@ -2297,7 +2297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3585,7 +3585,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3811,7 +3811,7 @@ dependencies = [ [[package]] name = "key-wallet" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=fe2476611fcf72d6f36f1154a39a2f9af3b6a248#fe2476611fcf72d6f36f1154a39a2f9af3b6a248" +source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" dependencies = [ "aes", "async-trait", @@ -3839,7 +3839,7 @@ dependencies = [ [[package]] name = "key-wallet-ffi" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=fe2476611fcf72d6f36f1154a39a2f9af3b6a248#fe2476611fcf72d6f36f1154a39a2f9af3b6a248" +source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" dependencies = [ "cbindgen 0.29.2", "dash-network", @@ -3855,7 +3855,7 @@ dependencies = [ [[package]] name = "key-wallet-manager" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=fe2476611fcf72d6f36f1154a39a2f9af3b6a248#fe2476611fcf72d6f36f1154a39a2f9af3b6a248" +source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" dependencies = [ "async-trait", "bincode", @@ -4331,7 +4331,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -5338,7 +5338,7 @@ dependencies = [ "once_cell", "socket2 0.5.10", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.52.0", ] [[package]] @@ -6052,7 +6052,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -6065,7 +6065,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -6124,7 +6124,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -6714,7 +6714,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -6947,7 +6947,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -8351,7 +8351,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -8457,15 +8457,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - [[package]] name = "windows-sys" version = "0.61.2" @@ -8499,30 +8490,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", + "windows_i686_gnullvm", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -8535,12 +8509,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -8553,12 +8521,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -8571,24 +8533,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -8601,12 +8551,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -8619,12 +8563,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -8637,12 +8575,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -8655,12 +8587,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "winnow" version = "0.5.40" diff --git a/Cargo.toml b/Cargo.toml index b645caa087b..75d027b48bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,15 +49,15 @@ members = [ ] [workspace.dependencies] -dashcore = { git = "https://github.com/dashpay/rust-dashcore", rev = "fe2476611fcf72d6f36f1154a39a2f9af3b6a248" } -dash-network-seeds = { git = "https://github.com/dashpay/rust-dashcore", rev = "fe2476611fcf72d6f36f1154a39a2f9af3b6a248" } -dash-spv = { git = "https://github.com/dashpay/rust-dashcore", rev = "fe2476611fcf72d6f36f1154a39a2f9af3b6a248" } -dash-spv-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "fe2476611fcf72d6f36f1154a39a2f9af3b6a248" } -key-wallet = { git = "https://github.com/dashpay/rust-dashcore", rev = "fe2476611fcf72d6f36f1154a39a2f9af3b6a248" } -key-wallet-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "fe2476611fcf72d6f36f1154a39a2f9af3b6a248" } -key-wallet-manager = { git = "https://github.com/dashpay/rust-dashcore", rev = "fe2476611fcf72d6f36f1154a39a2f9af3b6a248" } -dash-network = { git = "https://github.com/dashpay/rust-dashcore", rev = "fe2476611fcf72d6f36f1154a39a2f9af3b6a248" } -dashcore-rpc = { git = "https://github.com/dashpay/rust-dashcore", rev = "fe2476611fcf72d6f36f1154a39a2f9af3b6a248" } +dashcore = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } +dash-network-seeds = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } +dash-spv = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } +dash-spv-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } +key-wallet = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } +key-wallet-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } +key-wallet-manager = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } +dash-network = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } +dashcore-rpc = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } # Optimize heavy crypto crates even in dev/test builds so that # Halo 2 proof generation and verification run at near-release speed. diff --git a/packages/rs-platform-wallet/Cargo.toml b/packages/rs-platform-wallet/Cargo.toml index 13d0ccb00af..05e5eb0547c 100644 --- a/packages/rs-platform-wallet/Cargo.toml +++ b/packages/rs-platform-wallet/Cargo.toml @@ -65,3 +65,15 @@ default = ["bls", "eddsa"] bls = ["key-wallet/bls", "key-wallet-manager/bls"] eddsa = ["key-wallet/eddsa", "key-wallet-manager/eddsa"] shielded = ["dep:grovedb-commitment-tree", "dep:zip32", "dash-sdk/shielded", "dpp/shielded-client"] +# Forward to the upstream `key-wallet` / `key-wallet-manager` +# `keep-finalized-transactions` feature. With it OFF (the default), +# chainlocked transactions are evicted from the in-memory +# `transactions` map and only their txids are kept (in +# `finalized_txids`) for dedup; tx history is delivered through the +# event channel. Turn ON to keep the full `TransactionRecord` for +# finalized transactions in memory for the wallet's lifetime — useful +# for debug surfaces that page through history. +keep-finalized-transactions = [ + "key-wallet/keep-finalized-transactions", + "key-wallet-manager/keep-finalized-transactions", +] diff --git a/packages/rs-platform-wallet/src/changeset/core_bridge.rs b/packages/rs-platform-wallet/src/changeset/core_bridge.rs index 53aeb80dcc6..b2d9761ac2b 100644 --- a/packages/rs-platform-wallet/src/changeset/core_bridge.rs +++ b/packages/rs-platform-wallet/src/changeset/core_bridge.rs @@ -211,12 +211,12 @@ async fn is_chain_locked( }; // Walk every account; if any holds an in-memory record for this // txid, the chain-lock determination falls out of its - // `TransactionContext`. With `keep_txs_in_memory` off (the default) - // `get_transaction` returns `None` regardless of state — chain-lock - // delivery is event-driven in that mode, and this helper just - // reports "no record locally" by returning false. + // `TransactionContext`. With `keep-finalized-transactions` off + // (the default) `transactions()` returns an empty map regardless + // of state — chain-lock delivery is event-driven in that mode, and + // this helper just reports "no record locally" by returning false. for account in info.core_wallet.accounts.all_accounts() { - if let Some(record) = account.get_transaction(txid) { + if let Some(record) = account.transactions().get(txid) { return matches!(record.context, TransactionContext::InChainLockedBlock(_)); } } diff --git a/packages/rs-platform-wallet/src/manager/accessors.rs b/packages/rs-platform-wallet/src/manager/accessors.rs index 8b4d4810ff5..172667098af 100644 --- a/packages/rs-platform-wallet/src/manager/accessors.rs +++ b/packages/rs-platform-wallet/src/manager/accessors.rs @@ -547,17 +547,18 @@ impl PlatformWalletManager

{ .iter() .find(|a| &a.managed_account_type().to_account_type() == target)?; // Funds-only fields (`utxos`) live on the funds variant; the - // ref-enum delegates the rest. `transactions_iter()` returns an - // empty iterator when `keep_txs_in_memory` is off (the default - // — tx history is event-driven), so `total_transactions` reads - // 0 in production builds. Both behaviors are intentional. + // ref-enum delegates the rest. `transactions()` returns an + // empty map when `keep-finalized-transactions` is off (the + // default — tx history is event-driven), so + // `total_transactions` reads 0 in production builds. Both + // behaviors are intentional. let funds = account.as_funds(); Some(AccountMetadataSnapshot { - // `transactions_iter()` returns empty when - // `keep_txs_in_memory` is off (the default — tx history is - // event-driven), so `total_transactions` reads 0 in - // production builds. - total_transactions: account.transactions_iter().count() as u64, + // `transactions()` is empty when + // `keep-finalized-transactions` is off (the default — tx + // history is event-driven), so `total_transactions` reads + // 0 in production builds. + total_transactions: account.transactions().len() as u64, total_utxos: funds.map(|a| a.utxos.len() as u64).unwrap_or(0), monitor_revision: account.monitor_revision(), }) @@ -657,17 +658,14 @@ impl PlatformWalletManager

{ else { return Vec::new(); }; - // `transactions_iter` is the variant-agnostic walk and returns - // an empty iterator when `keep_txs_in_memory` is disabled — the - // default. Tx history is delivered through the event channel, - // not stored in-memory, so a paged readout here is effectively - // a debug surface for builds that flip the feature on. We - // collapse `(Txid, &TransactionRecord)` to just records, since - // the snapshot type carries the txid as a field of its own. - let iter = account - .transactions_iter() - .map(|(_, record)| record) - .skip(page_offset); + // `transactions()` returns an empty map when + // `keep-finalized-transactions` is disabled — the default. Tx + // history is delivered through the event channel, not stored + // in-memory, so a paged readout here is effectively a debug + // surface for builds that flip the feature on. The snapshot + // type carries the txid as a field of its own, so we walk + // values only. + let iter = account.transactions().values().skip(page_offset); let take = if page_limit == 0 { usize::MAX } else { diff --git a/packages/rs-platform-wallet/src/wallet/asset_lock/build.rs b/packages/rs-platform-wallet/src/wallet/asset_lock/build.rs index 1fadb3fb290..e8ad52ffe23 100644 --- a/packages/rs-platform-wallet/src/wallet/asset_lock/build.rs +++ b/packages/rs-platform-wallet/src/wallet/asset_lock/build.rs @@ -8,6 +8,7 @@ use std::time::Duration; use dashcore::Address as DashAddress; use dashcore::{OutPoint, PrivateKey, Transaction, TxOut}; +use key_wallet::managed_account::managed_account_trait::ManagedAccountTrait; use key_wallet::wallet::managed_wallet_info::asset_lock_builder::{ AssetLockFundingType, CreditOutputFunding, }; diff --git a/packages/rs-platform-wallet/src/wallet/asset_lock/sync/proof.rs b/packages/rs-platform-wallet/src/wallet/asset_lock/sync/proof.rs index 7d937438a17..36f69719b2d 100644 --- a/packages/rs-platform-wallet/src/wallet/asset_lock/sync/proof.rs +++ b/packages/rs-platform-wallet/src/wallet/asset_lock/sync/proof.rs @@ -4,6 +4,7 @@ use crate::broadcaster::TransactionBroadcaster; use std::time::Duration; use dashcore::OutPoint; +use key_wallet::managed_account::managed_account_trait::ManagedAccountTrait; use crate::error::PlatformWalletError; @@ -45,7 +46,7 @@ impl AssetLockManager { .accounts .standard_bip44_accounts .get(&account_index) - .and_then(|a| a.transactions.get(&out_point.txid)) + .and_then(|a| a.transactions().get(&out_point.txid)) .ok_or_else(|| { PlatformWalletError::AssetLockProofWait(format!( "Transaction {} not found in account {}", @@ -139,7 +140,7 @@ impl AssetLockManager { .accounts .standard_bip44_accounts .get(&account_index) - .and_then(|a| a.transactions.get(&txid)) + .and_then(|a| a.transactions().get(&txid)) .ok_or_else(|| { PlatformWalletError::AssetLockProofWait(format!( "Transaction {} not found in account {}", @@ -223,7 +224,7 @@ impl AssetLockManager { .accounts .standard_bip44_accounts .get(&account_index) - .and_then(|a| a.transactions.get(&out_point.txid)) + .and_then(|a| a.transactions().get(&out_point.txid)) { if matches!(record.context, TransactionContext::InChainLockedBlock(_)) { if let Some(h) = record.height() { @@ -294,7 +295,7 @@ impl AssetLockManager { .accounts .standard_bip44_accounts .get(&account_index) - .and_then(|a| a.transactions.get(&out_point.txid)) + .and_then(|a| a.transactions().get(&out_point.txid)) { match &record.context { TransactionContext::InstantSend(instant_lock) => { diff --git a/packages/rs-platform-wallet/src/wallet/asset_lock/sync/recovery.rs b/packages/rs-platform-wallet/src/wallet/asset_lock/sync/recovery.rs index 7cb5f7e450f..f7052041bea 100644 --- a/packages/rs-platform-wallet/src/wallet/asset_lock/sync/recovery.rs +++ b/packages/rs-platform-wallet/src/wallet/asset_lock/sync/recovery.rs @@ -9,6 +9,7 @@ use std::time::Duration; use dashcore::Address as DashAddress; use dashcore::{OutPoint, PrivateKey}; +use key_wallet::managed_account::managed_account_trait::ManagedAccountTrait; use key_wallet::wallet::managed_wallet_info::asset_lock_builder::AssetLockFundingType; use key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; @@ -105,7 +106,7 @@ impl AssetLockManager { .accounts .standard_bip44_accounts .get(&account_index) - .and_then(|a| a.transactions.get(&out_point.txid)); + .and_then(|a| a.transactions().get(&out_point.txid)); match record { Some(record) => match &record.context { diff --git a/packages/rs-platform-wallet/src/wallet/core/broadcast.rs b/packages/rs-platform-wallet/src/wallet/core/broadcast.rs index 10578a7a682..4484ff5748b 100644 --- a/packages/rs-platform-wallet/src/wallet/core/broadcast.rs +++ b/packages/rs-platform-wallet/src/wallet/core/broadcast.rs @@ -1,5 +1,6 @@ use dashcore::{Address as DashAddress, Transaction}; use key_wallet::account::account_type::StandardAccountType; +use key_wallet::managed_account::managed_account_trait::ManagedAccountTrait; use crate::broadcaster::TransactionBroadcaster; use crate::{CoreWallet, PlatformWalletError}; @@ -116,7 +117,15 @@ impl CoreWallet { current_height, |utxo| { for account in info.core_wallet.accounts.all_accounts() { - if let Some(path) = account.address_derivation_path(&utxo.address) { + // Address pools live on the keys variant + // after the funds/keys split; the funds + // account composes a keys account, and + // `keys_account()` exposes it for both + // `ManagedAccountRef` variants. + if let Some(path) = account + .keys_account() + .address_derivation_path(&utxo.address) + { if let Ok(key) = wallet.derive_private_key(&path) { return Some(key); } diff --git a/packages/rs-platform-wallet/src/wallet/identity/network/contacts.rs b/packages/rs-platform-wallet/src/wallet/identity/network/contacts.rs index 1ac523757e9..8a3479043bf 100644 --- a/packages/rs-platform-wallet/src/wallet/identity/network/contacts.rs +++ b/packages/rs-platform-wallet/src/wallet/identity/network/contacts.rs @@ -5,6 +5,7 @@ use dpp::identity::identity_public_key::accessors::v0::IdentityPublicKeyGettersV use dpp::identity::Identity; use dpp::prelude::Identifier; use key_wallet::account::AccountType; +use key_wallet::managed_account::managed_account_trait::ManagedAccountTrait; use super::*; use crate::broadcaster::TransactionBroadcaster; @@ -139,12 +140,12 @@ impl IdentityWallet { .get_wallet_info_mut(&self.wallet_id) .ok_or_else(|| PlatformWalletError::WalletNotFound(hex::encode(self.wallet_id)))?; // DashPay accounts are funds-bearing; use the typed - // `insert_funds` API exposed by the post-split collection - // rather than wrapping in `OwnedManagedCoreAccount`. + // `insert_funds_bearing_account` API exposed by the post-split + // collection rather than wrapping in `OwnedManagedCoreAccount`. let managed = key_wallet::managed_account::ManagedCoreFundsAccount::from_account(&account); info.core_wallet .accounts - .insert_funds(managed) + .insert_funds_bearing_account(managed) .map_err(|e| { PlatformWalletError::InvalidIdentityData(format!( "Failed to register contact account: {e}" @@ -231,7 +232,7 @@ impl IdentityWallet { user_identity_id, friend_identity_id, .. - } = &account.managed_account_type + } = account.managed_account_type() else { // Routing invariant: dashpay_receival_accounts must // only contain DashpayReceivingFunds. If this ever @@ -497,7 +498,7 @@ impl IdentityWallet { // (b) Insert ManagedCoreFundsAccount for address-pool tracking. info.core_wallet .accounts - .insert_funds(managed) + .insert_funds_bearing_account(managed) .map_err(|e| { PlatformWalletError::InvalidIdentityData(format!( "Failed to register external contact account: {}", diff --git a/packages/rs-platform-wallet/src/wallet/identity/network/payments.rs b/packages/rs-platform-wallet/src/wallet/identity/network/payments.rs index 5186cd5fc61..3a44ae1e805 100644 --- a/packages/rs-platform-wallet/src/wallet/identity/network/payments.rs +++ b/packages/rs-platform-wallet/src/wallet/identity/network/payments.rs @@ -1,6 +1,7 @@ //! DashPay payment recording and send-to-contact flows. use dpp::prelude::Identifier; +use key_wallet::managed_account::managed_account_trait::ManagedAccountTrait; use super::*; use crate::broadcaster::TransactionBroadcaster; @@ -223,7 +224,15 @@ impl IdentityWallet { current_height, |utxo| { for account in info.core_wallet.accounts.all_accounts() { - if let Some(path) = account.address_derivation_path(&utxo.address) { + // Address pools live on the keys variant + // after the funds/keys split; the funds + // account composes a keys account, and + // `keys_account()` exposes it for both + // `ManagedAccountRef` variants. + if let Some(path) = account + .keys_account() + .address_derivation_path(&utxo.address) + { if let Ok(key) = wallet.derive_private_key(&path) { return Some(key); } diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/KeyWallet.swift b/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/KeyWallet.swift index 4b459cc9d7b..47541039840 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/KeyWallet.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/KeyWallet.swift @@ -22,10 +22,6 @@ import Foundation /// let mnemonic = try Mnemonic.generate() /// let wallet = try Wallet(mnemonic: mnemonic, network: .testnet) /// -/// // Get a receive address -/// let managed = try ManagedWallet(wallet: wallet) -/// let address = try managed.getNextReceiveAddress(wallet: wallet) -/// /// // Check wallet balance /// let balance = try wallet.getBalance() /// print("Confirmed: \(balance.confirmed), Unconfirmed: \(balance.unconfirmed)") @@ -49,7 +45,6 @@ public class KeyWallet { // Re-export all public types for convenience public typealias KeyWalletWallet = Wallet public typealias KeyWalletAccount = Account -public typealias KeyWalletManagedWallet = ManagedWallet public typealias KeyWalletManager = WalletManager public typealias KeyWalletMnemonic = Mnemonic public typealias KeyWalletTransaction = Transaction diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedWallet.swift b/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedWallet.swift deleted file mode 100644 index 4bb6175c2f1..00000000000 --- a/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedWallet.swift +++ /dev/null @@ -1,430 +0,0 @@ -import Foundation -import DashSDKFFI - -/// Swift wrapper for managed wallet with address pool management and transaction checking -public class ManagedWallet { - private let handle: UnsafeMutablePointer - - /// Create a managed wallet wrapper from a regular wallet - /// - Parameter wallet: The wallet to manage - public init(wallet: Wallet) throws { - var error = FFIError() - guard let managedPointer = wallet_create_managed_wallet(wallet.ffiHandle, &error) else { - defer { - if error.message != nil { - error_message_free(error.message) - } - } - throw KeyWalletError(ffiError: error) - } - - self.handle = managedPointer - } - - deinit { - ffi_managed_wallet_free(handle) - } - - // MARK: - Address Generation - - /// Get the next unused receive address for a BIP44 account - /// - Parameters: - /// - wallet: The wallet for key derivation - /// - accountIndex: The account index - /// - Returns: The next receive address - public func getNextReceiveAddress(wallet: Wallet, accountIndex: UInt32 = 0) throws -> String { - var error = FFIError() - - guard let infoHandle = getInfoHandle() else { - throw KeyWalletError.invalidState("Failed to get managed wallet info") - } - - let addressPtr = managed_wallet_get_next_bip44_receive_address( - infoHandle, wallet.ffiHandle, accountIndex, &error) - - defer { - if error.message != nil { - error_message_free(error.message) - } - } - - guard let ptr = addressPtr else { - throw KeyWalletError(ffiError: error) - } - - let address = String(cString: ptr) - address_free(ptr) - - return address - } - - /// Get the next unused change address for a BIP44 account - /// - Parameters: - /// - wallet: The wallet for key derivation - /// - accountIndex: The account index - /// - Returns: The next change address - public func getNextChangeAddress(wallet: Wallet, accountIndex: UInt32 = 0) throws -> String { - var error = FFIError() - - guard let infoHandle = getInfoHandle() else { - throw KeyWalletError.invalidState("Failed to get managed wallet info") - } - - let addressPtr = managed_wallet_get_next_bip44_change_address( - infoHandle, wallet.ffiHandle, accountIndex, &error) - - defer { - if error.message != nil { - error_message_free(error.message) - } - } - - guard let ptr = addressPtr else { - throw KeyWalletError(ffiError: error) - } - - let address = String(cString: ptr) - address_free(ptr) - - return address - } - - /// Get a range of external (receive) addresses - /// - Parameters: - /// - wallet: The wallet for key derivation - /// - accountIndex: The account index - /// - startIndex: Starting index (inclusive) - /// - endIndex: Ending index (exclusive) - /// - Returns: Array of addresses - public func getExternalAddressRange(wallet: Wallet, accountIndex: UInt32 = 0, - startIndex: UInt32, endIndex: UInt32) throws -> [String] { - guard endIndex > startIndex else { - throw KeyWalletError.invalidInput("End index must be greater than start index") - } - - var error = FFIError() - var addressesPtr: UnsafeMutablePointer?>? - var count: size_t = 0 - - guard let infoHandle = getInfoHandle() else { - throw KeyWalletError.invalidState("Failed to get managed wallet info") - } - - let success = managed_wallet_get_bip_44_external_address_range( - infoHandle, wallet.ffiHandle, accountIndex, - startIndex, endIndex, &addressesPtr, &count, &error) - - defer { - if error.message != nil { - error_message_free(error.message) - } - if let ptr = addressesPtr { - address_array_free(ptr, count) - } - } - - guard success, let ptr = addressesPtr else { - throw KeyWalletError(ffiError: error) - } - - var addresses: [String] = [] - for i in 0.. [String] { - guard endIndex > startIndex else { - throw KeyWalletError.invalidInput("End index must be greater than start index") - } - - var error = FFIError() - var addressesPtr: UnsafeMutablePointer?>? - var count: size_t = 0 - - guard let infoHandle = getInfoHandle() else { - throw KeyWalletError.invalidState("Failed to get managed wallet info") - } - - let success = managed_wallet_get_bip_44_internal_address_range( - infoHandle, wallet.ffiHandle, accountIndex, - startIndex, endIndex, &addressesPtr, &count, &error) - - defer { - if error.message != nil { - error_message_free(error.message) - } - if let ptr = addressesPtr { - address_array_free(ptr, count) - } - } - - guard success, let ptr = addressesPtr else { - throw KeyWalletError(ffiError: error) - } - - var addresses: [String] = [] - for i in 0.. AddressPoolInfo { - var error = FFIError() - var ffiInfo = FFIAddressPoolInfo() - - let success = managed_wallet_get_address_pool_info( - handle, accountType.ffiValue, accountIndex, - poolType.ffiValue, &ffiInfo, &error) - - defer { - if error.message != nil { - error_message_free(error.message) - } - } - - guard success else { - throw KeyWalletError(ffiError: error) - } - - return AddressPoolInfo(ffiInfo: ffiInfo) - } - - /// Set the gap limit for an address pool - /// - Parameters: - /// - accountType: The account type - /// - accountIndex: The account index - /// - poolType: The address pool type - /// - gapLimit: The new gap limit - public func setGapLimit(accountType: AccountType, accountIndex: UInt32 = 0, - poolType: AddressPoolType, gapLimit: UInt32) throws { - var error = FFIError() - - let success = managed_wallet_set_gap_limit( - handle, accountType.ffiValue, accountIndex, - poolType.ffiValue, gapLimit, &error) - - defer { - if error.message != nil { - error_message_free(error.message) - } - } - - guard success else { - throw KeyWalletError(ffiError: error) - } - } - - /// Generate addresses up to a specific index - /// - Parameters: - /// - wallet: The wallet for key derivation - /// - accountType: The account type - /// - accountIndex: The account index - /// - poolType: The address pool type - /// - targetIndex: The target index to generate up to - public func generateAddressesToIndex(wallet: Wallet, accountType: AccountType, - accountIndex: UInt32 = 0, - poolType: AddressPoolType, - targetIndex: UInt32) throws { - var error = FFIError() - - let success = managed_wallet_generate_addresses_to_index( - handle, wallet.ffiHandle, accountType.ffiValue, - accountIndex, poolType.ffiValue, targetIndex, &error) - - defer { - if error.message != nil { - error_message_free(error.message) - } - } - - guard success else { - throw KeyWalletError(ffiError: error) - } - } - - /// Mark an address as used - /// - Parameter address: The address to mark as used - public func markAddressUsed(_ address: String) throws { - var error = FFIError() - - let success = address.withCString { addressCStr in - managed_wallet_mark_address_used(handle, addressCStr, &error) - } - - defer { - if error.message != nil { - error_message_free(error.message) - } - } - - guard success else { - throw KeyWalletError(ffiError: error) - } - } - - // MARK: - Transaction Checking - - /// Check if a transaction belongs to the wallet - /// - Parameters: - /// - wallet: The wallet to check against - /// - transactionData: The transaction bytes - /// - context: The transaction context - /// - blockHeight: The block height (0 for mempool) - /// - blockHash: The block hash (nil for mempool) - /// - timestamp: The timestamp - /// - updateState: Whether to update wallet state if transaction is relevant - /// - Returns: Transaction check result - public func checkTransaction(wallet: Wallet, transactionData: Data, - context: TransactionContextType = .mempool, - blockHeight: UInt32 = 0, - blockHash: Data? = nil, - timestamp: UInt32 = 0, - updateState: Bool = true) throws -> TransactionCheckResult { - var error = FFIError() - var result = FFITransactionCheckResult() - - // Build FFIBlockInfo - var blockInfo = FFIBlockInfo() - blockInfo.height = blockHeight - blockInfo.timestamp = timestamp - if let hash = blockHash, hash.count == 32 { - hash.withUnsafeBytes { buf in - withUnsafeMutableBytes(of: &blockInfo.block_hash) { dst in - dst.copyBytes(from: buf.prefix(32)) - } - } - } - - let contextType = FFITransactionContextType(rawValue: context.rawValue) - - let success = transactionData.withUnsafeBytes { txBytes in - let txPtr = txBytes.bindMemory(to: UInt8.self).baseAddress - - return managed_wallet_check_transaction( - handle, wallet.ffiHandle, - txPtr, transactionData.count, - contextType, blockInfo, - nil, 0, // islock_data, islock_len - updateState, &result, &error) - } - - defer { - if error.message != nil { - error_message_free(error.message) - } - transaction_check_result_free(&result) - } - - guard success else { - throw KeyWalletError(ffiError: error) - } - - return TransactionCheckResult(ffiResult: result) - } - - // MARK: - Balance and UTXOs - - /// Get the wallet balance from managed wallet info - public func getBalance() throws -> Balance { - guard let infoHandle = getInfoHandle() else { - throw KeyWalletError.invalidState("Failed to get managed wallet info") - } - - var error = FFIError() - var confirmed: UInt64 = 0 - var unconfirmed: UInt64 = 0 - var immature: UInt64 = 0 - var locked: UInt64 = 0 - var total: UInt64 = 0 - - let success = managed_wallet_get_balance( - infoHandle, &confirmed, &unconfirmed, &immature, &locked, &total, &error) - - defer { - if error.message != nil { - error_message_free(error.message) - } - } - - guard success else { - throw KeyWalletError(ffiError: error) - } - - let ffiBalance = FFIBalance( - confirmed: confirmed, - unconfirmed: unconfirmed, - immature: immature, - locked: locked, - total: total - ) - - return Balance(ffiBalance: ffiBalance) - } - - /// Get all UTXOs from the managed wallet - public func getUTXOs() throws -> [UTXO] { - guard let infoHandle = getInfoHandle() else { - throw KeyWalletError.invalidState("Failed to get managed wallet info") - } - - var error = FFIError() - var utxosPtr: UnsafeMutablePointer? - var count: size_t = 0 - - let success = managed_wallet_get_utxos( - infoHandle, &utxosPtr, &count, &error) - - defer { - if error.message != nil { - error_message_free(error.message) - } - if let ptr = utxosPtr { - utxo_array_free(ptr, count) - } - } - - guard success, let ptr = utxosPtr else { - throw KeyWalletError(ffiError: error) - } - - var utxos: [UTXO] = [] - for i in 0.. UnsafeMutablePointer? { - // The handle is an FFIManagedWalletInfo* (opaque C handle) - return handle - } -} From d4aff16c204a166b2befae59754db7aba96dc8d2 Mon Sep 17 00:00:00 2001 From: Quantum Explorer Date: Thu, 7 May 2026 23:02:19 +0700 Subject: [PATCH 2/2] chore: bump rust-dashcore one commit forward to d6dd5da MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Picks up dashpay/rust-dashcore#735 (`feat(key-wallet): build_and_sign_transaction_with_signer`) — purely additive on the key-wallet API; no platform-side adaptation required. iOS-side cleanup that surfaced under the bumped key-wallet-ffi: * Remove `transactionCount` and `getTransactions()` from Swift `ManagedAccount`. The corresponding C symbols (`managed_core_account_get_transaction_count` / `managed_core_account_get_transactions`) are gated upstream behind `#[cfg(feature = "keep-finalized-transactions")]` (off by default — production model delivers tx history through the platform-wallet event channel). With the feature off the static archive doesn't export those symbols, so the SwiftDashSDK link step fails. No Swift callers in this repo, so the right move per the swift-sdk CLAUDE.md ownership rules is to drop the dead bridges rather than force the feature on (which would change the production-build memory model). Verification: - cargo check --workspace --all-targets: clean - packages/swift-sdk/build_ios.sh --target sim --profile dev: BUILD SUCCEEDED (Rust + Swift, including SwiftExampleApp link) Co-Authored-By: Claude Opus 4.7 (1M context) --- Cargo.lock | 44 +++++------ Cargo.toml | 18 ++--- .../KeyWallet/ManagedAccount.swift | 73 +++---------------- 3 files changed, 40 insertions(+), 95 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 006f3ca1cfa..d5813be584a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1138,7 +1138,7 @@ version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "faf9468729b8cbcea668e36183cb69d317348c2e08e994829fb56ebfdfbaac34" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1568,7 +1568,7 @@ dependencies = [ [[package]] name = "dash-network" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" +source = "git+https://github.com/dashpay/rust-dashcore?rev=d6dd5da14902dca4332036c5ef4db03734934eb3#d6dd5da14902dca4332036c5ef4db03734934eb3" dependencies = [ "bincode", "bincode_derive", @@ -1579,7 +1579,7 @@ dependencies = [ [[package]] name = "dash-network-seeds" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" +source = "git+https://github.com/dashpay/rust-dashcore?rev=d6dd5da14902dca4332036c5ef4db03734934eb3#d6dd5da14902dca4332036c5ef4db03734934eb3" dependencies = [ "dash-network", ] @@ -1656,7 +1656,7 @@ dependencies = [ [[package]] name = "dash-spv" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" +source = "git+https://github.com/dashpay/rust-dashcore?rev=d6dd5da14902dca4332036c5ef4db03734934eb3#d6dd5da14902dca4332036c5ef4db03734934eb3" dependencies = [ "async-trait", "chrono", @@ -1684,7 +1684,7 @@ dependencies = [ [[package]] name = "dash-spv-ffi" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" +source = "git+https://github.com/dashpay/rust-dashcore?rev=d6dd5da14902dca4332036c5ef4db03734934eb3#d6dd5da14902dca4332036c5ef4db03734934eb3" dependencies = [ "cbindgen 0.29.2", "clap", @@ -1703,7 +1703,7 @@ dependencies = [ [[package]] name = "dashcore" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" +source = "git+https://github.com/dashpay/rust-dashcore?rev=d6dd5da14902dca4332036c5ef4db03734934eb3#d6dd5da14902dca4332036c5ef4db03734934eb3" dependencies = [ "anyhow", "base64-compat", @@ -1729,12 +1729,12 @@ dependencies = [ [[package]] name = "dashcore-private" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" +source = "git+https://github.com/dashpay/rust-dashcore?rev=d6dd5da14902dca4332036c5ef4db03734934eb3#d6dd5da14902dca4332036c5ef4db03734934eb3" [[package]] name = "dashcore-rpc" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" +source = "git+https://github.com/dashpay/rust-dashcore?rev=d6dd5da14902dca4332036c5ef4db03734934eb3#d6dd5da14902dca4332036c5ef4db03734934eb3" dependencies = [ "dashcore-rpc-json", "hex", @@ -1747,7 +1747,7 @@ dependencies = [ [[package]] name = "dashcore-rpc-json" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" +source = "git+https://github.com/dashpay/rust-dashcore?rev=d6dd5da14902dca4332036c5ef4db03734934eb3#d6dd5da14902dca4332036c5ef4db03734934eb3" dependencies = [ "bincode", "dashcore", @@ -1762,7 +1762,7 @@ dependencies = [ [[package]] name = "dashcore_hashes" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" +source = "git+https://github.com/dashpay/rust-dashcore?rev=d6dd5da14902dca4332036c5ef4db03734934eb3#d6dd5da14902dca4332036c5ef4db03734934eb3" dependencies = [ "bincode", "dashcore-private", @@ -2297,7 +2297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3585,7 +3585,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3811,7 +3811,7 @@ dependencies = [ [[package]] name = "key-wallet" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" +source = "git+https://github.com/dashpay/rust-dashcore?rev=d6dd5da14902dca4332036c5ef4db03734934eb3#d6dd5da14902dca4332036c5ef4db03734934eb3" dependencies = [ "aes", "async-trait", @@ -3839,7 +3839,7 @@ dependencies = [ [[package]] name = "key-wallet-ffi" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" +source = "git+https://github.com/dashpay/rust-dashcore?rev=d6dd5da14902dca4332036c5ef4db03734934eb3#d6dd5da14902dca4332036c5ef4db03734934eb3" dependencies = [ "cbindgen 0.29.2", "dash-network", @@ -3855,7 +3855,7 @@ dependencies = [ [[package]] name = "key-wallet-manager" version = "0.42.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=428b60d0c93b7842876e568ebb40c2e5455d4277#428b60d0c93b7842876e568ebb40c2e5455d4277" +source = "git+https://github.com/dashpay/rust-dashcore?rev=d6dd5da14902dca4332036c5ef4db03734934eb3#d6dd5da14902dca4332036c5ef4db03734934eb3" dependencies = [ "async-trait", "bincode", @@ -4331,7 +4331,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -5338,7 +5338,7 @@ dependencies = [ "once_cell", "socket2 0.5.10", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6052,7 +6052,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6065,7 +6065,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6124,7 +6124,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6947,7 +6947,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -8351,7 +8351,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 75d027b48bb..d78558b6a63 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,15 +49,15 @@ members = [ ] [workspace.dependencies] -dashcore = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } -dash-network-seeds = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } -dash-spv = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } -dash-spv-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } -key-wallet = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } -key-wallet-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } -key-wallet-manager = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } -dash-network = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } -dashcore-rpc = { git = "https://github.com/dashpay/rust-dashcore", rev = "428b60d0c93b7842876e568ebb40c2e5455d4277" } +dashcore = { git = "https://github.com/dashpay/rust-dashcore", rev = "d6dd5da14902dca4332036c5ef4db03734934eb3" } +dash-network-seeds = { git = "https://github.com/dashpay/rust-dashcore", rev = "d6dd5da14902dca4332036c5ef4db03734934eb3" } +dash-spv = { git = "https://github.com/dashpay/rust-dashcore", rev = "d6dd5da14902dca4332036c5ef4db03734934eb3" } +dash-spv-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "d6dd5da14902dca4332036c5ef4db03734934eb3" } +key-wallet = { git = "https://github.com/dashpay/rust-dashcore", rev = "d6dd5da14902dca4332036c5ef4db03734934eb3" } +key-wallet-ffi = { git = "https://github.com/dashpay/rust-dashcore", rev = "d6dd5da14902dca4332036c5ef4db03734934eb3" } +key-wallet-manager = { git = "https://github.com/dashpay/rust-dashcore", rev = "d6dd5da14902dca4332036c5ef4db03734934eb3" } +dash-network = { git = "https://github.com/dashpay/rust-dashcore", rev = "d6dd5da14902dca4332036c5ef4db03734934eb3" } +dashcore-rpc = { git = "https://github.com/dashpay/rust-dashcore", rev = "d6dd5da14902dca4332036c5ef4db03734934eb3" } # Optimize heavy crypto crates even in dev/test builds so that # Halo 2 proof generation and verification run at near-release speed. diff --git a/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift b/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift index 8b3a3746adb..af2a7dd54db 100644 --- a/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift +++ b/packages/swift-sdk/Sources/SwiftDashSDK/KeyWallet/ManagedAccount.swift @@ -41,75 +41,20 @@ public class ManagedAccount { return managed_core_account_get_index(handle) } - /// Get the transaction count - public var transactionCount: UInt32 { - return managed_core_account_get_transaction_count(handle) - } - /// Get the UTXO count public var utxoCount: UInt32 { return managed_core_account_get_utxo_count(handle) } - // MARK: - Transactions - - /// Get all transactions for this account - /// - Returns: Array of transactions - public func getTransactions() -> [WalletTransaction] { - var ptr: UnsafeMutablePointer? - var count: size_t = 0 - - let success = managed_core_account_get_transactions(handle, &ptr, &count) - - guard success else { - preconditionFailure( - "Invalid state: managed_core_account_get_transactions can only fail if any pointer is nil" - ) - } - - // Handle empty case - guard count > 0, let ptr else { - return [] - } - - defer { - managed_core_account_free_transactions(ptr, count) - } - - // Convert FFI transactions to Swift transactions - var transactions: [WalletTransaction] = [] - transactions.reserveCapacity(count) - - for i in 0.. 0 ? ffiTx.fee : nil, - isOurs: true // direction-based, inferred from net_amount sign - ) - - transactions.append(transaction) - } - - return transactions - } + // `transactionCount` and `getTransactions()` accessors were removed + // in lockstep with upstream gating + // `managed_core_account_get_transaction_count` / + // `managed_core_account_get_transactions` behind the + // `keep-finalized-transactions` Cargo feature (off by default). + // The production model delivers tx history through the + // platform-wallet event channel, not from the in-memory + // per-account map. Consumers that need history should subscribe + // to wallet events on the Rust side. // MARK: - Balance