MetaMask / metamask-extension

:globe_with_meridians: :electric_plug: The MetaMask browser extension enables browsing Ethereum blockchain enabled websites
https://metamask.io
Other
12.02k stars 4.91k forks source link

[Bug]: [MV3] Hardware Wallet Support #16217

Closed andrewpeters9 closed 1 year ago

andrewpeters9 commented 2 years ago

Describe the bug

Current interactions with hardware wallets, namely Trezor and Ledger wallets, are not supported by Chrome MV3 changes.

Steps to reproduce

Some of the ways the issue can be reproduced:

Error messages or log output

No response

Version

develop-oct16

Build type

No response

Browser

Chrome

Operating system

MacOS

Hardware wallet

No response

Additional context

General approaches on how to solve the issue:

  1. Address hardware-wallet connection issues within the background scripts by removing incompatibilities (briefly: DOM references (mainly iframe creations), and the loading of dynamic content (i.e. the Trezor connect popup). This would be done through the elaboration of the Keyrings, and use of APIs such as WebHID and WebUSB
  2. or, allow for hardware-wallet connections to be conducted within content scripts.

Why I believe # 2 is the better choice:

Suggested approach can be summarised into one verbose sentence:

Try to execute methods within hardware keyrings on the background-side first via a wrapper around the hardware keyring controller, upon (potential) failure defer to a promisified frontend execution of said method.

Why not run all Hardware Keyrings solely in the frontend?

Brief Overview of what the approach would entail:

Non- metamask-extension changes:

Client-Background Comms Changes:

Note: there are likely quite a few ways to approach the client-background comms implementation of this solution. Feel free to suggest changes/alternatives Given that there are quite a few places where the clientside is calling background methods that potentially need an additional callback, addressing the issue where each callBackgroundMethod is executed appears too messy.

Instead, a cleaner approach appears to be to persist the initial promise (the callBackgroundMethod promise), this can be done by:

  1. Attaching a clientside proxy to callBackgroundMethod's, likely around https://github.com/MetaMask/metamask-extension/blob/develop/ui/store/action-queue/index.js#L133 or somewhere else in the action-queue/index.js file. The proxy can intercept promise resolves/reject, and communicate with a ClientKeyringController (if a certain method is passed along) before resolving the promise
  2. or, elaborating the RPC comms to allow for a promisifiable message initiated from the background. This would involve elaborating the methods that are handled here https://github.com/MetaMask/metamask-extension/blob/develop/ui/index.js#L39-L52

If there's no preference, then I believe # 2 would be a better choice as it affords the opportunity for background-initiated promises that aren't related to call stacks which have callBackgroundMethod in them - it also appears less intrusive.

Diagram of Proposed Solution:

proposed-solution

danjm commented 2 years ago

@andrewpeters9 I want to make sure I understand:

Is this proposing that the webhid and webusb connections would be done from inside a service worker that is created in the contentscript?

andrewpeters9 commented 2 years ago

@danjm It's proposing that the connections (WebHid + WebUSB) would be done client-side, but their Keyrings would be called by the service worker. I'll DM you regarding a quick chat.

github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity in the last 90 days. It will be closed in 45 days. Thank you for your contributions.

github-actions[bot] commented 1 year ago

This issue was closed because there has been no follow up activity in the last 45 days. If you feel this was closed in error, please reopen and provide evidence on the latest release of the extension. Thank you for your contributions.