Skip to content

refactor: Single network WalletManager#299

Merged
xdustinface merged 1 commit intov0.41-devfrom
refactor/wallet-manager
Dec 24, 2025
Merged

refactor: Single network WalletManager#299
xdustinface merged 1 commit intov0.41-devfrom
refactor/wallet-manager

Conversation

@xdustinface
Copy link
Collaborator

@xdustinface xdustinface commented Dec 22, 2025

Refactors the WalletManager to be a single network wallet only. Follow up to finalize the refactoring started in:

Summary by CodeRabbit

Release Notes

  • Refactor
    • Simplified wallet manager API by moving network configuration to initialization time instead of per-method calls.
    • Updated wallet interface methods to remove redundant network parameters, reducing API complexity.
    • Streamlined FFI function signatures for wallet operations by centralizing network context management.
    • Consolidated network state handling in wallet manager for improved performance and reduced parameter passing overhead.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 22, 2025

Walkthrough

The pull request refactors network configuration management across all crates by moving network binding from per-method-call parameters to initialization time. WalletManager constructors now require a Network argument, while trait methods and wallet operations that previously accepted network parameters have them removed. BlockProcessor's network field is eliminated, and FFI APIs are updated to reflect this centralized approach.

Changes

Cohort / File(s) Summary
WalletManager Initialization
key-wallet-manager/src/wallet_manager/mod.rs, key-wallet-ffi/src/wallet_manager.rs
WalletManager::new() signature changed to require Network parameter; network field added to struct; removed per-network state storage; birth height logic consolidated to use self.current_height
WalletInterface Trait
key-wallet-manager/src/wallet_interface.rs, key-wallet-manager/src/wallet_manager/process_block.rs
Removed network parameter from: process_block, process_mempool_transaction, check_compact_filter, transaction_effect, earliest_required_height, describe; removed handle_reorg method entirely; updated implementations to use global wallet collection iterations instead of network-scoped logic
BlockProcessor
dash-spv/src/client/block_processor.rs, dash-spv/src/client/lifecycle.rs
Removed network field from struct; removed network parameter from constructor; updated wallet method calls to omit network argument
FFI Public API
key-wallet-ffi/FFI_API.md, key-wallet-ffi/include/key_wallet_ffi.h
wallet_manager_create now requires FFINetwork parameter; removed network parameter from: wallet_manager_add_wallet_from_mnemonic*, wallet_manager_describe, wallet_manager_process_transaction, wallet_manager_update_height, wallet_manager_current_height
FFI Implementation
key-wallet-ffi/src/address_pool.rs, key-wallet-ffi/src/managed_account.rs
Updated test and internal calls to pass network at wallet_manager_create instead of wallet_manager_add_wallet_from_mnemonic* calls
SPV Client Core
dash-spv/src/sync/filters/matching.rs, dash-spv/src/sync/manager.rs, dash-spv/src/sync/message_handlers.rs
Removed network parameter from check_filter_for_matches, process_block, and related calls; simplified wallet_birth_height_hint to query directly without network mapping
Examples
dash-spv/examples/filter_sync.rs, dash-spv/examples/simple_sync.rs, dash-spv/examples/spv_with_wallet.rs, key-wallet-manager/examples/wallet_creation.rs
Updated WalletManager instantiation to pass config.network; adapted method calls to new signatures without network parameters
Integration & Unit Tests
dash-spv/src/client/block_processor_test.rs, dash-spv-ffi/tests/test_wallet_manager.rs, dash-spv/tests/*_test.rs, key-wallet-ffi/tests/*, key-wallet-manager/tests/*
Updated all test setup code to pass network at WalletManager creation; removed network arguments from wallet method invocations; updated mock implementations to match new trait signatures

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

The changes span multiple crates with heterogeneous modifications to trait definitions, struct layouts, and method signatures. While individual changes follow a consistent pattern (moving network to initialization), the breadth of affected call sites, integration across FFI boundaries, and the need to verify state management changes (particularly around height and network scoping) require substantial review effort.

Possibly related PRs

Suggested reviewers

  • QuantumExplorer

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: refactoring WalletManager to support a single network, which aligns with the comprehensive modifications across all related files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/wallet-manager

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@xdustinface xdustinface force-pushed the refactor/wallet-manager branch from 1232c3b to 61198ae Compare December 22, 2025 08:55
@github-actions github-actions bot added the merge-conflict The PR conflicts with the target branch. label Dec 22, 2025
@github-actions
Copy link

This PR has merge conflicts with the base branch. Please rebase or merge the base branch into your branch to resolve them.

@xdustinface xdustinface force-pushed the refactor/ffi-networks branch from 3271b7a to 4a4014c Compare December 22, 2025 08:56
@github-actions github-actions bot removed the merge-conflict The PR conflicts with the target branch. label Dec 22, 2025
@xdustinface xdustinface reopened this Dec 22, 2025
@xdustinface xdustinface force-pushed the refactor/wallet-manager branch from 61198ae to a09352a Compare December 22, 2025 18:32
@github-actions
Copy link

This PR has merge conflicts with the base branch. Please rebase or merge the base branch into your branch to resolve them.

@github-actions github-actions bot added the merge-conflict The PR conflicts with the target branch. label Dec 22, 2025
@xdustinface xdustinface force-pushed the refactor/ffi-networks branch 2 times, most recently from 3df2035 to c896c14 Compare December 22, 2025 18:55
@xdustinface xdustinface force-pushed the refactor/wallet-manager branch from a09352a to 2cd41fa Compare December 22, 2025 18:55
@github-actions github-actions bot removed the merge-conflict The PR conflicts with the target branch. label Dec 22, 2025
@xdustinface xdustinface force-pushed the refactor/ffi-networks branch from c896c14 to 1a26acc Compare December 22, 2025 19:01
@github-actions
Copy link

This PR has merge conflicts with the base branch. Please rebase or merge the base branch into your branch to resolve them.

@github-actions github-actions bot added the merge-conflict The PR conflicts with the target branch. label Dec 22, 2025
@xdustinface xdustinface force-pushed the refactor/wallet-manager branch from 2cd41fa to 583a170 Compare December 22, 2025 19:08
@github-actions github-actions bot removed the merge-conflict The PR conflicts with the target branch. label Dec 22, 2025
@xdustinface xdustinface force-pushed the refactor/ffi-networks branch from 1a26acc to 5eff2d1 Compare December 22, 2025 19:15
@github-actions github-actions bot added the merge-conflict The PR conflicts with the target branch. label Dec 22, 2025
@github-actions
Copy link

This PR has merge conflicts with the base branch. Please rebase or merge the base branch into your branch to resolve them.

@xdustinface xdustinface force-pushed the refactor/ffi-networks branch from 5eff2d1 to db44dd5 Compare December 22, 2025 19:33
@xdustinface xdustinface force-pushed the refactor/wallet-manager branch from 583a170 to da1af64 Compare December 22, 2025 19:34
@github-actions github-actions bot removed the merge-conflict The PR conflicts with the target branch. label Dec 22, 2025
@xdustinface xdustinface force-pushed the refactor/ffi-networks branch from db44dd5 to 87c0601 Compare December 22, 2025 23:40
@github-actions github-actions bot added the merge-conflict The PR conflicts with the target branch. label Dec 22, 2025
@github-actions
Copy link

This PR has merge conflicts with the base branch. Please rebase or merge the base branch into your branch to resolve them.

@xdustinface xdustinface force-pushed the refactor/wallet-manager branch from da1af64 to b984765 Compare December 22, 2025 23:54
@github-actions github-actions bot removed the merge-conflict The PR conflicts with the target branch. label Dec 22, 2025
@xdustinface xdustinface changed the base branch from refactor/ffi-networks to v0.41-dev December 23, 2025 08:01
@xdustinface xdustinface force-pushed the refactor/wallet-manager branch from b984765 to 432e895 Compare December 23, 2025 08:02
@xdustinface xdustinface marked this pull request as ready for review December 23, 2025 08:09
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
key-wallet-manager/src/wallet_manager/mod.rs (3)

332-360: Missing network-consistency check when importing from extended private key

import_wallet_from_extended_priv_key builds a Wallet via Wallet::from_extended_key(...) without verifying that wallet.network matches self.network. Given that WalletManager is now explicitly single-network, this allows importing a wallet for a different network into the same manager, violating the “single network” invariant and the project preference to avoid mixing mainnet/testnet contexts.

Consider rejecting imports where the wallet’s network does not match the manager’s:

Suggested guard in import_wallet_from_extended_priv_key
-        // Create wallet from extended private key
-        let wallet = Wallet::from_extended_key(extended_priv_key, account_creation_options)
-            .map_err(|e| WalletError::WalletCreation(e.to_string()))?;
+        // Create wallet from extended private key
+        let wallet = Wallet::from_extended_key(extended_priv_key, account_creation_options)
+            .map_err(|e| WalletError::WalletCreation(e.to_string()))?;
+
+        // Enforce single-network invariant
+        if wallet.network != self.network {
+            return Err(WalletError::InvalidNetwork);
+        }

Based on learnings, this helps enforce “never mix mainnet and testnet operations” when managing wallets.


375-407: Also enforce network match when importing from xpub

Similarly, import_wallet_from_xpub creates a wallet via Wallet::from_xpub(...) and then adds it to a manager whose network may not match the xpub’s implied network. To keep the single-network invariant, add the same kind of check before inserting:

Suggested guard in import_wallet_from_xpub
-        // Create watch-only or externally signable wallet from extended public key
-        let wallet = Wallet::from_xpub(extended_pub_key, accounts, can_sign_externally)
-            .map_err(|e| WalletError::WalletCreation(e.to_string()))?;
+        // Create watch-only or externally signable wallet from extended public key
+        let wallet = Wallet::from_xpub(extended_pub_key, accounts, can_sign_externally)
+            .map_err(|e| WalletError::WalletCreation(e.to_string()))?;
+
+        // Enforce that imported wallet matches this manager's network
+        if wallet.network != self.network {
+            return Err(WalletError::InvalidNetwork);
+        }

This prevents accidentally loading a mainnet watch-only wallet into a testnet manager (or vice versa).

Based on learnings, …


422-451: Import from serialized bytes should also validate network vs manager

import_wallet_from_bytes deserializes a Wallet and then unconditionally inserts it, only using self.current_height as a default birth height. If the serialized wallet is for a different network than self.network, the manager will now be managing cross-network state.

Recommend adding a network check similar to the other import paths:

Suggested guard in import_wallet_from_bytes
-        // Compute wallet ID from the wallet's root public key
-        let wallet_id = wallet.compute_wallet_id();
+        // Ensure the imported wallet matches this manager's network
+        if wallet.network != self.network {
+            return Err(WalletError::InvalidNetwork);
+        }
+
+        // Compute wallet ID from the wallet's root public key
+        let wallet_id = wallet.compute_wallet_id();

Based on learnings, this keeps imported backups from silently breaking the single-network invariant.

♻️ Duplicate comments (1)
key-wallet-manager/src/wallet_manager/mod.rs (1)

869-879: wallet_utxos delegates cleanly to wallet_info.utxos

Aside from the type-consistency concern already mentioned for get_all_utxos, this method is straightforward: it resolves the wallet info and hands back the UTXO set. Once the shared utxos() contract is confirmed, this is fine.

🧹 Nitpick comments (10)
key-wallet-ffi/src/address_pool.rs (1)

1056-1063: FFI wallet_manager_create usage matches new network-bound API

Both test sites now construct the manager with an explicit FFINetwork::Testnet argument, matching the updated wallet_manager_create(network, error) signature and keeping the testnet address generation consistent with the manager’s network. Looks good; if this pattern expands further, consider a small helper to create a test manager and reduce duplication.

Also applies to: 1155-1162

key-wallet-ffi/src/wallet_manager_tests.rs (1)

883-1076: Serialized-wallet roundtrip tests use network-bound managers consistently

In test_create_wallet_from_mnemonic_return_serialized_bytes, all managers (manager, manager2, manager3, manager4, manager5) are created via wallet_manager_create(FFINetwork::Testnet, error), aligning with the new API. The watch-only and externally signable flows still validate ID stability and error handling for invalid mnemonics. You could optionally factor out a tiny helper for “fresh Testnet manager + error” to DRY these repeated patterns.

key-wallet-ffi/tests/test_passphrase_wallets.rs (1)

60-60: Consider adding Mainnet test coverage.

All tests in this file use FFINetwork::Testnet. Per coding guidelines, tests should cover both mainnet and testnet configurations to ensure network-specific behavior is validated.

Consider adding parallel test cases for FFINetwork::Dash (mainnet) to verify passphrase wallet functionality on both networks.

Based on coding guidelines.

key-wallet-manager/tests/test_serialized_wallets.rs (1)

11-11: Consider adding Mainnet test coverage.

All WalletManager instances are created with Network::Testnet. Per coding guidelines, tests should cover both mainnet and testnet configurations.

Consider adding test variants that use Network::Dash (mainnet) to ensure wallet serialization and passphrase handling work correctly across both networks.

Based on coding guidelines.

Also applies to: 30-30, 48-48, 64-64, 72-72, 90-90

key-wallet-ffi/src/wallet_manager_serialization_tests.rs (1)

20-20: Consider adding Mainnet test coverage.

All tests create wallet managers with FFINetwork::Testnet. Per coding guidelines, tests should validate behavior on both mainnet and testnet networks.

Consider duplicating key serialization tests to also run with FFINetwork::Dash (mainnet), ensuring serialization compatibility across networks.

Based on coding guidelines.

Also applies to: 71-71, 119-119, 167-167, 215-215, 246-246, 282-282, 320-320, 355-355

key-wallet-ffi/tests/test_import_wallet.rs (1)

17-17: Consider adding Mainnet test coverage.

The test creates wallet managers with FFINetwork::Testnet. Per coding guidelines, tests should validate both mainnet and testnet configurations.

Consider adding a test variant using FFINetwork::Dash (mainnet) to ensure wallet import functionality works correctly on both networks.

Based on coding guidelines.

Also applies to: 52-52

key-wallet-ffi/tests/integration_test.rs (1)

28-28: Consider adding Mainnet integration test coverage.

All integration tests use FFINetwork::Testnet. Per coding guidelines, integration tests should cover both mainnet and testnet configurations to validate network operations thoroughly.

Consider duplicating test_full_wallet_workflow and other critical integration tests to also run with FFINetwork::Dash (mainnet), ensuring the complete workflow functions correctly across both networks.

Based on coding guidelines.

key-wallet-manager/tests/spv_integration_tests.rs (1)

120-150: Consider adding mainnet test variant.

The filter caching tests work well with the new single-network API. Per coding guidelines, tests should cover both mainnet and testnet configurations. Consider adding a parameterized test or separate test function for Network::Dash to ensure network consistency validation works across networks.

key-wallet-ffi/src/managed_account.rs (1)

1343-1349: Minor: mutable binding may be unnecessary.

Line 1348 declares manager as mutable (let mut manager), but it's later reassigned via wallet_manager_create. The first assignment doesn't need mut since the variable is only being initialized, not mutated.

🔎 Suggested fix
-            let mut manager = wallet_manager_create(FFINetwork::Testnet, &mut error);
+            let manager = wallet_manager_create(FFINetwork::Testnet, &mut error);

Note: Line 1437 does require mut since the same variable is reassigned later in the test.

key-wallet-ffi/FFI_API.md (1)

480-480: Clarify network context in descriptions.

Several function descriptions still reference "for a network" or "for a given network" but no longer accept a network parameter:

  • Line 480: wallet_manager_current_height - "Get current height for a network"
  • Line 496: wallet_manager_describe - "Describe the wallet manager for a given network"
  • Line 676: wallet_manager_update_height - "Update block height for a network"

Since this is auto-generated documentation, consider updating the source docstrings to clarify that these operations apply to the network specified when the wallet manager was created (via wallet_manager_create).

Suggested description improvements

For consistency, descriptions could be updated to:

  • wallet_manager_current_height: "Get current height for the wallet manager's network"
  • wallet_manager_describe: "Describe the wallet manager"
  • wallet_manager_update_height: "Update block height for the wallet manager's network"

Also applies to: 496-496, 676-676

Copy link
Member

@QuantumExplorer QuantumExplorer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't go into too much detail on the review.

@xdustinface xdustinface merged commit 3884314 into v0.41-dev Dec 24, 2025
25 checks passed
@xdustinface xdustinface deleted the refactor/wallet-manager branch February 25, 2026 23:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants