Summary
WalletManager::create_account (key-wallet-manager/src/lib.rs:541-556) — the manager crate's only public account-creation API — calls wallet.add_account on the raw Wallet (into AccountCollection) and bumps structural_revision. It never calls any of ManagedWalletInfo's add_managed_* variants, and never touches wallet_infos/ManagedAccountCollection at all.
The identical gap exists in the FFI layer: key-wallet-ffi::wallet_add_account (key-wallet-ffi/src/wallet.rs:314ff) also mutates only Wallet, never ManagedWalletInfo.
Confirmed by exhaustive workspace grep: add_managed_account, add_managed_bls_account, add_managed_account_from_xpub, and the other add_managed_* variants are called from zero non-test call sites in key-wallet-manager or key-wallet-ffi — only from test modules. git log -S "fn create_account" -- key-wallet-manager/src/lib.rs shows this predates PR #851 (since commit 40f5b4f6).
Impact
An account added through the manager crate's natural, real-world API is never scanned, never balanced through the managed layer, and receives none of the wallet-level protections that live on ManagedWalletInfo (including the #649 out-of-order-spend reconciliation and its account-addition safeguards from PR #851) — silently. There is no error, no log, nothing to indicate the account isn't actually being monitored.
key-wallet-manager/tests/integration_test.rs::test_account_management only asserts get_accounts (accessors.rs:107-110), which reads the raw Wallet, never ManagedWalletInfo — so this has zero test coverage today and would not catch either the original gap or a future regression.
Proposed fix
Either:
- Wire
WalletManager::create_account (and key-wallet-ffi::wallet_add_account) to also call the appropriate add_managed_* variant, so accounts created through the real API are actually monitored (this looks like the intended behavior), or
- If
add_managed_* is intentionally the only supported way to make an account "live" for monitoring purposes, document that loudly on create_account/wallet_add_account, and add a regression test pinning that create_account intentionally does not auto-manage.
Context
Surfaced during adversarial QA (Marvin) while verifying PR #851's follow-up fix for late-added-account resurrection (QA-001). Does not reopen that specific bug — an account invisible to ManagedWalletInfo has nothing for the prune/resurrection machinery to resurrect — but it means the fix's protections only engage for accounts added via add_managed_*, not via the production-facing create_account/wallet_add_account APIs.
Related, lower-priority note (not a blocker, folding in here rather than opening a second issue)
The same investigation traced an "implementation checkpoint" flagged during PR #851's design work: a coinbase belonging to a late-added/backfilled account computes its maturity window as (old_height, height] in WalletManager::finalize_block_advance (process_block.rs:396-449); for a backfilled block at or below the wallet's already-advanced last_processed_height, that window is empty, so the matured-coinbase event is not re-emitted for it. Balance correctness is not at risk (update_balance() recomputes from scratch each time), but a consumer relying on the event stream to learn about newly-spendable backfilled coinbase funds would miss the notification for that specific replay path. No test exercises this in either direction today.
🤖 Co-authored by Claudius the Magnificent AI Agent
Summary
WalletManager::create_account(key-wallet-manager/src/lib.rs:541-556) — the manager crate's only public account-creation API — callswallet.add_accounton the rawWallet(intoAccountCollection) and bumpsstructural_revision. It never calls any ofManagedWalletInfo'sadd_managed_*variants, and never toucheswallet_infos/ManagedAccountCollectionat all.The identical gap exists in the FFI layer:
key-wallet-ffi::wallet_add_account(key-wallet-ffi/src/wallet.rs:314ff) also mutates onlyWallet, neverManagedWalletInfo.Confirmed by exhaustive workspace grep:
add_managed_account,add_managed_bls_account,add_managed_account_from_xpub, and the otheradd_managed_*variants are called from zero non-test call sites inkey-wallet-managerorkey-wallet-ffi— only from test modules.git log -S "fn create_account" -- key-wallet-manager/src/lib.rsshows this predates PR #851 (since commit40f5b4f6).Impact
An account added through the manager crate's natural, real-world API is never scanned, never balanced through the managed layer, and receives none of the wallet-level protections that live on
ManagedWalletInfo(including the #649 out-of-order-spend reconciliation and its account-addition safeguards from PR #851) — silently. There is no error, no log, nothing to indicate the account isn't actually being monitored.key-wallet-manager/tests/integration_test.rs::test_account_managementonly assertsget_accounts(accessors.rs:107-110), which reads the rawWallet, neverManagedWalletInfo— so this has zero test coverage today and would not catch either the original gap or a future regression.Proposed fix
Either:
WalletManager::create_account(andkey-wallet-ffi::wallet_add_account) to also call the appropriateadd_managed_*variant, so accounts created through the real API are actually monitored (this looks like the intended behavior), oradd_managed_*is intentionally the only supported way to make an account "live" for monitoring purposes, document that loudly oncreate_account/wallet_add_account, and add a regression test pinning thatcreate_accountintentionally does not auto-manage.Context
Surfaced during adversarial QA (Marvin) while verifying PR #851's follow-up fix for late-added-account resurrection (QA-001). Does not reopen that specific bug — an account invisible to
ManagedWalletInfohas nothing for the prune/resurrection machinery to resurrect — but it means the fix's protections only engage for accounts added viaadd_managed_*, not via the production-facingcreate_account/wallet_add_accountAPIs.Related, lower-priority note (not a blocker, folding in here rather than opening a second issue)
The same investigation traced an "implementation checkpoint" flagged during PR #851's design work: a coinbase belonging to a late-added/backfilled account computes its maturity window as
(old_height, height]inWalletManager::finalize_block_advance(process_block.rs:396-449); for a backfilled block at or below the wallet's already-advancedlast_processed_height, that window is empty, so the matured-coinbase event is not re-emitted for it. Balance correctness is not at risk (update_balance()recomputes from scratch each time), but a consumer relying on the event stream to learn about newly-spendable backfilled coinbase funds would miss the notification for that specific replay path. No test exercises this in either direction today.🤖 Co-authored by Claudius the Magnificent AI Agent