Skip to content
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

Feat/add GridPlus Lattice1 Hardware Wallet #1346

Closed
wants to merge 35 commits into from

Conversation

mrcnk
Copy link

@mrcnk mrcnk commented Feb 15, 2024

Fixes BX-####
Figma link (if any):

What changed (plus any additional context for devs)

  • Added GridPlus as a hardware wallet option.
  • Added the onboarding process flow for GridPlus.
  • Added gridplus-sdk dependency and allowed it in lavamoat.
  • Added handlers to sign legacy transaction, typed data, and personal messages with GridPlus.
  • Added handler to broadcast transactions with GridPlus.
  • Added semi-automatic E2E test for the GridPlus onboarding.
  • Added an option to derive an address with custom address index with GridPlus.
  • Added effects to check for removed permissions of GridPlus (in Lattice1).

Screen recordings / screenshots

CleanShot 2024-02-15 at 18 11 24@2x
CleanShot 2024-02-15 at 18 12 41@2x
CleanShot 2024-02-15 at 18 13 33@2x
CleanShot 2024-02-15 at 18 14 13@2x

What to test

Copy link

socket-security bot commented Feb 15, 2024

🚨 Potential security issues detected. Learn more about Socket for GitHub ↗︎

To accept the risk, merge this PR and you will not be notified again.

Alert Package NoteSource
Install scripts npm/[email protected]
  • Install script: postinstall
  • Source: npx patch-package

View full report↗︎

Next steps

What is an install script?

Install scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.

Packages should not be running non-essential scripts during install and there are often solutions to problems people solve with install scripts that can be run at publish time instead.

Take a deeper look at the dependency

Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support [AT] socket [DOT] dev.

Remove the package

If you happen to install a dependency that Socket reports as Known Malware you should immediately remove it and select a different dependency. For other alert types, you may may wish to investigate alternative packages or consider if there are other ways to mitigate the specific risk posed by the dependency.

Mark a package as acceptable risk

To ignore an alert, reply with a comment starting with @SocketSecurity ignore followed by a space separated list of ecosystem/package-name@version specifiers. e.g. @SocketSecurity ignore npm/[email protected] or ignore all packages with @SocketSecurity ignore-all

Copy link
Member

@brunobar79 brunobar79 left a comment

Choose a reason for hiding this comment

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

REALLY GOOD STUFF!!

Added some comments but nothing major.
LMK if you have any questions.

src/design-system/components/TextOverflow/TextOverflow.tsx Outdated Show resolved Hide resolved
src/entries/popup/Routes.tsx Outdated Show resolved Hide resolved
src/entries/popup/components/Checkbox/Checkbox.tsx Outdated Show resolved Hide resolved
src/entries/popup/handlers/gridplus.ts Outdated Show resolved Hide resolved
src/entries/popup/handlers/wallet.ts Outdated Show resolved Hide resolved
src/entries/popup/pages/hw/gridplus/addressChoice.tsx Outdated Show resolved Hide resolved
src/entries/popup/pages/hw/gridplus/addressChoice.tsx Outdated Show resolved Hide resolved
static/manifest.json Outdated Show resolved Hide resolved
static/manifest.json Outdated Show resolved Hide resolved
static/vendor/trezor-connect.js Outdated Show resolved Hide resolved
@mrcnk
Copy link
Author

mrcnk commented Feb 28, 2024

@brunobar79 the PR feedback improvements are implemented now.

Copy link

socket-security bot commented Feb 29, 2024

New and removed dependencies detected. Learn more about Socket for GitHub ↗︎

Package New capabilities Transitives Size Publisher
npm/@ethereumjs/[email protected] Transitive: network +3 1.41 MB holgerd77
npm/[email protected] environment, network +14 4.53 MB asmiller1989

View full report↗︎

Copy link

Here's the packed extension for this build:
node_modules.tar.gz

Copy link
Member

@BrodyHughes BrodyHughes left a comment

Choose a reason for hiding this comment

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

did a quick lil onboarding test using mock data / IS_TESTING. Only issues I see:

  • Wallets & Keys page uses the generic Ledger logo instead of the Grid Lattice + logo
  • The first two pages of the flow don’t seem to match our other designs. mainly font size / spacing. this is just me nit picking tho. may need designer input.
Screenshot 2024-03-01 at 12 35 59 PM

e2e/helpers.ts Outdated Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
Copy link
Member

@BrodyHughes BrodyHughes left a comment

Choose a reason for hiding this comment

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

