-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: use withKeyring
method
#25435
Conversation
app/scripts/metamask-controller.js
Outdated
if (this.isKeyringAvailable(LedgerKeyring.type)) { | ||
await this.withKeyringForDevice( | ||
{ name: HardwareDeviceNames.ledger }, | ||
async (keyring) => this.setLedgerTransportPreference(keyring), | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could also be completely removed, since there shouldn't be any Ledger keyring right after creating (or restoring) the vault.
The this.isKeyringAvailable(LedgerKeyring.type)
condition helps not creating the keyring in case it was not present in the first place
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately we creates a new Ledger keyring for each user irrespective of whether they are Ledger users. This does seem bad, but I am unsure what the consequences would be for stopping this practice. The comment does suggest that setting this preference as soon as possible was critical, but I don't recall why.
Could we consider continuing the questionable practice of creating a Ledger keyring for all users (as we currently do), and stop doing this in a separate PR? So that we can reduce the changes of complications from this refactor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might also want to drop the await
here, given the comment above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, we can address this in a separate PR. I removed isKeyringAvailable
from the two occurrences of this practice for Ledger (and the isKeyringAvailable
function itself, since it is now unused), and left the promise dangling.
Perhaps a good place to set the transport preference would be in withKeyringForDevice
since it is used for all hardware keyring interactions
app/scripts/metamask-controller.js
Outdated
const keyring = await this.keyringController.getKeyringForAccount(address); | ||
// Remove account from the keyring | ||
await this.keyringController.removeAccount(address); | ||
const updatedKeyringAccounts = keyring ? await keyring.getAccounts() : {}; | ||
if (updatedKeyringAccounts?.length === 0) { | ||
keyring.destroy?.(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
KeyringController calls keyring.destroy()
automatically when the keyring is left with no accounts
const keyring = await this.getKeyringForDevice(deviceName); | ||
return this.withKeyringForDevice({ name: deviceName }, async (keyring) => { | ||
for (const address of keyring.accounts) { | ||
await this._onAccountRemoved(address); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By extracting side effects from removeAccount
we can execute side effects here without ending up in a deadlock.
The account is removed from KeyringController anyway when calling keyring.forgetDevice()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm. These side effects are a little strange (permissions should be automatically removed when an account is deleted, for instance). But I see that this is similar to how it already works today. Seems like a reasonable solution to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. Also, ideally, side effects should be executed after the account removal instead of before since an error could occur (that now would also trigger a rollback)
I have temporarily moved this back into draft to resolve conflicts |
4276021
to
4e9bd9f
Compare
Builds ready [2baee85]
Page Load Metrics (251 ± 253 ms)
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #25435 +/- ##
===========================================
- Coverage 69.75% 69.75% -0.00%
===========================================
Files 1400 1400
Lines 49419 49421 +2
Branches 13668 13664 -4
===========================================
Hits 34470 34470
- Misses 14949 14951 +2 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Just one pending issue about the unlockedAddress
casing, and one nit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Quality Gate passedIssues Measures |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Builds ready [b93dd74]
Page Load Metrics (106 ± 31 ms)
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
Description
With
@metamask/keyring-controller
v16 a new method is available which simplify safe direct keyring interactions which are not available through KeyringController.Through
withKeyring
it's possible to lock KeyringController's main mutex and select a specific keyring to interact with while KeyringController will be unusable concurrently.withKeyring
also takes care of persisting keyrings and updating the controller state at the end of the operation, which makes it possible to use it in substitution ofgetKeyringsByType
andpersistAllKeyrings
.Currently, most of the direct keyring interactions in the extension are made for hardware devices and snaps.
This PR is supposed to be merged after #25033
Related issues
Fixes: #24276
Manual testing steps
Affected workflows may include:
Screenshots/Recordings
N/A
Pre-merge author checklist
Pre-merge reviewer checklist