Skip to content

refactor(multichain-account-service)!: replace withKeyring usage with withKeyringV2#8491

Open
hmalik88 wants to merge 14 commits intomainfrom
hm/mul-1545
Open

refactor(multichain-account-service)!: replace withKeyring usage with withKeyringV2#8491
hmalik88 wants to merge 14 commits intomainfrom
hm/mul-1545

Conversation

@hmalik88
Copy link
Copy Markdown
Contributor

@hmalik88 hmalik88 commented Apr 16, 2026

Explanation

Changes

Base provider & types

  • Update AllowedActions to use KeyringControllerWithKeyringV2Action
  • BaseBip44AccountProvider.withKeyring now calls KeyringController:withKeyringV2 with KeyringSelectorV2

EvmAccountProvider

  • Callbacks use KeyringV2 methods: getAccounts() returns KeyringAccount[], createAccounts() replaces addAccounts()
  • Range creation loops with bip44:derive-index since HdKeyringV2 does not support bip44:derive-index-range
  • discoverAccounts replaces the V1 keyring.root peek with a create → check → delete-if-no-activity pattern, preserving the same net behavior of not leaving unused accounts in the
    HD keyring
  • Removed #getAddressFromGroupIndex (relied on V1 HD keyring internals)

SnapAccountProvider

  • Removed RestrictedSnapKeyring escape-hatch pattern that leaked keyring references outside the withKeyring mutex
  • withSnap now runs operations inside the withKeyringV2 scope
  • createBip44Accounts always uses keyring.createAccounts() directly, removing the V1/V2 branching based on batched config
  • resyncAccounts uses keyring.deleteAccount(id) instead of keyring.removeAccount(address)

Snap subclasses (BTC, SOL, TRX)

  • Removed createAccountV1 overrides — V2 snaps handle chain-specific account creation internally

References

N/a

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

Note

Medium Risk
Touches account creation/discovery paths and keyring mutex/persistence boundaries; regressions could lead to missed discovery results or unintended account/keyring state changes, though changes are scoped to provider/keyring integration.

Overview
BREAKING: Migrates multichain account providers’ keyring access from KeyringController:withKeyring to KeyringController:withKeyringV2, updating shared types/messenger delegation and the base provider withKeyring helper to use KeyringSelectorV2.

Updates EvmAccountProvider to use V2 keyring methods (getAccounts() returning KeyringAccount[], createAccounts(), deleteAccount()), changes range creation to loop per-index (since V2 HD keyrings don’t support range creation), and rewrites discovery to do create→RPC activity check→delete-if-inactive within a single withKeyringV2 callback to ensure no net keyring state change when no activity is found.

Keeps Snap-based providers on V1 keyring behavior for now by overriding withKeyring to call KeyringController:withKeyring, while still accepting V2 selectors; tests are updated accordingly and the changelog documents the breaking API shift.

Reviewed by Cursor Bugbot for commit 15f7986. Bugbot is set up for automated code reviews on this repo. Configure here.

@hmalik88 hmalik88 changed the title refactor(multichain-account-service): replace withKeyring usage with withKeyringV2 refactor(multichain-account-service)!: replace withKeyring usage with withKeyringV2 Apr 16, 2026
@hmalik88 hmalik88 marked this pull request as ready for review April 16, 2026 20:45
@hmalik88 hmalik88 requested review from a team as code owners April 16, 2026 20:45
Comment thread packages/multichain-account-service/src/providers/EvmAccountProvider.ts Outdated
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit e442d90. Configure here.

// Activity found — account stays. Return the address so we can
// look it up in the AccountsController after the callback persists.
return address;
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Discovery holds keyring mutex during network I/O

Medium Severity

The refactored discoverAccounts now performs the entire create → RPC check → delete flow inside a single withKeyringV2 callback. Since withKeyringV2 holds the KeyringController's exclusive mutex (#persistOrRollback#withControllerLock), the RPC call to #getTransactionCount — which retries up to maxAttempts times with timeoutMs and backOffMs delays — now blocks all other keyring operations (signing, account creation, switching, etc.) for potentially several seconds. The prior implementation performed the RPC call outside withKeyring, acquiring the mutex only briefly for the peek and create steps.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e442d90. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The prior implementation peeked at addresses via keyring.root (V1 internal state) outside the lock. V2 keyrings don't expose HD internals, so we create the account inside the callback to discover the address, and delete it if inactive. Both must happen in the same callback so that #persistOrRollback sees zero net state change, as a result this holds the lock during the rpc call

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.

1 participant