Finally got to test this with a physical GridPlus Lattice today:

  • Import flow worked well
  • Eth mainnet swaps, sends + dapp interactions are the only thing that seemed to work for me. No L2s or sidechains. When attempting, the GridPlus screen would flash, then the browser extension would say ‘make sure your GridPlus is unlocked’
  • Importing a duplicate wallet just caused the gridPlus import flow to get stuck on this screen:
Screenshot 2024-03-07 at 2 48 59 PM
  • Also when you import a wallet with the GridPlus, then import a sub wallet under the same mnemonic, they appear as separate wallet groups in our Wallets & Keys:
Screenshot 2024-03-07 at 2 49 28 PM
  • Additionally, it would be nice if the flow was keyboard navigable. I have suggestions on how to make the first page of the flow work with our keyboard nav. You can add tabIndex={0} on most things to make it work, or in some cases, you can also use our Lens component.

@mrcnk
Copy link
Author

mrcnk commented Mar 11, 2024

@BrodyHughes @brunobar79 the new feedback is addressed now. Pushed the improvements.

@BrodyHughes
Copy link
Member

Do you have a more square sized asset for this screen so it matches the designs of the others?
Screenshot 2024-03-15 at 12 27 23 PM

Also still seeing these issues:

  • Eth mainnet swaps, sends + dapp interactions are the only thing that seemed to work for me. No L2s or sidechains. When attempting, the GridPlus screen would flash, then the browser extension would say ‘make sure your GridPlus is unlocked’
  • Importing a duplicate wallet just caused the gridPlus import flow to get stuck on this screen:
Screenshot 2024-03-07 at 2 48 59 PM * Also when you import a wallet with the GridPlus, then import a sub wallet under the same mnemonic, they appear as separate wallet groups in our Wallets & Keys: Screenshot 2024-03-07 at 2 49 28 PM

@mrcnk
Copy link
Author

mrcnk commented Apr 15, 2024

Hi @BrodyHughes @brunobar79, I refactored the tx signing part and L2 transactions should now be working fine. Also the logo in Wallets & Keys is updated to match the rest.

Comment on lines 73 to 78
const nonExistingAddresses = fetchedAddresses
.map((address) => getAddress(address))
.filter(
(address) =>
!sortedAccounts.map((account) => account.address).includes(address),
);
Copy link
Contributor

Choose a reason for hiding this comment

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

is the idea here to not let the user select accounts that he already have in the extension?
lets say he had the pk in the extension AND in the grid+ lattice?
this should prevent him from importing that account from the gridplus?

Copy link
Author

Choose a reason for hiding this comment

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

Yes, precisely. It resulted in a thrown error when importing the same address another time.

deviceId: formData.deviceId,
password: formData.password,
name: appName,
getStoredClient: () => useGridPlusClientStore.getState().client,
Copy link
Contributor

Choose a reason for hiding this comment

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

why do we have a useGridPlusClientStore and a getStoredGridPlusClient?

Copy link
Author

Choose a reason for hiding this comment

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

Hi @greg-schrammel! Our SDK currently only supports synchronous storages (it's Web Storage API compliant), so in order to upgrade from it, to async Chrome Storage API, we had to utilize a simple Zustand store to make it synchronous.

(account) => account.address,
);
} else {
fetchedAddresses = (await fetchAddresses()) as Address[];
Copy link
Contributor

Choose a reason for hiding this comment

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

does this fetchAddresses get the client from some global? how does it know? couldn't find it in the sdk docs

Copy link
Author

Choose a reason for hiding this comment

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

fetchAddresses calls our API. Now, if user permitted Rainbow, it will return n derived addresses of user's wallet. The detailed implementation:
https://github.com/GridPlus/gridplus-sdk/blob/32b5389a768b2efd989a8af892a2b14e837110a8/src/api/addresses.ts#L18

event.preventDefault();
const accountsToImport = formData.selectedAddresses.map((address, i) => ({
address,
index: i,
Copy link
Contributor

Choose a reason for hiding this comment

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

is there a way to "add by index"? this index here should be the index of the wallet in the derivation path, not it's index in the array

Copy link
Author

Choose a reason for hiding this comment

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

The index in this view actually relates to the derivation path in Lattice. If there's no override for fetchAddresses starting path, then it starts from address index 0.

Copy link

github-actions bot commented May 1, 2024

Here's the packed extension for this build:
node_modules.tar.gz

@DanielSinclair
Copy link
Contributor

Closing in favor of #1538 to run CI and merge this week

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.

None yet

5 participants