-
Notifications
You must be signed in to change notification settings - Fork 5k
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)
#27025
base: main
Are you sure you want to change the base?
Conversation
e323e79
to
6a165c8
Compare
Builds ready [6a165c8]
Page Load Metrics (1757 ± 85 ms)
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #27025 +/- ##
===========================================
- Coverage 69.96% 69.95% -0.00%
===========================================
Files 1441 1441
Lines 50102 50104 +2
Branches 14012 14008 -4
===========================================
Hits 35049 35049
- Misses 15053 15055 +2 ☔ View full report in Codecov by Sentry. |
Builds ready [c483c52]
Page Load Metrics (1813 ± 106 ms)
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
Quality Gate passedIssues Measures |
Builds ready [d5005d0]
Page Load Metrics (1705 ± 104 ms)
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
Builds ready [9ad5aad]
Page Load Metrics (1813 ± 91 ms)
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
Builds ready [32eeb35]
Page Load Metrics (1770 ± 134 ms)
Bundle size diffs [🚨 Warning! Bundle size has increased!]
|
Quality Gate failedFailed conditions |
This is currently blocked by https://github.com/MetaMask/accounts-planning/issues/615 |
This PR has been automatically marked as stale because it has not had recent activity in the last 60 days. It will be closed in 14 days. Thank you for your contributions. |
Builds ready [7ec4004]
Page Load Metrics (2051 ± 69 ms)
|
if (deviceName !== HardwareDeviceNames.trezor) { | ||
return deviceName; |
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.
This comparison is inverted so that the function can return without potentially adding a new keyring
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
automatically removes (and destroys) empty keyrings when removing accounts
/** | ||
* Select a hardware wallet device and execute a | ||
* callback with the keyring for that device. | ||
* | ||
* Note that KeyringController state is not updated before | ||
* the end of the callback execution, and calls to KeyringController | ||
* methods within the callback can lead to deadlocks. | ||
* | ||
* @param {object} options - The options for the device | ||
* @param {string} options.name - The device name to select | ||
* @param {string} options.hdPath - An optional hd path to be set on the device | ||
* keyring | ||
* @param {*} callback - The callback to execute with the keyring | ||
* @returns {*} The result of the callback | ||
*/ | ||
async withKeyringForDevice(options, callback) { |
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.
This is probably the biggest change of this PR: getKeyringForDevice
is now withKeyringForDevice
.
Instead of being a getter for a Keyring instance related to a device, it is now a safe callback executor for hardware devices.
It uses KeyringController.withKeyring
behind the scenes, so it also takes care of:
- Persisting keyrings into the encrypted vault after each change
- Reflecting Keyrings' changes to
KeyringController.state
- Rolling back to the previous controller state in case of unhandled errors
* @param {*} callback - The callback to execute with the keyring | ||
* @returns {*} The result of the callback | ||
*/ | ||
async withKeyringForDevice(options, callback) { |
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.
Nit: can we make this private I see it's being used only on this file (can we have a workaround for the test file without mocking a private function)?
app/scripts/metamask-controller.js
Outdated
* @param {string} address - The address of the account to remove. | ||
* @returns {Promise<void>} | ||
*/ | ||
async _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.
Nit: this seems to me it can be just a void can we remove the async keyword ? and await when calling the function
Description
This PR cherry-picks def6b15 into
develop
, after being reverted at 821c3bd. The reason the original commit was reverted is explained in #26840.From the original PR (#25435):
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.
Related issues
Fixes: #26840
Fixes: #24276
Manual testing steps
As for the original PR (#25435):
Affected workflows may include:
Screenshots/Recordings
Before
After
Pre-merge author checklist
Pre-merge reviewer checklist