Skip to content

Conversation

@bergarces
Copy link
Contributor

@bergarces bergarces commented Feb 9, 2023

Explanation

This PR aims to implement support for hardware wallets on MV3 using Chrome's Offscreen API.

Snaps

The idea is that hardware wallets are dealt with within an iframe inside the offscreen page. That is to ensure there's no conflict with snaps use of the offscreen api. As shown in this PR, in order to enable the snaps offscreen execution environment, an offscreen.html along with a javascript bundle is imported. Since this PR will be creating the offscreen.html, that'll have to change so that only the JavaScript bundles are imported.

Keyrings

Before this PR can be merged, the two associated PRs to split keyring and bridge logic from trezor and ledger keyrings need to be merged.

Those PRs were motivated by the issues faced implementing the MetaMask Desktop companion app, but they are useful in this case as well, since the SDKs rely on DOM calls that are not present within MV3 service-workers.

Lavamoat

The iframe code is currently bundled separately from the rest and it's not being bundled with lavamoat. Currently, that code only uses one dependency (@trezor/connect-web), although it should be possible to use no dependency at all if we import the code directly in the iframe from their page (https://connect.trezor.io/9/trezor-connect.js).

Trezor

The Trezor case is the simplest. A keyring bridge that forwards a message to the offscren iframe, which uses the TrezorConnect SDK the same way that it is used in the existing MV2 bridge. The SDK needs to be initialised with env: 'web' to prevent the use of extension APIs that are not supported in offscreen pages.

Ledger

The ledger case uses the existing live iframe (https://github.com/MetaMask/eth-ledger-bridge-keyring/blob/gh-pages/ledger-bridge.js). The offscreen ledger iframe just forwards the calls there and awaits a response.

Lattice

For the Lattice case, it was enough to overwrite the _getCreds method of the existing keyring. This solution, however, doesn't take into consideration that the sdk session is stored in the service-worker and, therefore, is bound to be cleared once it becomes inactive. A more robust solution should be possible by splitting the Lattice keyring code in the same fashion as Ledger and Lattice, so that functionality can be moved to the offscreen iframe if needed.

Splitting PR

It should be possible to split this PR in smaller ones for each hardware wallet, which should be easier to review.

Manual Testing Steps

For each hardware wallet (trezor, ledger and lattice), the following actions need to be tested for both MV2 and MV3 versions of the extension:

  • Import account from hardware wallet
  • Send transaction
  • Sign message
  • Sign personal message
  • Sign typed data v4

Pre-merge author checklist

  • I've clearly explained:
    • What problem this PR is solving
    • How this problem was solved
    • How reviewers can test my changes
  • Sufficient automated test coverage has been added

Pre-merge reviewer checklist

  • Manual testing (e.g. pull and build branch, run in browser, test code being changed)
  • PR is linked to the appropriate GitHub issue
  • IF this PR fixes a bug in the release milestone, add this PR to the release milestone

If further QA is required (e.g. new feature, complex testing steps, large refactor), add the Extension QA Board label.

In this case, a QA Engineer approval will be be required.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 9, 2023

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@bergarces bergarces force-pushed the offscreen-trezor branch 2 times, most recently from 444af14 to 9bd2ae5 Compare February 16, 2023 14:54
@bergarces bergarces changed the title mv3 trezor support using offscreen mv3 HW support using offscreen Feb 21, 2023
@bergarces bergarces force-pushed the offscreen-trezor branch 3 times, most recently from 14df1ec to 33abd2a Compare March 7, 2023 17:02
@danjm
Copy link
Contributor

danjm commented Mar 31, 2023

Fixes #14847

@socket-security
Copy link

socket-security bot commented Jun 20, 2023

👍 Dependency issues cleared. Learn more about Socket for GitHub ↗︎

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

@socket-security
Copy link

socket-security bot commented Jun 20, 2023

Updated dependencies detected. Learn more about Socket for GitHub ↗︎

Packages Version New capabilities Transitives Size Publisher
@metamask/eth-ledger-bridge-keyring 0.15.0...1.0.1 None +0/-1 106 kB metamaskbot
@metamask/eth-trezor-keyring 1.1.0...2.0.0 None +0/-0 81.8 kB metamaskbot

@github-actions
Copy link
Contributor

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.

@github-actions github-actions bot added the stale issues and PRs marked as stale label Aug 19, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Sep 2, 2023

This PR was closed because there has been no follow up activity in the last 14 days. Thank you for your contributions.

@github-actions github-actions bot closed this Sep 2, 2023
@danjm danjm reopened this Sep 28, 2023
@github-actions github-actions bot removed the stale issues and PRs marked as stale label Sep 28, 2023
brad-decker added a commit that referenced this pull request Nov 30, 2023
## **Description**
For MV3 snaps and Hardware wallet functionality we need to run some sets
of code in an offscreen document that can communicate with the
extension. The purpose of this Pull request is to start the conversation
about how to build this. This PR should be a stepping stone for the
fundamentals of #17687 and #17008 to incrementally be adopted.

The idea here is that we create a new "entry point" into the application
in the way of this offscreen.html file. There is a offscreen.ts file
that can be used to initialize a PostMessageStream for the iframe
itself, which is done in #17008. Essentially the
snaps-execution-environment offscreen document sets up lockdown and then
initializes the OffscreenSnapExecutor with its PostMessageStream. These
pieces can be added in a future PR, although I might need some guidance
on the proper way to setup lockdown.

In terms of Hardware wallet support, the iframes in #17687 and the
supporting typescript files can be included in layers ontop of this
folder structure, eventually getting to full hardware wallet support but
we should tackle these one at a time. There are a couple PRs opened by
@mikesposito to upgrade trezor and ledger keyrings that are also piecing
out elements from #17687 that are prereqs for continuing HW support in
MV3.

This uses post-message-stream which will later be used as well for snaps
execution in the offscreen document.

## **Related issues**
Partially progresses #21622 

## **Manual testing steps**

1. run `yarn start:mv3`
2. Go to extensions in chrome.
3. You should see both a service-worker and offscreen.html file loaded
and be able to inspect both.
4. Open both windows. From the service-worker console, run
`chrome.runtime.sendMessage({target: 'child', data: 'test'})`
5. See that the offscreen.html console logs the message. 
6. From the offscreen console, run `chrome.runtime.sendMessage({target:
'parent', data: 'test'})`
7. See that the service worker console logs the message. 

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've clearly explained what problem this PR is solving and how it
is solved.
- [x] I've linked related issues
- [x] I've included manual testing steps
- [x] I've included screenshots/recordings if applicable
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
- [x] I’ve properly set the pull request status:
  - [ ] In case it's not yet "ready for review", I've set it to "draft".
- [x] In case it's "ready for review", I've changed it from "draft" to
"non-draft".

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
@gauthierpetetin gauthierpetetin removed the team-extension-platform Extension Platform team label Dec 4, 2023
@github-actions github-actions bot locked and limited conversation to collaborators Jan 31, 2024
@gauthierpetetin gauthierpetetin added the team-extension-platform Extension Platform team label Feb 9, 2024
@bergarces bergarces deleted the offscreen-trezor branch November 4, 2025 16:44
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

team-extension-platform Extension Platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants