mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 09:23:21 +01:00
[FLASK] Add Snaps Keyring (#19710)
* flask - add restricted snap_manageAccounts * snap keyring: use local snap keyring instead of package * mvp snap-keyring * fixed the easier lint errors * fix missing permission text * add removal function * update snap keyring * update dep * update git link * update messages and remove snap keyring from lib * set snapprovider as soon as possible * chore: update snap keyring dependency * chore: pass SnapController to SnapKeyring constructor * chore: update deps and comment line (wip) * fix latest update for snaps and remove setController * update yarn lock * add routes * add messages * add message * add snap account detail page * add snap account card * add snap account page * update route * add background * use css grid * update snap text styling * fix lint * remove unused import * change manage link to go to snap * add types for react-router-dom * add link to settings * add breadcrumb to header * add popover * add prop types * add link to propTypes * fix icon in header and tag * update popover * update yarn.lock * add link to account list menu * update from deprecated * add add-snap-popup * use popoverheader * fix lint * update to use modal instead of popup * add install snap * remove export of DeferredPromise * change snap keyring to its own enum * update imports and fences * fix snapId and route * fix header and button for snapCard * hide app header on AddSnapAccountPage * update icon * match path to SnapAccountDetail * set getting started button to close modal * fix key prop warning * add By Metamask message * fix label * add fence to snapkeyringtype * update yarn.lock * refactor removeAccount and static snap list * update removeSnap * feat: remove associated accounts when snap is removed * add get snaps installed to snaps page * fix updateAvailable * add tests to ui components * update test * update scss * udpate config snap popup style * fixed https://www.notion.so/Show-pop-up-only-once-c6aa8494486a4ece8a5c5e35fea56ab5 * update accountListMenu click to open tab or push depending on environment * update yark.lock * remove unused uuid * update lock * update eth-snap-keyring * udpate install from snap page * update to install to use popup * use release versino of eth-snap-keyring * chore: bump snaps-utils version to `0.34.1-flask.1` * update configure snap * chore: update eth-snap-keyring * chore: update policies * fix: remove unused * fix: fix snap-account-detail-page test * fix: fix styles * chore: remove swappable-obj-proxy * fix: fix duplicate entry * fix: disable export private key for snaps account * feat: shuffle snap lists on every reload * fix: configure not popping up * refactor: snapsAddSnapAccountModalDismissal into action and selector * fix: E2BIG when running prettier * fix: lint default export or add-snap-account-modal * fix: lint, remove vendor prefix * fix: fix snapCreatedByMetamask to snapCreatedByMetaMask * Add `manageAccounts` RPC method (#19724) * Update dependencies * Remove snap-keyring-permissions * Update dependencies * Update dependencies * Update imports * removed portfolio link from wallet view (#19716) * removed portfolio link from wallet view * removed unused code * updated test * updated spec file * updated test * Validate LavaMoat policies on each PR (#19703) * Validate LavaMoat policies on each PR The LavaMoat policies are now validated on every PR. This makes it easier to validate policy changes, as they should always correspond with the changes made in the PR (unlike today, when they could be due to a change in platform or a previous PR). Closes #19680 * Update LavaMoat policies --------- Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com> * fix(action): add required permissions to remove labels (#19728) * Fix dependencies * signature approved metrics e2e test (#19628) * Update dependencies * Integrate Snow with LavaMoat scuttling protection (#17969) * Update lavamoat policies * Security Provider cleanup (#19694) * security-prov: isFlaggedSecurityProviderResponse * security-prov: create shared/modules/util * security prov: rn isFlagged -> isSuspcious - util fn returns true if response is not verified and flagged * security prov: add util test and support undefined param * security prov: reorg util fn - no logic changes * Update LavaMoat policies (#19744) Update LavaMoat policies to match what CI expects. * Replacing deprecated constants & creating stories (#19686) * Replacing deprecated constants & creating stories * updating snapshot * fix: fix imports * chore: update policy.json * fix: move SmartTransactionController out of snaps code fence * fix: yarn.lock dedupe * fix: lavamoat policy * fix: update test * fix: remove snapshot, the list of snaps are always randomized. * fix: resole snaps-controller to use flask --------- Co-authored-by: Nidhi Kumari <nidhi.kumari@consensys.net> Co-authored-by: Mark Stacey <markjstacey@gmail.com> Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com> Co-authored-by: Gauthier Petetin <gauthierpetetin@hotmail.com> Co-authored-by: Brad Decker <bhdecker84@gmail.com> Co-authored-by: weizman <weizmangal@gmail.com> Co-authored-by: Ariella Vu <20778143+digiwand@users.noreply.github.com> Co-authored-by: Dhruv <79097544+dhruvv173@users.noreply.github.com> Co-authored-by: Monte Lai <monte.lai@consensys.net> * Update LavaMoat policies * chore: fix webapp policy.json * feat: add snap label test * feat: test to disable export private key for snap accounts * feat: add snap account link test in account-list-menu * fix: add fence for setSnapsAddSnapAccountModalDismissed * fix: remove comments * fix: move routes into snaps fence * feat: use snap registry * fix: account snap identification * chore: add `keyring-snaps` feature flag * fix: remove unneeded spread * Disable warn logs in content-script (#19754) * Use Yarn caching in GitHub Actions (#19662) GitHub actions that install dependencies will now also cache those dependencies using the standard strategy for Yarn (which is to hash the lockfile). This matches the module template (see https://github.com/MetaMask/metamask-module-template/pull/145 for details). This should have no functional impact except that this action will run faster when dependencies are unchanged. * Fixing misspelling in 10.28.0 changelog notes (#19756) * Add `tokenId` type validation in `wallet_watchAsset` middleware (#19738) * Remove unused GitHub Action workflow (#19660) This GitHub action workflow was disabled, but was still running setup steps. It has now been removed entirely. We can re-introduce it again later once the problem that led to it being disabled has been fixed. The associated npm script and JavaScript module have been removed as well. * Fix #847 - Don't show account address on token pages (#19740) Co-authored-by: Nidhi Kumari <nidhi.kumari@consensys.net> * Deprecating FormField and fixing console error (#19739) * Deprecating FormField and fixing console error * Updating snapshots * updated linea image for token and badge (#19717) * updated linea image for token and badge * replaced hardcoded string with constant * UI updates for contacts Page (#19646) * updated contacts flow update * json file updates * updated contacts edit and view list * keep contacts tab selected * lint fix * replaced hardcoded strings with constant * updated padding in box * Replacing deprecated components and fixing prop errors (#19745) * Use `snaps@0.35.2-flask.1` and `snaps@1.0.0-prerelease.1` (#19734) * snaps@0.35.0-flask.1 * Update LavaMoat policies * Update stable snaps packages to 1.0.0-prerelease.1 * Update LavaMoat policies * Fix lint * snaps@0.35.2 * Exclude snap_manageAccounts * Code fencing * Revert removing endowment:keyring exclusion * Bump iframe URLs * UX: Ensure multichain native token name is always shown (#19705) * UX: Ensure multichain native token name is always shown * Fix lint * UX Multichain: fixed padding for edit screen (#19707) * fixed padding for edit screen * Use network picker for header trigger * Fix swaps display * updated snapshot --------- Co-authored-by: David Walsh <davidwalsh83@gmail.com> * Bump @metamask/providers to v11.1.0 (#19762) * Bump @metamask/providers to v11.1.0 --------- Co-authored-by: Alex <adonesky@gmail.com> * Fix fallback gas estimation (#19746) * Fix fallback gas estimation Our fallback gas estimation was failing due to a bug in the `@metamask/controller-utils` package. This was causing gas estimation to fail completely on certain networks (those not supported by our gas estimation APIs and non EIP-1559 compatibile), and it was causing the fallback gas estimation operation (in case our API was down) to fail across all networks. Fixes https://github.com/MetaMask/metamask-extension/issues/19735 * Add e2e tests E2E tests have been added to capture gas estimation. Cases are added for our API, for the fallback estimate, and for non-EIP-1559 estimates. As part of this work, the legacy gas API had to be disabled. This was being used in e2e tests but was dead code in production. It needed to be disabled to ensure the code under test was reachable. * Fix gas API referenced in e2e test * Update unit test snapshots * Update Label component font weight from bold to medium (#19731) * Update Label component font weight from bold to medium * update snapshot * fix snapshots * fix snapshots 2 * Removeing deprecated constants for enums --------- Co-authored-by: georgewrmarshall <george.marshall@consensys.net> * Part of #17670: Replace Typography with Text component in CancelSpeedupPopover (#18638) * create story * replace Typography with Text component * review changes * replace CSS with props styling * use `Button` from `component-library` * tooltip HTML refactor with `component-library` components * remove whitespace in story * strong tag support within Text component * addresses #18651 * taken from #18752 as suggested in https://github.com/MetaMask/metamask-extension/pull/18638#discussion_r1176334805 * replace `strong` with new `Text as="strong"` * remove unneccessary css from fa564e3f036f1439f9f220cca23595b508760614 * add text variant definition * Updating text variant of button * restrore proper spacing between elements * Quick fix for test * Adding key --------- Co-authored-by: georgewrmarshall <george.marshall@consensys.net> Co-authored-by: Garrett Bear <gwhisten@gmail.com> * Issue 17670 replace typography with text (#19433) * Replace Typograph with Text component in numeric-input-component.js * Replace Typography with Text component in signature-request-message.js * Replace Typography with Text component in signature-request.component.js * Replacing deprecating constants and fixing some signature story warnings * Updating snapshot * Fixing import --------- Co-authored-by: georgewrmarshall <george.marshall@consensys.net> Co-authored-by: Garrett Bear <gwhisten@gmail.com> * Part of #18714: Replacing deprecated constants in `confirm-subtitle` folder (#19699) * repalcing deprecated constants * resolve issue * lint fixes --------- Co-authored-by: georgewrmarshall <george.marshall@consensys.net> * Part of #17670: Replace Typography with Text component in: callout.js (#18912) * Part of #17670: Replace Typography with Text component in: callout.js * Update ui/components/ui/callout/callout.js Co-authored-by: Danica Shen <zhaodanica@gmail.com> * Update callout.js * Updating snapshot and deprecating component * Updating snapshot and deprecating component --------- Co-authored-by: Danica Shen <zhaodanica@gmail.com> Co-authored-by: George Marshall <george.marshall@consensys.net> Co-authored-by: Garrett Bear <gwhisten@gmail.com> * [MMI] Added code fences in whats new popup (#19581) * added code fences in whats new popup * Improved code * Added missing prop * Update LavaMoat policies * updated functions by using an options object for the rendering functions in order to bypass possible typsecript issues --------- Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com> * Updated action list in token, NFTs and activity view (#19702) * updated ui for nft import button * updated no nft image found in the center * updated footer for all screens in tabs * removed no nft state from nft tab * updated snapshot * lint fix * fixed e2e tests * fixed prep build error * removed no nfts yet test * updated tabs * fixed prod error * updated no nft screen * changed button size to md * fix: change 'M' to '?' * fix: update fence to keyring-snaps * chore: rename folder * fix: typo * chore: remove logs * feat: add metamask developer constant * fix: sass keyring-snap path * chore: update yarn.lock * fix: remove alias * feat: add KEYRING_SNAPS_REGISTRY_URL env * fix: nested fence * feat: add snap manageAccount e2e (#19777) * feat: add snap manageAccount e2e * feat: update link * fix: lint * fix: get values of restrictedMethodPermissionBuilders * fix: add fence to perferences * fix: stop shuffle * fix: remove KEYRING_SNAPS_REGISTRY_URL from metamaskRc * fix: use permissions to determine account snaps * fix: remove shuffle * fix: add comments to fences in excluded snap permission. * chore: fix policy.json * fix: fix snap-account-detail test * fix: lint * fix: snap accoutn detail page test * Update LavaMoat policies * Update ui/pages/keyring-snaps/snap-account-detail-page/snap-account-detail-page.test.tsx Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com> * Update ui/pages/keyring-snaps/snap-account-detail-page/snap-account-detail-page.test.tsx Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com> * fix: remove fence from isAbleToExportAccount * chore: remove comment line * fix: dismiss snap modal * fix: try catch for scroll * fix: icon for manageAccount * fix: update `handleSnapRequest` to make `params` optional and add `id` * fix: lint for uuid * fix: remove arg in saveSnapKeyring * fix: add fence for uuidV4 * chore: bump dep * fix: permission_manageAccounts message and icon * chore: update registry link * chore: convert address to lowercase * fix: change icon * chore: bump eth-snap-keyring * chore: update webapp policy.json * Update ui/pages/keyring-snaps/new-snap-account-page/new-snap-account-page.test.tsx Co-authored-by: Gustavo Antunes <17601467+gantunesr@users.noreply.github.com> * fix: update fences * fix: nested fence * Update app/_locales/en/messages.json Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com> * Update app/_locales/en/messages.json Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com> * Update app/_locales/en/messages.json Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com> * Update app/_locales/en/messages.json Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com> * Update ui/components/multichain/account-details/account-details-display.js Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com> * Update ui/pages/keyring-snaps/snap-account-detail-page/header.tsx Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com> * Update ui/pages/keyring-snaps/snap-account-detail-page/snap-account-detail-page.tsx Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com> * fix: rename and added jsdoc * fix: add fence to snap label * fix: remove comment * fix: change pixel to int and remove unused class * fix: lint * fix: create two tests for main and flask restricted methods * fix: remove fence in test * fix: lint header * feat: allow `metamask.github.io` in manifest * fix: remove comment * fix: rename isAbleToExportAccount * chore: use a more restrictive registry URL * fix: change to && not || * fix: remove unused * fix: move keyring snaps URL to Flask's base manifest * fix: use fetch instead of fetchWithCache * fix: lint --------- Co-authored-by: kumavis <aaron@kumavis.me> Co-authored-by: Howard Braham <howrad@gmail.com> Co-authored-by: Daniel Rocha <68558152+danroc@users.noreply.github.com> Co-authored-by: Gustavo Antunes <17601467+gantunesr@users.noreply.github.com> Co-authored-by: Nidhi Kumari <nidhi.kumari@consensys.net> Co-authored-by: Mark Stacey <markjstacey@gmail.com> Co-authored-by: MetaMask Bot <metamaskbot@users.noreply.github.com> Co-authored-by: Gauthier Petetin <gauthierpetetin@hotmail.com> Co-authored-by: Brad Decker <bhdecker84@gmail.com> Co-authored-by: weizman <weizmangal@gmail.com> Co-authored-by: Ariella Vu <20778143+digiwand@users.noreply.github.com> Co-authored-by: Dhruv <79097544+dhruvv173@users.noreply.github.com> Co-authored-by: ryanml <ryanlanese@gmail.com> Co-authored-by: Alex Donesky <adonesky@gmail.com> Co-authored-by: David Walsh <davidwalsh83@gmail.com> Co-authored-by: George Marshall <george.marshall@consensys.net> Co-authored-by: Frederik Bolding <frederik.bolding@gmail.com> Co-authored-by: jiexi <jiexiluan@gmail.com> Co-authored-by: jainex <jainexp017@gmail.com> Co-authored-by: Matthias Kretschmann <m@kretschmann.io> Co-authored-by: Garrett Bear <gwhisten@gmail.com> Co-authored-by: Ujwal Kumar <ujwalkumar95@gmail.com> Co-authored-by: rohit kerkar <129620973+rohiiittttt@users.noreply.github.com> Co-authored-by: Harsh Shukla <125105825+PrgrmrHarshShukla@users.noreply.github.com> Co-authored-by: Danica Shen <zhaodanica@gmail.com> Co-authored-by: Albert Olivé <albertolivecorbella@gmail.com> Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
This commit is contained in:
parent
230c0c6fa1
commit
af2c87d777
78
app/_locales/en/messages.json
generated
78
app/_locales/en/messages.json
generated
@ -271,6 +271,9 @@
|
||||
"addNfts": {
|
||||
"message": "Add NFTs"
|
||||
},
|
||||
"addSnapAccountModalDescription": {
|
||||
"message": "Discover options to keep your account secure with MetaMask Snaps"
|
||||
},
|
||||
"addSuggestedNFTs": {
|
||||
"message": "Add suggested NFTs"
|
||||
},
|
||||
@ -706,6 +709,21 @@
|
||||
"complianceSettingsExplanation": {
|
||||
"message": "Change your settings or view reports by opening up Codefi Compliance or disconnect below."
|
||||
},
|
||||
"configureSnapPopupDescription": {
|
||||
"message": "You're now leaving MetaMask to configure this snap."
|
||||
},
|
||||
"configureSnapPopupInstallDescription": {
|
||||
"message": "You're now leaving MetaMask to install this snap."
|
||||
},
|
||||
"configureSnapPopupInstallTitle": {
|
||||
"message": "Install snap"
|
||||
},
|
||||
"configureSnapPopupLink": {
|
||||
"message": "Click this link to continue:"
|
||||
},
|
||||
"configureSnapPopupTitle": {
|
||||
"message": "Configure snap"
|
||||
},
|
||||
"confirm": {
|
||||
"message": "Confirm"
|
||||
},
|
||||
@ -1701,6 +1719,9 @@
|
||||
"general": {
|
||||
"message": "General"
|
||||
},
|
||||
"getStarted": {
|
||||
"message": "Get started"
|
||||
},
|
||||
"globalTitle": {
|
||||
"message": "Global menu"
|
||||
},
|
||||
@ -3126,6 +3147,10 @@
|
||||
"message": "Allow the snap to run indefinitely while, for example, processing large amounts of data.",
|
||||
"description": "An extended description for the `endowment:long-running` permission"
|
||||
},
|
||||
"permission_manageAccounts": {
|
||||
"message": "Add and control Ethereum accounts",
|
||||
"description": "The description for `snap_manageAccounts` permission"
|
||||
},
|
||||
"permission_manageBip32Keys": {
|
||||
"message": "Control your accounts and assets under $1 ($2).",
|
||||
"description": "The description for the `snap_getBip32Entropy` permission. $1 is a derivation path, e.g. 'm/44'/0'/0''. $2 is the elliptic curve name, e.g. 'secp256k1'."
|
||||
@ -3739,6 +3764,9 @@
|
||||
"message": "Set a spending cap for your $1",
|
||||
"description": "$1 is a token symbol"
|
||||
},
|
||||
"settingAddSnapAccount": {
|
||||
"message": "Add snap account"
|
||||
},
|
||||
"settings": {
|
||||
"message": "Settings"
|
||||
},
|
||||
@ -3843,6 +3871,9 @@
|
||||
"smartSwapsSubDescription": {
|
||||
"message": "* Smart Swaps will attempt to submit your transaction privately, multiple times. If all attempts fail, the transaction will be broadcast publicly to ensure your Swap successfully goes through."
|
||||
},
|
||||
"snapConfigure": {
|
||||
"message": "Configure"
|
||||
},
|
||||
"snapConnectionWarning": {
|
||||
"message": "$1 wants to connect to $2. Only continue if you trust this website.",
|
||||
"description": "$2 is the snap and $1 is the dapp requesting connection to the snap."
|
||||
@ -3851,6 +3882,47 @@
|
||||
"message": "This content is coming from $1",
|
||||
"description": "This is shown when a snap shows transaction insight information in the confirmation UI. $1 is a link to the snap's settings page with the link text being the name of the snap."
|
||||
},
|
||||
"snapCreateAccountSubtitle": {
|
||||
"message": "Choose how to secure your new account using MetaMask Snaps."
|
||||
},
|
||||
"snapCreateAccountTitle": {
|
||||
"message": "Create a $1 account",
|
||||
"description": "Title of the Create Snap Account Page, $1 is the text using a different color"
|
||||
},
|
||||
"snapCreateAccountTitle2": {
|
||||
"message": "snap",
|
||||
"description": "$1 of the snapCreateAccountTitle"
|
||||
},
|
||||
"snapCreatedByMetaMask": {
|
||||
"message": "By MetaMask"
|
||||
},
|
||||
"snapDetailAudits": {
|
||||
"message": "Audit"
|
||||
},
|
||||
"snapDetailDeveloper": {
|
||||
"message": "Developer"
|
||||
},
|
||||
"snapDetailLastUpdated": {
|
||||
"message": "Updated"
|
||||
},
|
||||
"snapDetailManageSnap": {
|
||||
"message": "Manage snap"
|
||||
},
|
||||
"snapDetailTags": {
|
||||
"message": "Tags"
|
||||
},
|
||||
"snapDetailVersion": {
|
||||
"message": "Version"
|
||||
},
|
||||
"snapDetailWebsite": {
|
||||
"message": "Website"
|
||||
},
|
||||
"snapDetailsCreateASnapAccount": {
|
||||
"message": "Create a Snap Account"
|
||||
},
|
||||
"snapDetailsInstalled": {
|
||||
"message": "Installed"
|
||||
},
|
||||
"snapError": {
|
||||
"message": "Snap Error: '$1'. Error Code: '$2'",
|
||||
"description": "This is shown when a snap encounters an error. $1 is the error message from the snap, and $2 is the error code."
|
||||
@ -3892,6 +3964,9 @@
|
||||
"message": "Installation failed",
|
||||
"description": "Error title used when snap installation fails."
|
||||
},
|
||||
"snapIsAudited": {
|
||||
"message": "Audited"
|
||||
},
|
||||
"snapResultError": {
|
||||
"message": "Error"
|
||||
},
|
||||
@ -3904,6 +3979,9 @@
|
||||
"snapUpdate": {
|
||||
"message": "Update snap"
|
||||
},
|
||||
"snapUpdateAvailable": {
|
||||
"message": "Update available"
|
||||
},
|
||||
"snapUpdateErrorDescription": {
|
||||
"message": "$1 couldn’t be updated.",
|
||||
"description": "Error description used when snap update fails. $1 is the snap name."
|
||||
|
218
app/images/add-snaps-image.svg
Normal file
218
app/images/add-snaps-image.svg
Normal file
@ -0,0 +1,218 @@
|
||||
<svg width="328" height="227" viewBox="0 0 328 227" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21.9141 117.201L47.3534 120.85V95.3771L21.9141 91.7284V117.201Z" fill="#43AEFC"/>
|
||||
<path d="M64.3018 111.091L47.3535 120.85V95.3767L64.3018 85.6187V111.091Z" fill="#037DD6"/>
|
||||
<path d="M38.8623 81.9697L21.9141 91.7278L47.3534 95.3765L64.3017 85.6184L38.8623 81.9697Z" fill="#75C4FD"/>
|
||||
<path d="M40.7607 114.435L28.5071 112.517C27.3207 112.331 26.3716 111.228 26.3716 110.04V100.825L40.0827 102.963C41.642 103.201 42.9131 104.677 42.9131 106.238V112.619C42.9131 113.807 41.947 114.622 40.7607 114.435Z" fill="white"/>
|
||||
<path d="M31.8627 99.5862L27.9137 98.9753C27.0494 98.8395 26.3545 99.4335 26.3545 100.282V102.726L34.6253 104.016L33.2185 100.689C32.9982 100.112 32.4559 99.688 31.8627 99.5862Z" fill="white"/>
|
||||
<path d="M289.51 71.3134L264.342 74.9281V49.7268L289.51 46.1121V71.3134Z" fill="#037DD6"/>
|
||||
<path d="M247.563 65.2527L264.342 74.926V49.7247L247.563 40.0515V65.2527Z" fill="#43AEFC"/>
|
||||
<path d="M272.732 36.438L289.51 46.1112L264.342 49.726L247.563 40.0527L272.732 36.438Z" fill="#75C4FD"/>
|
||||
<path d="M271.749 140.044C271.494 141.079 271.24 142.114 270.969 143.133C270.257 145.78 269.444 148.393 268.545 150.99C268.359 151.516 268.172 152.042 267.986 152.551C265.63 159.017 262.681 165.245 259.19 171.151C258.834 171.745 258.478 172.356 258.105 172.933C255.8 176.683 253.275 180.281 250.546 183.743C249.597 184.948 248.631 186.136 247.631 187.29C246.631 188.444 245.614 189.581 244.58 190.701C241.36 194.146 237.92 197.405 234.259 200.442C233.479 201.087 232.7 201.715 231.903 202.343C221.124 210.811 208.616 217.43 194.702 221.571C180.787 225.711 166.686 227.035 153.043 225.83C152.043 225.745 151.043 225.644 150.043 225.525C148.145 225.304 146.247 225.05 144.382 224.727C140.654 224.099 136.959 223.285 133.315 222.3C132.773 222.148 132.213 221.995 131.671 221.842C130.197 221.418 128.739 220.96 127.298 220.468C123.129 219.076 119.045 217.43 115.079 215.563C114.621 215.342 114.146 215.122 113.689 214.884C113.519 214.799 113.367 214.732 113.197 214.647C111.079 213.594 108.977 212.474 106.927 211.286C104.503 209.895 102.147 208.418 99.8421 206.857C99.3337 206.518 98.8083 206.161 98.2998 205.788C97.5372 205.262 96.7915 204.719 96.0457 204.159C94.7407 203.191 93.4696 202.207 92.2154 201.189C90.7918 200.035 89.402 198.847 88.0292 197.625C88.0292 197.625 88.0122 197.625 88.0122 197.608C87.2157 196.895 86.4361 196.183 85.6564 195.436C79.3008 189.411 73.6062 182.606 68.759 175.105C68.5217 174.749 68.2845 174.375 68.0641 174.019C65.9456 170.659 63.9965 167.18 62.217 163.565C61.8272 162.751 61.4373 161.953 61.0475 161.121C60.234 159.373 59.4713 157.592 58.7595 155.793C58.4545 155.012 58.1494 154.231 57.8443 153.434C57.7596 153.179 57.6579 152.942 57.5731 152.687C57.4545 152.365 57.3359 152.042 57.2172 151.72C56.5562 149.853 55.9292 147.952 55.3529 146.018C54.2343 142.25 53.3191 138.449 52.6073 134.664C52.5056 134.155 52.4209 133.663 52.3361 133.154C52.2853 132.882 52.2514 132.628 52.2005 132.356C51.7938 129.946 51.4718 127.52 51.2345 125.11C51.1667 124.397 51.0989 123.684 51.0481 122.972C50.8277 120.273 50.7091 117.575 50.6921 114.894V114.758C50.6921 113.96 50.6921 113.146 50.7091 112.348C50.726 111.313 50.7599 110.278 50.7938 109.242C50.8108 108.988 50.8108 108.75 50.8277 108.496C51.1836 101.08 52.2853 93.7652 54.0818 86.6715C54.1496 86.4169 54.2174 86.1624 54.2682 85.9078C54.7428 84.075 55.2682 82.2761 55.8275 80.4772C56.2342 79.1875 56.6579 77.9147 57.0986 76.6419C57.4037 75.7764 57.7257 74.9109 58.0477 74.0454C58.0477 74.0454 58.0477 74.0454 58.0477 74.0284C58.7087 72.3144 59.3866 70.6173 60.1323 68.9542C65.4032 56.9221 72.7588 45.8572 81.8939 36.3028L81.9278 36.2689C84.0463 34.0627 86.2496 31.9244 88.5546 29.9049C88.6732 29.8031 88.7919 29.7012 88.9105 29.5825C100.673 19.2474 114.791 11.2373 130.773 6.48549C146.704 1.73373 162.873 0.698523 178.313 2.88773C181.567 3.34593 184.787 3.9399 187.956 4.68661C197.329 6.85884 206.345 10.236 214.802 14.6823C215.718 15.1575 216.616 15.6496 217.531 16.1587C219.734 17.3976 221.904 18.7043 224.022 20.0959C224.971 20.7068 225.903 21.3517 226.836 21.9966C227.412 22.3869 227.971 22.7942 228.53 23.2015C229.276 23.7446 230.022 24.2876 230.751 24.8477C231.683 25.5604 232.598 26.2732 233.496 27.0199C233.632 27.1387 233.767 27.2405 233.903 27.3593C233.954 27.4102 234.022 27.4611 234.072 27.4951C235.513 28.683 236.92 29.9049 238.31 31.1777C241.377 33.9778 244.309 36.9816 247.072 40.1382C247.919 41.1055 248.733 42.0898 249.546 43.0741C249.716 43.2947 249.902 43.4983 250.072 43.7189C252.004 46.1288 253.851 48.6404 255.597 51.2369C256.071 51.9327 256.529 52.6455 256.987 53.3582C258.427 55.6153 259.8 57.9403 261.088 60.3162C261.427 60.9441 261.766 61.572 262.088 62.1999C262.291 62.6072 262.512 63.0145 262.715 63.4218C262.851 63.6764 262.969 63.9309 263.088 64.1855C265.867 69.8027 268.189 75.7424 270.037 81.9537C270.071 82.0894 270.121 82.2252 270.155 82.361L270.443 83.3622C271.02 85.4157 271.545 87.4691 272.003 89.5225C272.189 90.3371 272.359 91.1687 272.528 92.0002C272.63 92.5433 272.748 93.0864 272.833 93.6124C273.087 94.9701 273.308 96.3447 273.511 97.7024C273.647 98.6018 273.765 99.4843 273.867 100.384C274.155 102.743 274.375 105.102 274.511 107.46C274.528 107.851 274.562 108.258 274.579 108.648C275.172 119.425 274.155 129.946 271.749 140.044Z" fill="url(#paint0_linear_6966_12826)"/>
|
||||
<path d="M146.992 58.4162C149.873 56.3288 155.06 53.8341 154.246 49.4897C153.483 45.4677 148.348 45.1792 145.111 45.3319C139.332 45.6034 134.095 48.3017 128.519 49.4897C123.621 50.5249 118.299 49.9139 114.774 46.0446C112.469 43.516 111.248 40.2407 109.028 37.6442C106.469 34.6574 102.672 33.5204 98.8252 33.8258C96.7405 33.9955 94.6559 34.5216 92.5374 34.3349C90.2324 34.1313 88.2834 32.4003 88.6054 29.9735C86.3004 32.01 84.0971 34.1313 81.9786 36.3375L81.9447 36.3714C72.8096 45.9089 65.454 56.9907 60.1831 69.0228C59.4543 70.7029 58.7595 72.4 58.0985 74.097C58.0985 74.097 58.0985 74.097 58.0985 74.114C57.7765 74.9795 57.4544 75.845 57.1494 76.7105C56.7087 77.9833 56.2681 79.2561 55.8783 80.5458C52.675 90.7621 50.9124 101.488 50.7599 112.417C50.7429 113.214 50.7429 114.012 50.7429 114.826C52.4547 115.879 53.9292 117.372 55.3359 118.798C57.0985 120.596 58.8273 122.48 60.861 123.957C62.2678 124.975 63.9456 125.637 65.6405 124.924C67.8946 123.974 69.3013 121.666 70.7927 119.85C72.3859 117.915 74.4027 116.286 76.8602 115.641C79.216 115.013 81.7413 115.098 84.0463 114.3C86.1309 113.571 87.4698 111.891 88.1478 109.854C88.8935 107.631 88.9274 105.221 89.6901 103.015C90.5036 100.639 92.6221 98.2801 94.961 97.3128C99.198 95.5648 102.808 99.9432 104.977 102.981C107.621 106.681 109.553 111.364 113.401 114.012C115.502 115.454 118.045 115.828 120.468 114.996C122.57 114.266 124.553 112.977 125.536 110.923C127.519 106.816 125.62 102.082 126.434 97.771C127.23 93.5792 130.078 90.7282 133.484 88.4372C137.094 85.9934 140.976 83.923 144.145 80.8853C146.094 79.0355 147.907 76.7275 148.263 73.9782C148.585 71.5345 147.535 69.2604 145.941 67.4785C145.009 66.4263 143.06 65.2553 143.111 63.6771C143.162 62.4722 144.077 61.3012 144.806 60.4187C145.416 59.6381 146.179 59.0102 146.992 58.4162Z" fill="url(#paint1_linear_6966_12826)"/>
|
||||
<path d="M101.266 159.459C96.4185 155.505 89.6053 155.963 84.4361 152.688C81.5718 150.872 79.6397 148.055 77.4873 145.526C75.1993 142.828 72.5214 140.689 69.047 139.773C65.4032 138.823 61.5729 139.094 57.9629 137.957C55.8952 137.295 54.1495 136.175 52.6411 134.733C53.3529 138.517 54.2681 142.302 55.3867 146.086C56.1325 148.598 56.9629 151.075 57.8781 153.502C58.1663 154.3 58.4713 155.08 58.7933 155.861C59.5052 157.66 60.2678 159.442 61.0814 161.19C61.4542 162.004 61.844 162.819 62.2508 163.634C68.2166 175.802 76.1992 186.527 85.6733 195.504C86.4529 196.234 87.2326 196.964 88.0291 197.677C88.0291 197.677 88.0291 197.677 88.0461 197.694C89.4189 198.915 90.8086 200.103 92.2323 201.257C92.4018 200.613 92.5374 199.951 92.656 199.306C93.317 195.776 94.1983 192.331 95.4694 188.971C96.8422 185.322 98.5879 181.826 100.418 178.381C102.113 175.174 104.249 171.915 104.791 168.25C105.282 164.822 103.91 161.614 101.266 159.459Z" fill="url(#paint2_linear_6966_12826)"/>
|
||||
<path d="M239.411 190.173C237.886 190.071 236.293 189.935 234.768 190.088C232.547 190.291 230.514 191.344 228.7 192.582C226.683 193.957 224.87 195.62 222.836 196.978C221.734 197.708 220.548 198.386 219.277 198.726C217.887 199.082 216.446 198.997 215.04 198.845C212.582 198.556 210.074 198.149 207.82 199.455C206.006 200.508 204.803 202.324 203.735 204.071C202.6 205.938 201.532 207.992 199.82 209.417C197.719 211.165 195.261 211.471 192.702 210.809C191.549 210.503 190.414 210.181 189.228 210.011C187.77 209.808 186.279 209.841 184.821 209.892C183.245 209.943 181.669 210.045 180.092 210.062C178.635 210.096 177.16 209.926 175.703 210.011C173.788 210.113 172.161 210.775 170.703 212.031C168.89 213.592 167.313 215.374 165.263 216.664C161.263 219.158 156.263 219.226 151.687 219.498C148.84 219.667 144.501 220.126 144.332 223.791C144.315 224.114 144.332 224.436 144.382 224.742C146.264 225.064 148.145 225.319 150.043 225.539C151.043 225.658 152.043 225.76 153.043 225.845C166.686 227.033 180.77 225.726 194.702 221.585C208.616 217.444 221.141 210.826 231.903 202.357C232.7 201.73 233.479 201.102 234.259 200.457C237.92 197.419 241.36 194.161 244.581 190.716C242.852 190.478 241.14 190.291 239.411 190.173Z" fill="url(#paint3_linear_6966_12826)"/>
|
||||
<path d="M252.953 86.96C251.479 82.7513 247.631 79.8154 243.733 77.762C241.428 76.5571 239.005 75.6067 236.53 74.7921C233.7 73.8588 230.853 73.0781 228.259 71.5677C217.243 65.085 218.429 49.506 197.583 49.506C188.6 49.506 185.431 53.2056 181.703 58.0761C178.109 62.777 177.025 68.8185 172.839 73.1799C169.381 76.7947 164.873 79.2554 161.415 82.8532C157.483 86.9261 155.721 92.2379 155.856 97.8042C155.992 103.71 158.331 109.497 162.042 114.215C163.89 116.557 166.076 118.678 168.534 120.426C170.771 122.038 173.178 123.464 175.245 125.297C177.211 127.045 178.55 129.234 179.635 131.576C181.025 134.596 182.957 137.091 185.262 139.535C187.702 142.114 190.261 144.677 191.804 147.884C193.126 150.617 193.685 153.57 193.837 156.556C194.159 162.309 193.38 168.147 195.414 173.731C196.956 177.973 201.481 183.217 206.583 182.946C212.565 182.64 213.514 174.986 214.65 170.676C215.023 169.25 215.447 167.808 216.124 166.484C216.921 164.923 218.023 163.48 219.023 162.038C220.887 159.34 222.802 156.692 224.616 153.96C228.192 148.546 230.954 142.793 232.022 136.378C232.615 132.832 232.785 129.302 233.852 125.84C234.801 122.768 236.208 119.866 237.903 117.117C241.344 111.516 245.801 106.578 249.563 101.181C252.428 97.0745 254.716 91.9833 252.953 86.96Z" fill="url(#paint4_linear_6966_12826)"/>
|
||||
<path d="M233.954 27.4937C232.92 26.6451 231.869 25.7966 230.801 24.982C230.073 24.422 229.327 23.8789 228.581 23.3359C228.022 22.9286 227.446 22.5213 226.886 22.131C225.954 21.4861 225.022 20.8412 224.073 20.2303C221.954 18.8387 219.785 17.5319 217.582 16.2931C217.056 16.8361 216.514 17.3453 215.887 17.7865C213.09 19.7551 209.633 19.1102 206.447 18.8387C203.532 18.5841 200.549 18.7029 198.278 20.7733C196.43 22.4534 195.447 24.8463 194.261 26.9846C193.634 28.1555 192.939 29.2926 192.024 30.2599C191.142 31.1933 190.075 31.8042 188.973 32.4321C187.041 33.5182 184.888 34.7401 183.702 36.6917C182.465 38.7112 183.024 41.2398 184.583 42.9369C186.177 44.6679 188.804 44.9225 191.007 44.9734C193.532 45.0243 196.125 44.583 198.634 44.9903C201.362 45.4316 203.769 47.0268 206.498 47.4002C207.921 47.5868 209.345 47.3832 210.684 46.8741C212.328 46.2462 213.87 45.2449 215.633 44.9564C217.378 44.6849 218.497 45.4485 219.7 46.5856C220.565 47.4002 221.48 48.2147 222.683 48.4354C227.124 49.2839 228.632 44.3794 229.53 41.0192C230.005 39.2713 230.327 37.2178 231.395 35.7244C232.615 34.0273 234.682 33.1279 236.513 32.2624C237.106 31.9909 237.767 31.7024 238.394 31.346C236.937 30.0053 235.462 28.7325 233.954 27.4937Z" fill="url(#paint5_linear_6966_12826)"/>
|
||||
<path d="M272.613 92.1372C272.444 91.3057 272.274 90.4911 272.088 89.6595C271.528 87.1309 270.867 84.6023 270.122 82.0906C268.054 75.1497 265.376 68.5481 262.173 62.3369C261.851 61.709 261.512 61.0641 261.173 60.4532C259.885 58.0773 258.512 55.7523 257.071 53.4952C256.614 52.7825 256.156 52.0697 255.682 51.3739C253.055 47.4707 250.207 43.7711 247.157 40.2751C247.089 41.3613 246.682 42.4134 246.123 43.4656C244.598 46.3506 242.326 48.5228 240.157 50.8987C238.208 53.0031 236.242 55.4468 235.886 58.3827C235.734 59.6895 235.869 61.1659 236.581 62.3199C237.225 63.3891 238.293 64.017 239.377 64.5431C240.53 65.0861 241.716 65.5783 242.598 66.5456C243.648 67.6996 244.174 69.1591 244.92 70.5167C246.53 73.4356 249.733 74.4539 252.445 76.0491C253.97 76.9486 255.411 78.0856 256.122 79.7657C256.885 81.5985 256.766 83.635 256.936 85.5696C257.173 88.2001 257.987 91.1869 260.19 92.85C262.19 94.3604 264.834 94.3095 267.207 94.1228C269.105 93.97 271.037 93.6815 272.952 93.7664C272.816 93.2233 272.715 92.6803 272.613 92.1372Z" fill="url(#paint6_linear_6966_12826)"/>
|
||||
<path opacity="0.4" d="M101.113 207.74C49.4549 173.647 35.1844 104.084 69.2166 52.3578C99.1811 6.8427 156.602 -9.68664 205.142 10.2538C208.074 11.4587 210.972 12.7994 213.836 14.2588C217.429 16.1086 220.955 18.1621 224.395 20.4361C132.417 24.0339 55.2342 83.2952 101.113 207.74Z" fill="url(#paint7_linear_6966_12826)"/>
|
||||
<path d="M173.33 224.912C163.466 224.912 153.416 223.113 143.484 219.481C130.858 214.865 119.113 207.602 108.588 197.894C98.4188 188.527 89.8091 177.275 82.9959 164.462C76.1827 151.65 71.488 137.92 69.0644 123.665C66.556 108.901 66.6069 94.1872 69.2 79.9659C71.9117 65.0657 77.2504 51.642 85.0466 40.085C92.5886 28.9184 102.029 20.0088 113.147 13.6449C133.807 1.78242 158.28 0.0174789 182.025 8.68945C193.651 12.9321 204.566 19.4658 214.464 28.0698C225.666 37.811 235.073 49.7583 242.445 63.5893C249.292 76.419 253.987 90.1652 256.428 104.454C258.953 119.253 258.902 133.966 256.309 148.222L255.936 148.154L256.309 148.222C253.597 163.122 248.259 176.545 240.462 188.102C232.92 199.269 223.48 208.179 212.362 214.543C200.346 221.433 187.024 224.912 173.33 224.912ZM152.179 4.00557C138.603 4.00557 125.417 7.46756 113.503 14.3067C102.503 20.6198 93.1309 29.4445 85.6567 40.5093C77.9283 51.9814 72.6235 65.3033 69.9288 80.1016C67.3526 94.2381 67.3018 108.85 69.7932 123.529C72.1998 137.717 76.8606 151.361 83.6399 164.106C90.4192 176.851 98.9781 188.018 109.079 197.334C119.536 206.974 131.197 214.186 143.722 218.768C153.568 222.366 163.534 224.148 173.313 224.148C186.889 224.148 200.075 220.703 211.989 213.864C222.989 207.551 232.361 198.726 239.835 187.661C247.564 176.189 252.868 162.867 255.563 148.069C258.139 133.915 258.19 119.27 255.682 104.556C253.258 90.3519 248.581 76.6736 241.784 63.9287C234.446 50.1825 225.09 38.3201 213.972 28.6299C204.142 20.0767 193.312 13.6109 181.77 9.38524C171.923 5.80445 161.941 4.00557 152.179 4.00557Z" fill="white"/>
|
||||
<path d="M183.075 223.334C182.686 223.334 182.313 223.334 181.923 223.317C172.991 223.113 163.788 220.584 154.535 215.782C144.196 210.402 134.366 202.511 125.35 192.295C116.638 182.435 109.045 170.861 102.758 157.878C96.4698 144.896 91.809 131.166 88.9278 117.081C85.9279 102.486 84.9619 88.1291 86.0466 74.3999C88.4193 44.4129 100.571 21.2141 119.401 10.7602C126.807 6.65332 134.942 4.65079 143.569 4.85444C152.501 5.05809 161.704 7.5867 170.957 12.3894C180.482 17.3448 189.601 24.4555 198.041 33.5517C207.583 43.8359 215.887 56.1565 222.684 70.1572C228.988 83.1567 233.666 96.9029 236.564 111.022C239.581 125.651 240.547 140.025 239.462 153.771C237.09 183.758 224.938 206.957 206.108 217.411C199.024 221.348 191.295 223.334 183.075 223.334ZM142.417 5.60115C134.332 5.60115 126.722 7.55276 119.757 11.4221C101.164 21.7571 89.1481 44.7353 86.7923 74.4678C85.7076 88.1121 86.6737 102.401 89.6566 116.928C92.5378 130.963 97.1646 144.624 103.435 157.556C109.689 170.47 117.265 181.993 125.926 191.802C134.891 201.934 144.637 209.791 154.89 215.12C164.026 219.872 173.127 222.383 181.94 222.57C190.431 222.757 198.448 220.805 205.735 216.766C224.328 206.431 236.344 183.47 238.7 153.737C239.784 140.076 238.818 125.753 235.818 111.209C232.92 97.1574 228.277 83.4622 221.989 70.5306C215.226 56.5977 206.973 44.345 197.481 34.1117C189.092 25.0834 180.059 18.0236 170.602 13.1021C161.466 8.31644 152.365 5.82176 143.552 5.61812C143.179 5.60115 142.789 5.60115 142.417 5.60115Z" fill="white"/>
|
||||
<path d="M191.329 222.008C189.431 222.008 187.465 221.77 185.465 221.312C179.635 219.971 173.432 216.679 167.059 211.554C151.721 199.233 136.84 177.511 125.146 150.426C113.452 123.341 106.351 94.1176 105.13 68.1186C104.401 52.5736 105.808 39.3874 109.283 28.9336C112.621 18.9039 117.875 11.8442 124.468 8.484C129.112 6.10812 134.349 5.58203 140.027 6.88877C145.857 8.22944 152.06 11.5217 158.433 16.6469C165.585 22.3829 172.652 30.1894 179.448 39.8117C187.143 50.7068 194.159 63.4347 200.295 77.6391C212.023 104.758 219.141 134.049 220.361 160.082C221.09 175.627 219.684 188.813 216.209 199.267C212.87 209.297 207.616 216.374 201.024 219.717C198.024 221.227 194.787 222.008 191.329 222.008ZM134.163 6.92271C130.824 6.92271 127.705 7.66942 124.807 9.12889C118.401 12.4042 113.265 19.3282 109.994 29.1542C106.537 39.5232 105.147 52.6075 105.876 68.0507C107.096 93.9648 114.181 123.103 125.824 150.104C137.468 177.087 152.28 198.69 167.517 210.943C173.805 216 179.889 219.225 185.618 220.548C191.109 221.821 196.176 221.295 200.668 219.021C207.074 215.746 212.209 208.839 215.48 198.996C218.938 188.627 220.328 175.542 219.599 160.099C218.379 134.151 211.277 104.962 199.583 77.9107C193.465 63.7402 186.465 51.0632 178.804 40.219C172.042 30.6476 165.025 22.909 157.941 17.2069C151.653 12.1496 145.569 8.92524 139.84 7.60153C137.908 7.1603 136.01 6.92271 134.163 6.92271Z" fill="white"/>
|
||||
<path d="M196.075 221.248C191.38 221.248 185.381 216.632 178.5 207.671C156.535 179.059 131.451 113.875 122.587 62.3521C119.943 46.9428 118.943 33.7906 119.706 24.3041C120.452 15.0042 122.909 9.18331 126.79 7.48625C131.773 5.29705 138.739 9.81122 146.976 20.5366C151.942 27.0024 157.128 35.4029 162.433 45.5173C168.415 56.9555 174.263 70.0737 179.805 84.4648C190.38 111.94 198.583 140.841 202.888 165.856C205.532 181.265 206.532 194.417 205.769 203.904C205.024 213.204 202.566 219.024 198.685 220.722C197.871 221.061 197.007 221.248 196.075 221.248ZM129.434 7.6899C128.536 7.6899 127.773 7.87658 127.112 8.16508C123.502 9.76031 121.197 15.3436 120.469 24.355C119.706 33.7737 120.706 46.875 123.333 62.2164C132.18 113.637 157.196 178.668 179.093 207.196C187.126 217.667 192.55 220.484 196.041 220.484C196.939 220.484 197.702 220.297 198.363 220.009C201.973 218.414 204.278 212.83 205.007 203.819C205.769 194.4 204.769 181.299 202.142 165.958C197.854 141.011 189.668 112.161 179.11 84.7194C173.568 70.3453 167.737 57.2779 161.772 45.8567C156.501 35.7762 151.315 27.4097 146.383 20.9779C138.349 10.507 132.943 7.6899 129.434 7.6899Z" fill="white"/>
|
||||
<path d="M127.816 7.51205L127.093 7.75269L197.693 220.684L198.417 220.444L127.816 7.51205Z" fill="white"/>
|
||||
<path d="M263.156 64.3212C261.156 66.8668 256.275 70.2269 248.529 74.3338C217.972 90.5916 151.992 113.824 101.452 126.145C90.6054 128.792 69.0133 133.663 57.302 133.663C55.353 133.663 53.6751 133.527 52.3531 133.222C52.3023 132.95 52.2684 132.696 52.2175 132.424C57.3529 133.799 72.0979 132.509 101.266 125.398C151.755 113.095 217.65 89.8789 248.157 73.655C257.783 68.5299 261.478 65.3903 262.783 63.5405C262.902 63.829 263.037 64.0836 263.156 64.3212Z" fill="white"/>
|
||||
<path d="M250.123 43.8545C248.716 46.1964 243.869 49.5057 235.666 53.7483C206.786 68.6315 144.687 90.3878 97.2491 102.233C77.5382 107.155 62.878 109.734 55.0309 109.734C53.2852 109.734 51.8785 109.615 50.8108 109.344C50.8277 109.089 50.8277 108.852 50.8447 108.597C56.1326 110.074 72.9961 107.511 97.0626 101.504C144.45 89.675 206.481 67.9527 235.31 53.0865C246.072 47.5371 248.953 44.6012 249.614 43.2266C249.784 43.4302 249.953 43.6339 250.123 43.8545Z" fill="white"/>
|
||||
<path d="M234.14 27.6301C233.344 28.4956 230.581 30.3963 220.243 34.7917C193.465 46.1789 137.179 65.2539 94.7747 77.3199C82.233 80.8838 71.7251 83.5991 64.4034 85.1603C58.7088 86.3822 55.709 86.7386 54.0989 86.7556C54.1667 86.501 54.2345 86.2465 54.2853 85.9919C55.7768 85.941 58.6071 85.6185 63.9628 84.4815C71.2844 82.9372 81.8602 80.2049 94.5375 76.6072C136.908 64.5581 193.16 45.5001 219.921 34.1128C230.276 29.7175 232.903 27.8677 233.547 27.1549C233.683 27.2737 233.818 27.3755 233.954 27.4943C234.022 27.5452 234.073 27.5961 234.14 27.6301Z" fill="white"/>
|
||||
<path d="M65.7594 59.6876C65.1831 59.6876 65.0814 59.5518 64.9797 59.45C64.8442 59.2973 64.8272 59.0766 64.9289 58.89L65.6068 59.2294C65.6238 59.1954 65.6407 59.1275 65.6068 59.0427C65.5729 58.9578 65.5221 58.9239 65.5051 58.9069C66.3864 59.2633 75.4199 57.2099 97.995 50.3028C131.129 40.1714 175.381 25.0846 196.651 16.6841C206.447 12.8148 207.633 11.8305 207.752 11.6269C207.735 11.6439 207.718 11.7118 207.752 11.8136C207.769 11.8815 207.82 11.9154 207.837 11.9493L208.006 11.2196C208.413 11.3045 208.481 11.593 208.481 11.6948C208.515 12.136 208.566 12.7979 196.922 17.3969C175.635 25.7973 131.349 40.8842 98.1984 51.0326C88.2158 54.0873 79.9281 56.4801 74.2335 57.9566C68.8778 59.3312 66.6915 59.6876 65.7594 59.6876Z" fill="white"/>
|
||||
<path d="M84.4874 34.7934C84.0298 34.7934 83.962 34.6746 83.8773 34.5388C83.8264 34.471 83.7078 34.1994 84.0129 33.9109L84.5383 34.454C84.5552 34.42 84.5891 34.3182 84.5552 34.2164C84.5213 34.0976 84.4196 34.0467 84.3857 34.0297C85.0467 34.1994 91.0125 32.7909 105.639 28.2937C127.4 21.5903 156.484 11.6964 170.466 6.2319C176.771 3.77116 177.618 3.14325 177.737 3.00748C177.72 3.02445 177.686 3.09234 177.703 3.19416C177.72 3.27901 177.771 3.36387 177.839 3.41478L178.262 2.78687C178.398 2.88869 178.466 3.04142 178.449 3.21113C178.415 3.55054 178.364 3.97481 170.754 6.94466C156.738 12.4092 127.638 22.32 105.859 29.0234C99.2494 31.0599 93.792 32.6551 90.0464 33.6394C86.6059 34.5388 85.1484 34.7934 84.4874 34.7934Z" fill="white"/>
|
||||
<path d="M270.528 83.5136C268.461 86.7041 263.919 90.5394 256.953 94.9518C226.853 114.112 160.161 138.447 108.3 149.173C92.6393 152.414 79.3858 154.179 70.0134 154.264C69.7592 154.264 69.5049 154.264 69.2507 154.264C64.0984 154.264 60.2003 153.755 57.5903 152.754C57.4716 152.431 57.353 152.109 57.2344 151.786C59.4377 152.804 63.3188 153.568 69.9964 153.517C79.318 153.432 92.5207 151.684 108.13 148.443C159.924 137.735 226.497 113.45 256.529 94.3238C265.02 88.9272 268.766 85.1088 270.223 82.5123L270.528 83.5136Z" fill="white"/>
|
||||
<path d="M274.664 108.784C272.376 111.669 268.291 115.03 262.41 118.814C233.158 137.702 168.229 161.444 117.672 171.762C101.995 174.953 89.2836 176.565 80.1993 176.565C75.2843 176.565 71.454 176.09 68.7762 175.156C68.5389 174.8 68.3016 174.427 68.0813 174.07C70.3354 175.088 74.2505 175.852 80.962 175.784C90.0124 175.699 102.656 174.053 117.536 171.015C168.025 160.731 232.836 137.023 262.02 118.186C269.156 113.57 272.85 110.125 274.63 107.596C274.63 108.004 274.647 108.394 274.664 108.784Z" fill="white"/>
|
||||
<path d="M94.9102 193.724C86.7581 193.724 81.4532 192.417 79.5381 189.769L80.1482 189.328C81.9108 191.755 87.0123 192.96 94.8085 192.96C103.147 192.96 114.536 191.585 128.197 188.836C174.94 179.451 234.75 156.982 261.546 138.739C272.986 130.949 274.782 126.486 274.274 124.11L275.02 123.957C275.833 127.742 271.443 132.918 261.969 139.367C235.106 157.661 175.16 180.181 128.349 189.583C114.621 192.349 103.266 193.724 94.9102 193.724Z" fill="white"/>
|
||||
<path d="M268.546 150.991C268.359 151.517 268.173 152.043 267.986 152.552C266.139 154.164 263.8 155.895 260.97 157.762C236.598 173.799 182.753 194.385 140.925 203.65C127.451 206.637 116.52 208.148 108.91 208.148C104.927 208.148 101.859 207.723 99.8255 206.892C99.1645 206.62 98.6222 206.315 98.1985 205.958L98.3002 205.84L98.69 205.348C100.656 206.977 105.385 207.656 112.333 207.299C119.706 206.926 129.282 205.449 140.773 202.904C182.516 193.655 236.259 173.12 260.563 157.134C264.224 154.673 266.766 152.654 268.546 150.991Z" fill="white"/>
|
||||
<path d="M127.909 218.689C122.994 218.689 119.35 218.078 117.164 216.873L117.536 216.212C122.248 218.825 134.773 218.418 151.908 215.091C186.753 208.32 231.208 191.519 251.038 177.637C255.343 174.634 258.207 171.952 259.563 169.695L260.207 170.086C258.8 172.444 255.851 175.194 251.479 178.248C231.581 192.181 186.99 209.033 152.06 215.838C142.264 217.722 134.078 218.689 127.909 218.689Z" fill="white"/>
|
||||
<path d="M165.415 73.2644C165.229 73.468 165.076 73.7226 165.076 73.9941C165.076 74.656 165.89 74.9784 166.534 75.0972C170.28 75.776 173.957 75.4875 177.652 74.7238C182.669 73.6886 187.651 72.0595 192.821 72.0934C195.583 72.1104 198.21 72.7892 200.905 73.2813C203.346 73.7226 205.786 73.8074 208.244 73.4171C213.006 72.6365 217.396 70.3624 221.412 67.732C223.311 66.4931 225.226 65.2033 226.921 63.676C228.327 62.4032 229.666 60.9437 230.446 59.1788C231.158 57.5835 231.259 55.7847 230.429 54.2064C229.378 52.2548 227.107 51.2875 224.972 51.1687C222.429 51.0329 220.023 52.153 217.87 53.3918C215.565 54.7325 213.328 56.2089 211.023 57.5496C206.43 60.214 201.685 62.6578 196.804 64.7451C189.16 68.0035 181.516 69.7854 173.364 71.177C172.517 71.3297 171.381 71.3976 170.229 71.5334C168.364 71.8049 166.432 72.1783 165.415 73.2644Z" fill="url(#paint8_linear_6966_12826)"/>
|
||||
<path d="M149.416 84.4478C149.857 85.2284 150.823 85.5678 151.721 85.6696C154.212 85.9751 156.653 86.3145 159.195 86.0939C160.805 85.9581 162.398 85.6527 163.958 85.1775C164.72 84.9399 165.483 84.6684 166.229 84.3629C166.924 84.0744 167.618 83.7859 168.229 83.3447C169.127 82.7168 170.059 81.5288 169.246 80.4597C168.788 79.8488 167.957 79.679 167.246 79.6281C166.33 79.5603 165.381 79.6621 164.466 79.713C160.619 79.9506 156.805 80.4936 153.043 81.3252C151.874 81.5797 149.162 82.0379 149.162 83.5483C149.145 83.8199 149.23 84.1084 149.416 84.4478Z" fill="url(#paint9_linear_6966_12826)"/>
|
||||
<path d="M76.7759 42.2731C66.0137 44.5302 18.5586 76.0106 69.6237 74.4832C120.689 72.9559 104.385 55.7307 88.2499 58.7176C72.1151 61.7044 43.6251 63.7918 71.1152 49.4516L76.7759 42.2731Z" fill="url(#paint10_linear_6966_12826)"/>
|
||||
<path d="M76.7759 42.2731C66.0137 44.5302 18.5586 76.0106 69.6237 74.4832C120.689 72.9559 104.385 55.7307 88.2499 58.7176C72.1151 61.7044 43.6251 63.7918 71.1152 49.4516L76.7759 42.2731Z" fill="url(#paint11_linear_6966_12826)"/>
|
||||
<path d="M33.7949 198.236L59.6919 201.952V176.021L33.7949 172.305V198.236Z" fill="#43AEFC"/>
|
||||
<path d="M76.9452 192.013L59.6919 201.957V176.026L76.9452 166.082V192.013Z" fill="#037DD6"/>
|
||||
<path d="M51.0483 162.36L33.7949 172.288L59.6919 176.022L76.9453 166.077L51.0483 162.36Z" fill="#75C4FD"/>
|
||||
<path d="M52.8412 193.73C56.0275 190.748 55.8486 185.371 52.4416 181.722C49.0346 178.073 43.6897 177.532 40.5033 180.515C37.3169 183.498 37.4958 188.874 40.9028 192.523C44.3098 196.173 49.6548 196.713 52.8412 193.73Z" fill="white"/>
|
||||
<path d="M46.6755 182.238C46.6755 184.936 44.4892 186.837 41.7944 186.464C44.4892 186.82 46.6755 189.315 46.6755 192.013C46.6755 189.315 48.8619 187.414 51.5566 187.788C48.8619 187.431 46.6755 184.936 46.6755 182.238Z" fill="#43AEFC"/>
|
||||
<path d="M0 160.577L24.6089 164.107V139.465L0 135.935V160.577Z" fill="#43AEFC"/>
|
||||
<path d="M40.9979 154.672L24.6089 164.107V139.466L40.9979 130.03V154.672Z" fill="#037DD6"/>
|
||||
<path d="M16.389 126.5L0 135.936L24.6089 139.466L40.9979 130.03L16.389 126.5Z" fill="#75C4FD"/>
|
||||
<path d="M12.6434 151.89L11.9485 151.788C7.60971 151.16 4.08447 153.196 4.08447 156.353L20.5074 158.763C20.5074 155.589 16.9991 152.518 12.6434 151.89Z" fill="white"/>
|
||||
<path d="M15.465 149.628C17.0898 148.115 16.9912 145.364 15.2449 143.483C13.4986 141.602 10.7658 141.304 9.14108 142.816C7.51634 144.329 7.61488 147.08 9.3612 148.96C11.1075 150.841 13.8403 151.14 15.465 149.628Z" fill="white"/>
|
||||
<path d="M92.9443 181.859L118.858 185.576V159.645L92.9443 155.911V181.859Z" fill="#43AEFC"/>
|
||||
<path d="M136.112 175.63L118.858 185.575V159.644L136.112 149.699V175.63Z" fill="#037DD6"/>
|
||||
<path d="M110.198 145.982L92.9443 155.91L118.858 159.643L136.112 149.698L110.198 145.982Z" fill="#75C4FD"/>
|
||||
<path d="M108.588 164.734L103.215 163.987C99.8762 163.529 97.1814 165.854 97.1814 169.197V172.727V173.372C97.1814 174.882 98.4017 176.274 99.9101 176.494C101.418 176.698 102.639 175.646 102.639 174.135V173.49L109.147 174.39V175.035C109.147 176.545 110.367 177.937 111.876 178.157C113.384 178.361 114.604 177.309 114.604 175.798V175.154V171.624C114.621 168.28 111.926 165.192 108.588 164.734Z" fill="white"/>
|
||||
<path d="M102.011 170.757L100.723 170.57V166.225L102.011 166.412V170.757Z" fill="#43AEFC"/>
|
||||
<path d="M103.537 169.432L99.1982 168.838V167.549L103.537 168.143V169.432Z" fill="#43AEFC"/>
|
||||
<path d="M113.014 170.58C113.281 170.33 113.27 169.884 112.989 169.582C112.708 169.281 112.264 169.238 111.997 169.488C111.73 169.737 111.741 170.184 112.022 170.485C112.304 170.787 112.748 170.829 113.014 170.58Z" fill="#43AEFC"/>
|
||||
<path d="M110.092 170.184C110.359 169.935 110.347 169.488 110.066 169.187C109.785 168.885 109.341 168.843 109.074 169.092C108.807 169.342 108.819 169.788 109.1 170.09C109.381 170.391 109.825 170.433 110.092 170.184Z" fill="#43AEFC"/>
|
||||
<path d="M111.625 168.877C111.892 168.628 111.881 168.181 111.6 167.88C111.319 167.578 110.875 167.536 110.608 167.785C110.341 168.035 110.352 168.481 110.633 168.783C110.914 169.084 111.358 169.127 111.625 168.877Z" fill="#43AEFC"/>
|
||||
<path d="M111.628 171.897C111.895 171.648 111.883 171.201 111.602 170.9C111.321 170.598 110.877 170.556 110.61 170.806C110.344 171.055 110.355 171.502 110.636 171.803C110.917 172.105 111.361 172.147 111.628 171.897Z" fill="#43AEFC"/>
|
||||
<path d="M105.3 171.691L104.232 171.538C104.096 171.521 103.995 171.402 103.995 171.266C103.995 171.131 104.096 171.046 104.232 171.063L105.3 171.216C105.435 171.233 105.537 171.351 105.537 171.487C105.537 171.606 105.435 171.708 105.3 171.691Z" fill="#43AEFC"/>
|
||||
<path d="M108.13 172.078L107.062 171.926C106.927 171.909 106.825 171.79 106.825 171.654C106.825 171.518 106.927 171.433 107.062 171.45L108.13 171.603C108.266 171.62 108.367 171.739 108.367 171.875C108.367 171.993 108.266 172.095 108.13 172.078Z" fill="#43AEFC"/>
|
||||
<path d="M193.973 156.383L182.906 163.12V133.88L193.973 127.058V156.383Z" fill="#037DD6"/>
|
||||
<path d="M163.941 127.058L151.247 133.88H182.906L193.973 127.058H163.941Z" fill="#75C4FD"/>
|
||||
<path d="M182.889 133.882H151.247V163.241H182.889V133.882Z" fill="#43AEFC"/>
|
||||
<path d="M161.941 141.093V155.535L173.754 148.305L161.941 141.093Z" fill="white"/>
|
||||
<path d="M253.495 166.681L227.598 170.415V144.467L253.495 140.75V166.681Z" fill="#037DD6"/>
|
||||
<path d="M210.345 160.473L227.598 170.418V144.47L210.345 134.542V160.473Z" fill="#43AEFC"/>
|
||||
<path d="M236.242 130.807L253.495 140.752L227.598 144.469L210.345 134.541L236.242 130.807Z" fill="#75C4FD"/>
|
||||
<path d="M245.292 161.849L233.835 156.86L245.292 147.865L245.987 148.884L236.411 156.402L245.987 160.576L245.292 161.849Z" fill="white"/>
|
||||
<path d="M247.312 149.908C248.324 148.803 248.395 147.218 247.47 146.37C246.545 145.521 244.975 145.729 243.963 146.835C242.951 147.94 242.881 149.525 243.805 150.373C244.73 151.222 246.3 151.014 247.312 149.908Z" fill="white"/>
|
||||
<path d="M247.311 162.823C248.323 161.718 248.394 160.134 247.469 159.285C246.545 158.436 244.975 158.645 243.963 159.75C242.951 160.856 242.88 162.44 243.805 163.288C244.729 164.137 246.299 163.929 247.311 162.823Z" fill="white"/>
|
||||
<path d="M236.38 158.24C237.392 157.135 237.462 155.55 236.538 154.702C235.613 153.853 234.043 154.061 233.031 155.167C232.019 156.272 231.949 157.857 232.873 158.705C233.798 159.554 235.368 159.346 236.38 158.24Z" fill="white"/>
|
||||
<path d="M271.206 172.169C269.8 176.005 266.529 178.873 262.986 180.757C258.631 183.065 253.597 183.794 248.784 184.558C243.801 185.356 238.089 188.461 233.276 189.972C228.446 191.482 223.734 193.383 219.209 195.623C217.429 196.505 215.718 197.625 213.701 197.897C211.887 198.151 209.955 197.523 209.311 195.657C208.989 194.774 209.311 192.364 213.091 190.566C218.446 188.02 221.955 186.696 227.7 185.152C227.751 185.135 227.802 185.118 227.853 185.101C230.666 184.015 233.479 182.929 236.293 181.86C241.123 180.01 246.072 178.364 250.75 176.141C252.241 175.428 253.665 174.63 255.004 173.714C255.038 173.697 255.055 173.68 255.089 173.663C256.156 172.984 257.885 171.338 259.207 170.031C260.376 168.877 261.359 167.553 262.122 166.094C262.749 164.906 263.495 163.464 263.969 162.496C264.02 162.462 264.071 162.428 264.122 162.394C265.054 161.902 266.139 161.733 267.257 161.953C271.969 162.903 272.613 168.351 271.206 172.169Z" fill="url(#paint12_linear_6966_12826)"/>
|
||||
<path d="M213.091 200.663C212.243 199.186 210.532 199.645 209.227 200.12C208.667 200.323 208.125 200.544 207.583 200.799C205.667 201.291 203.871 202.156 202.227 203.31C201.176 204.04 199.769 205.228 200.702 206.62C201.363 207.604 202.752 207.638 203.803 207.4C205.295 207.078 206.786 206.569 208.21 206.009C209.549 205.483 211.074 204.973 212.209 204.057C213.209 203.276 213.786 201.868 213.091 200.663Z" fill="url(#paint13_linear_6966_12826)"/>
|
||||
<path d="M213.667 2.46215C211.87 0.663266 209.057 -0.134352 206.65 0.0183837C205.718 0.086266 204.582 0.408707 204.125 1.52877C202.989 4.41376 206.328 4.41376 205.921 6.94238C205.769 7.9097 205.159 8.72429 204.532 9.38614C199.684 14.4264 193.6 15.7841 187.651 17.7357C187.363 17.8205 187.075 17.9223 186.787 18.0072C186.753 18.0242 186.719 18.0242 186.702 18.0411C184.397 18.9236 181.177 19.4667 179.923 22.3008C178.499 25.5252 180.279 28.8005 182.668 30.1072C185.329 31.5667 188.566 31.4479 191.515 30.9218C194.075 30.4806 196.634 29.683 199.074 28.529C206.243 25.2027 223.751 12.5936 213.667 2.46215Z" fill="url(#paint14_linear_6966_12826)"/>
|
||||
<path d="M199.414 4.1767C198.092 1.34261 193.719 1.51232 191.346 2.70026C189.753 3.49788 188.041 5.02523 187.567 6.84108C186.719 8.11388 186.397 9.52243 187.262 10.8971C188.889 13.4766 192.414 12.5941 194.821 11.2874C197.719 10.2522 200.837 7.23141 199.414 4.1767Z" fill="url(#paint15_linear_6966_12826)"/>
|
||||
<path d="M110.757 105.898L113.215 105.66L112.249 103.081L110.486 103.251L110.757 105.898Z" fill="#B77B6A"/>
|
||||
<path d="M111.995 97.1218C112.639 97.3933 113.198 98.191 113.605 98.768C114.011 99.345 114.316 99.9729 114.621 100.601C114.842 101.076 115.045 101.585 114.994 102.111C114.944 102.756 114.503 103.316 113.961 103.655C112.656 104.47 110.808 104.012 109.842 102.824C108.91 101.67 108.876 100.16 109.13 98.768C109.368 97.5121 110.842 96.6297 111.995 97.1218Z" fill="#B77B6A"/>
|
||||
<path d="M109.757 104.42C110.689 105.048 110.91 103.86 110.74 102.791C111.045 101.892 109.842 100.958 110.673 100.178C111.045 99.8724 111.537 99.7536 111.91 99.4481C112.283 99.1426 112.639 98.1414 112.639 97.6492C112.977 98.0565 113.367 98.8541 113.825 99.1256C113.689 98.1074 113.079 97.1061 112.164 96.6479C111.249 96.1728 110.113 96.1897 109.215 96.6649C108.571 97.0043 108.046 97.5644 107.418 97.9207C106.927 98.1923 106.351 98.345 105.791 98.345C105.063 98.345 104.317 98.1074 103.605 98.2092C102.792 98.328 102.097 98.8711 101.3 99.1426C100.487 99.4142 99.5714 99.3972 98.7917 99.0747C98.3002 100.161 98.4697 101.502 99.046 102.537C99.8086 103.894 101.368 104.743 101.842 106.219C102.114 107.068 101.995 108.052 102.419 108.85C102.825 109.613 103.622 110.038 104.402 110.411L109.757 104.42Z" fill="#2E3446"/>
|
||||
<path d="M110.469 102.843L110.995 102.741L110.757 101.757C110.656 101.35 110.232 101.095 109.825 101.214L109.757 101.231C109.351 101.333 109.181 101.825 109.435 102.164L109.69 102.521C109.859 102.775 110.164 102.894 110.469 102.843Z" fill="#B77B6A"/>
|
||||
<path d="M114.266 101.264C114.266 101.264 113.367 102.163 112.859 102.027C112.859 102.027 113.605 102.876 114.333 101.96L114.266 101.264Z" fill="white"/>
|
||||
<path d="M125.366 99.7697C125.587 99.4303 125.688 98.8533 125.722 98.6326C125.756 98.412 125.841 98.0217 126.282 97.7332C126.722 97.4447 126.536 97.8011 126.485 98.0387C126.434 98.2763 126.655 98.5478 126.604 98.8702C126.553 99.1927 126.129 100.007 125.79 100.126C125.451 100.245 125.366 99.7697 125.366 99.7697Z" fill="#E88F97"/>
|
||||
<path d="M126.214 98.5327C126.638 98.1594 127.316 97.4975 127.807 97.1411C128.502 96.632 128.417 96.9205 127.909 97.5654C127.587 97.9727 127.367 98.2781 127.367 98.2781L127.468 98.3291C127.468 98.3291 127.858 98.0745 128.214 97.8369C128.57 97.5993 128.824 97.4975 129.061 97.4466C129.299 97.3957 129.197 98.1254 129.129 98.4818C129.061 98.8382 128.146 100.009 127.909 100.145C127.672 100.281 127.451 100.433 126.706 100.62C125.723 101.044 125.485 100.111 125.485 100.111L126.214 98.5327Z" fill="#E88F97"/>
|
||||
<path d="M113.452 105.557L113.74 104.454L112.401 104.522L113.452 105.557Z" fill="#FFD33D"/>
|
||||
<path d="M96.1477 108.51C96.1477 108.51 95.9274 108.731 95.8596 108.884C95.7918 109.036 95.7918 109.715 95.4529 109.885C95.097 110.055 94.6732 110.123 94.5377 110.123C94.4021 110.123 94.2326 109.919 94.1648 109.885C94.097 109.851 93.7072 110.004 93.4191 109.766C93.1309 109.529 93.1648 109.036 93.2665 108.408C93.3682 107.781 93.3513 107.594 94.0123 107.305C94.6732 107.017 95.7579 106.644 95.7579 106.644L96.1477 108.51Z" fill="#E88F97"/>
|
||||
<path d="M111.011 106.187L113.537 105.932L112.554 103.285L110.74 103.472L111.011 106.187Z" fill="#E88F97"/>
|
||||
<path d="M112.282 97.1575C112.943 97.446 113.52 98.2605 113.943 98.8545C114.35 99.4485 114.672 100.076 114.977 100.738C115.214 101.23 115.418 101.756 115.367 102.283C115.299 102.944 114.858 103.521 114.299 103.878C112.96 104.709 111.062 104.251 110.062 103.029C109.096 101.841 109.079 100.297 109.333 98.8545C109.588 97.5647 111.113 96.6483 112.282 97.1575Z" fill="#E88F97"/>
|
||||
<path d="M109.706 105.286L110.74 105.15C111.706 105.795 111.164 104.081 110.994 102.995C111.316 102.079 110.062 101.111 110.927 100.314C111.299 99.9912 111.808 99.8724 112.198 99.5669C112.587 99.2614 112.943 98.2093 112.96 97.7171C113.299 98.1414 113.706 98.956 114.181 99.2445C114.045 98.2093 113.418 97.1741 112.469 96.6989C111.537 96.2237 110.367 96.2237 109.435 96.7159C109.35 96.7668 109.283 96.8007 109.215 96.8516C109.215 96.8516 109.198 96.8516 109.198 96.8686C106.961 98.4299 105.469 103.419 109.706 105.286Z" fill="#2E3446"/>
|
||||
<path d="M110.723 103.03L111.266 102.928L111.011 101.926C110.91 101.502 110.486 101.248 110.062 101.366L109.995 101.383C109.571 101.502 109.401 101.994 109.656 102.351L109.927 102.707C110.096 102.962 110.418 103.097 110.723 103.03Z" fill="#E88F97"/>
|
||||
<path d="M114.621 101.418C114.621 101.418 113.706 102.351 113.164 102.198C113.164 102.198 113.943 103.081 114.689 102.13L114.621 101.418Z" fill="white"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M95.2097 106.836C101.569 103.688 108.682 104.905 112.69 105.773L112.281 107.688C108.291 106.825 101.777 105.768 96.0688 108.594L95.2097 106.836Z" fill="#FFD33D"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M115.476 107.644C114.516 107.617 113.595 107.591 112.594 107.704L112.377 105.757C113.524 105.628 114.591 105.658 115.545 105.686C115.693 105.69 115.838 105.694 115.981 105.697C117.067 105.724 118.007 105.712 118.948 105.475C120.758 105.019 122.836 103.655 125.648 99.2283L127.288 100.284C124.355 104.902 121.924 106.745 119.421 107.376C118.205 107.682 117.037 107.683 115.934 107.656C115.78 107.652 115.627 107.648 115.476 107.644Z" fill="#FFD33D"/>
|
||||
<path d="M113.231 105.102C113.231 105.102 120.892 116.32 117.384 128.64C117.384 128.64 102.198 132.119 94.9104 114.3L110.74 105.153L113.231 105.102Z" fill="#FFD33D"/>
|
||||
<path d="M120.163 139.634C120.163 139.634 118.773 145.354 118.757 146.762C118.74 148.171 121.248 152.43 121.248 152.43L114.536 149.002L116.35 139.312L120.163 139.634Z" fill="#FFD33D"/>
|
||||
<path d="M109.656 113.723L111.401 115.115C119.316 121.411 122.994 131.78 120.791 141.521L114.621 139.994C115.909 134.359 116.537 126.383 110.028 120.155L108.808 119.035C107.808 118.102 107.537 116.608 108.181 115.403L109.656 113.723Z" fill="#2E3446"/>
|
||||
<path d="M89.1311 120.355C89.1311 120.355 85.1483 116.027 83.9619 115.23C82.7755 114.432 77.8774 114.178 77.8774 114.178L84.4534 110.478L91.5208 117.351L89.1311 120.355Z" fill="#FFD33D"/>
|
||||
<path d="M108.164 115.401C108.13 115.452 105.503 120.798 100.334 120.882C97.8085 120.916 94.7917 118.795 92.5376 116.063L87.6565 120.085C90.8767 123.971 94.5714 125.906 98.6051 125.838C103.825 125.753 108.13 122.24 110.333 120.034C112.096 118.337 112.977 116.114 112.977 116.114L108.164 115.401Z" fill="#2E3446"/>
|
||||
<path d="M112.791 105.387C112.791 105.387 116.333 113.533 114.876 118.437L107.435 116.418L112.791 105.387Z" fill="#F66A0A"/>
|
||||
<path d="M103.317 99.9914C103.741 98.0568 106.961 98.3962 108.978 100.178L108.893 102.418C103.859 104.624 102.876 101.926 103.317 99.9914Z" fill="#2E3446"/>
|
||||
<path d="M112.791 105.386C112.774 105.353 112.096 103.944 112.096 103.944L110.486 104.47L110.689 105.403L112.791 105.386Z" fill="#FFD33D"/>
|
||||
<path d="M112.859 106.151C113.186 106.151 113.452 105.885 113.452 105.557C113.452 105.229 113.186 104.963 112.859 104.963C112.531 104.963 112.266 105.229 112.266 105.557C112.266 105.885 112.531 106.151 112.859 106.151Z" fill="#2E3446"/>
|
||||
<path d="M311.696 145.492L283.409 149.548V121.241L311.696 117.168V145.492Z" fill="#037DD6"/>
|
||||
<path d="M264.58 138.686L283.409 149.547V121.24L264.58 110.379V138.686Z" fill="#43AEFC"/>
|
||||
<path d="M292.849 106.321L311.696 117.165L283.409 121.238L264.58 110.377L292.849 106.321Z" fill="#75C4FD"/>
|
||||
<path d="M297.544 123.665C293.815 124.191 290.781 127.636 290.781 131.37C290.781 135.103 297.544 143.045 297.544 143.045C297.544 143.045 304.306 133.22 304.306 129.486C304.306 125.753 301.289 123.139 297.544 123.665ZM297.544 132.592C295.951 132.812 294.663 131.709 294.663 130.114C294.663 128.519 295.951 127.042 297.544 126.822C299.137 126.601 300.425 127.704 300.425 129.299C300.425 130.895 299.137 132.354 297.544 132.592Z" fill="white"/>
|
||||
<path d="M136.095 199.204C134.722 198.966 133.434 199.407 132.146 199.832C130.485 200.392 128.807 200.867 127.112 201.274C123.807 202.072 120.417 202.462 117.028 202.615C113.18 202.785 109.299 202.632 105.486 202.14C102.689 201.783 99.893 201.461 97.4016 202.615C96.4186 202.988 95.5542 203.548 95.3339 204.583C95.1474 205.5 95.6051 206.331 96.4186 206.756C96.8931 206.993 97.4185 207.078 97.8931 207.333C98.1812 207.485 98.3676 207.757 98.4185 208.062C98.4524 208.215 98.4863 208.351 98.5371 208.487C98.8591 209.386 99.6387 210.082 100.452 210.523C102.91 211.881 106.045 211.609 108.74 211.423C114.774 211.015 120.705 210.099 126.553 208.555C128.264 208.096 129.959 207.604 131.637 207.044C133.146 206.535 134.79 206.06 136.196 205.296C137.4 204.634 138.603 203.48 138.603 202.021C138.586 200.578 137.467 199.441 136.095 199.204Z" fill="url(#paint16_linear_6966_12826)"/>
|
||||
<path d="M86.6904 190.141C84.8769 189.48 82.8431 188.852 80.8093 188.614C80.4195 188.563 80.0128 188.614 79.6738 188.801C79.4535 188.92 79.2501 189.089 79.0976 189.327C78.9111 189.615 78.7925 189.938 78.7247 190.277C78.7078 192.704 81.0127 194.673 82.877 196.047C84.0465 196.913 85.3515 197.846 86.809 198.084C87.6056 198.219 88.5717 198.084 89.1818 197.558C90.3173 197.116 91.6054 196.522 92.0969 195.334C93.3172 192.382 88.6395 190.854 86.6904 190.141Z" fill="url(#paint17_linear_6966_12826)"/>
|
||||
<path d="M119.994 215.851C119.909 215.563 119.723 215.376 119.452 215.257C119.435 215.24 119.418 215.223 119.384 215.206C119.282 215.155 119.18 215.105 119.079 215.071C118.994 214.952 118.841 214.867 118.655 214.867C117.553 214.867 115.723 214.663 114.909 215.614C114.537 216.055 114.537 216.717 114.977 217.124C115.452 217.548 116.214 217.565 116.808 217.548C117.638 217.497 120.401 217.192 119.994 215.851Z" fill="url(#paint18_linear_6966_12826)"/>
|
||||
<path d="M294.68 42.6129C295.7 42.6129 296.527 41.7847 296.527 40.7631C296.527 39.7415 295.7 38.9133 294.68 38.9133C293.659 38.9133 292.832 39.7415 292.832 40.7631C292.832 41.7847 293.659 42.6129 294.68 42.6129Z" fill="url(#paint19_linear_6966_12826)"/>
|
||||
<path d="M46.7434 149.718C47.7636 149.718 48.5907 148.89 48.5907 147.868C48.5907 146.847 47.7636 146.019 46.7434 146.019C45.7231 146.019 44.896 146.847 44.896 147.868C44.896 148.89 45.7231 149.718 46.7434 149.718Z" fill="url(#paint20_linear_6966_12826)"/>
|
||||
<path d="M159.704 188.392C160.724 188.392 161.551 187.563 161.551 186.542C161.551 185.52 160.724 184.692 159.704 184.692C158.684 184.692 157.856 185.52 157.856 186.542C157.856 187.563 158.684 188.392 159.704 188.392Z" fill="url(#paint21_linear_6966_12826)"/>
|
||||
<path d="M17.0329 175.918C18.0532 175.918 18.8803 175.09 18.8803 174.069C18.8803 173.047 18.0532 172.219 17.0329 172.219C16.0126 172.219 15.1855 173.047 15.1855 174.069C15.1855 175.09 16.0126 175.918 17.0329 175.918Z" fill="url(#paint22_linear_6966_12826)"/>
|
||||
<path d="M279.02 101.607C280.04 101.607 280.867 100.779 280.867 99.7571C280.867 98.7355 280.04 97.9073 279.02 97.9073C277.999 97.9073 277.172 98.7355 277.172 99.7571C277.172 100.779 277.999 101.607 279.02 101.607Z" fill="url(#paint23_linear_6966_12826)"/>
|
||||
<path d="M274.799 153.113C275.82 153.113 276.647 152.285 276.647 151.264C276.647 150.242 275.82 149.414 274.799 149.414C273.779 149.414 272.952 150.242 272.952 151.264C272.952 152.285 273.779 153.113 274.799 153.113Z" fill="url(#paint24_linear_6966_12826)"/>
|
||||
<path d="M328 95.5088L301.154 99.3781V72.4798L328 68.6274V95.5088Z" fill="#037DD6"/>
|
||||
<path d="M283.257 89.0627L301.154 99.3809V72.4825L283.257 62.1644V89.0627Z" fill="#43AEFC"/>
|
||||
<path d="M310.12 58.3107L328 68.6118L301.154 72.4811L283.257 62.163L310.12 58.3107Z" fill="#75C4FD"/>
|
||||
<path d="M320.356 84.2271C320.39 83.9725 320.407 83.701 320.407 83.4464C320.407 83.1749 320.39 82.9203 320.339 82.6658L322.034 81.1045C322.187 80.9687 322.221 80.7311 322.136 80.5784L320.543 78.0328C320.441 77.8631 320.238 77.8291 320.051 77.931L318.068 79.0171C317.645 78.7625 317.204 78.5589 316.712 78.4231L316.407 76.3357C316.373 76.1321 316.204 76.0303 316.001 76.0472L312.797 76.5054C312.594 76.5394 312.441 76.6921 312.408 76.8958L312.102 79.068C311.611 79.3395 311.17 79.6789 310.747 80.0353L308.764 79.5262C308.577 79.4753 308.374 79.5771 308.272 79.7808L306.679 82.7846C306.577 82.9712 306.611 83.1919 306.781 83.2767L308.476 84.3628C308.442 84.6174 308.408 84.8889 308.408 85.1604C308.408 85.432 308.425 85.6865 308.476 85.9411L306.781 87.5024C306.628 87.6381 306.594 87.8757 306.679 88.0285L308.272 90.5741C308.374 90.7438 308.577 90.7777 308.764 90.6759L310.747 89.5898C311.17 89.8443 311.611 90.048 312.102 90.1837L312.408 92.2711C312.441 92.4578 312.611 92.5766 312.814 92.5596L316.018 92.1014C316.221 92.0675 316.39 91.9147 316.407 91.7111L316.712 89.5388C317.204 89.2673 317.645 88.9279 318.068 88.5715L320.051 89.0806C320.238 89.1316 320.441 89.0297 320.543 88.8261L322.136 85.8223C322.238 85.6356 322.204 85.415 322.034 85.3301L320.356 84.2271ZM314.39 87.2987C312.746 87.5363 311.391 86.3823 311.391 84.7192C311.391 83.0561 312.746 81.5287 314.39 81.2911C316.034 81.0536 317.39 82.2076 317.39 83.8707C317.39 85.5338 316.051 87.0611 314.39 87.2987Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_6966_12826" x1="159.628" y1="107.412" x2="223.004" y2="242.728" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.0101602" stop-color="#F2F2F2"/>
|
||||
<stop offset="0.9999" stop-color="#CCCCCC"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_6966_12826" x1="88.7838" y1="52.5761" x2="204.486" y2="300.54" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E6E6E6"/>
|
||||
<stop offset="1" stop-color="#808080"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_6966_12826" x1="41.7906" y1="74.5032" x2="157.493" y2="322.467" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E6E6E6"/>
|
||||
<stop offset="1" stop-color="#808080"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_6966_12826" x1="165.179" y1="189.093" x2="223.556" y2="226.144" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E6E6E6"/>
|
||||
<stop offset="1" stop-color="#808080"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_6966_12826" x1="167.632" y1="15.7845" x2="283.334" y2="263.748" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E6E6E6"/>
|
||||
<stop offset="1" stop-color="#808080"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_6966_12826" x1="195.362" y1="2.84379" x2="311.064" y2="250.808" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E6E6E6"/>
|
||||
<stop offset="1" stop-color="#808080"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint6_linear_6966_12826" x1="217.002" y1="-7.25108" x2="332.704" y2="240.713" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E6E6E6"/>
|
||||
<stop offset="1" stop-color="#808080"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint7_linear_6966_12826" x1="45.9648" y1="131.68" x2="270.909" y2="52.869" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint8_linear_6966_12826" x1="141.1" y1="63.3402" x2="244.334" y2="63.3402" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE566"/>
|
||||
<stop offset="1" stop-color="#FFB0EB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint9_linear_6966_12826" x1="141.1" y1="82.879" x2="244.334" y2="82.879" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE566"/>
|
||||
<stop offset="1" stop-color="#FFB0EB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint10_linear_6966_12826" x1="75.3517" y1="65.4367" x2="81.8393" y2="39.5203" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE566"/>
|
||||
<stop offset="1" stop-color="#FFB0EB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint11_linear_6966_12826" x1="75.3517" y1="65.4367" x2="81.8393" y2="39.5203" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE566"/>
|
||||
<stop offset="1" stop-color="#FFB0EB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint12_linear_6966_12826" x1="297.367" y1="147.49" x2="230.403" y2="190.447" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE566"/>
|
||||
<stop offset="1" stop-color="#FFB0EB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint13_linear_6966_12826" x1="64.1903" y1="239.535" x2="167.607" y2="213.599" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE566"/>
|
||||
<stop offset="1" stop-color="#FFB0EB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint14_linear_6966_12826" x1="65.5451" y1="67.577" x2="225.504" y2="5.57676" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE566"/>
|
||||
<stop offset="1" stop-color="#FFB0EB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint15_linear_6966_12826" x1="61.8447" y1="58.0293" x2="221.803" y2="-3.97067" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE566"/>
|
||||
<stop offset="1" stop-color="#FFB0EB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint16_linear_6966_12826" x1="59.0001" y1="218.838" x2="162.416" y2="192.903" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE566"/>
|
||||
<stop offset="1" stop-color="#FFB0EB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint17_linear_6966_12826" x1="54.4732" y1="200.787" x2="157.889" y2="174.851" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE566"/>
|
||||
<stop offset="1" stop-color="#FFB0EB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint18_linear_6966_12826" x1="61.8207" y1="230.084" x2="165.237" y2="204.148" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE566"/>
|
||||
<stop offset="1" stop-color="#FFB0EB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint19_linear_6966_12826" x1="292.818" y1="40.76" x2="296.527" y2="40.76" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#75C4FD"/>
|
||||
<stop offset="1" stop-color="#75C4FD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint20_linear_6966_12826" x1="44.896" y1="147.861" x2="48.6052" y2="147.861" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#75C4FD"/>
|
||||
<stop offset="1" stop-color="#75C4FD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint21_linear_6966_12826" x1="157.852" y1="186.54" x2="161.562" y2="186.54" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#75C4FD"/>
|
||||
<stop offset="1" stop-color="#75C4FD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint22_linear_6966_12826" x1="15.1708" y1="174.073" x2="18.88" y2="174.073" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#75C4FD"/>
|
||||
<stop offset="1" stop-color="#75C4FD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint23_linear_6966_12826" x1="277.168" y1="99.7566" x2="280.878" y2="99.7566" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#75C4FD"/>
|
||||
<stop offset="1" stop-color="#75C4FD"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint24_linear_6966_12826" x1="272.938" y1="151.261" x2="276.647" y2="151.261" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#75C4FD"/>
|
||||
<stop offset="1" stop-color="#75C4FD"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 51 KiB |
19
app/images/snap-account-page.svg
Normal file
19
app/images/snap-account-page.svg
Normal file
@ -0,0 +1,19 @@
|
||||
<svg width="1024" height="606" viewBox="0 0 1024 606" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g style="mix-blend-mode:multiply" opacity="0.1">
|
||||
<path d="M423.504 537.172C403.6 534.714 382.471 538.401 364.404 529.183C327.352 510.439 329.801 451.135 294.893 428.396C275.907 415.798 250.185 418.256 229.974 428.704C209.764 439.151 194.453 456.973 180.367 474.795C149.133 515.048 122.492 559.296 101.669 606.001L498.834 606.001C489.035 571.587 459.332 541.781 423.504 537.172Z" fill="#666666"/>
|
||||
<path d="M0.00689697 606.001L0.00691613 386.914C56.351 345.125 112.695 303.028 171.183 263.39C210.991 236.349 251.412 210.538 293.67 186.571C348.789 155.229 425.344 153.078 463.621 207.466C485.669 238.501 489.956 280.597 500.98 318.392C512.003 356.187 536.501 395.518 571.716 396.44C604.175 397.362 629.591 365.405 645.821 333.448C661.744 301.492 674.605 265.233 701.552 244.646C734.318 219.757 779.638 226.21 813.322 249.255C821.896 255.093 829.858 261.853 837.207 269.535C858.948 291.352 876.403 319.007 892.633 346.354C922.03 396.44 926.317 426.246 952.958 478.175C975.311 521.501 997.665 565.441 1024 605.694L498.53 605.694C488.731 571.279 459.334 541.474 423.2 536.865C403.296 534.406 382.167 538.094 364.406 528.875C327.354 510.132 329.498 450.827 294.895 428.089C275.909 415.491 250.187 417.949 229.977 428.396C209.766 438.844 194.455 456.666 180.369 474.488C149.135 514.741 122.494 558.988 101.671 605.694L0.006897 605.694L0.00689697 606.001Z" fill="url(#paint0_linear_6094_102467)"/>
|
||||
<path d="M171.483 263.436C187.1 250.838 202.104 238.24 215.578 225.334C273.147 170.332 327.96 112.257 379.405 51.4166C405.433 20.6892 445.854 -14.0328 480.457 6.86188C491.787 13.9292 499.442 25.9129 504.648 38.2039C516.284 65.8586 518.734 95.9715 523.633 125.47C528.533 154.968 537.107 185.388 557.93 206.898C578.753 228.407 614.886 237.318 638.771 219.496C658.982 204.439 664.494 176.785 680.723 157.426C705.221 127.928 752.072 124.241 784.837 143.906C817.603 163.572 835.976 201.981 838.732 240.083C839.344 250.223 839.038 260.363 838.119 270.196C830.77 262.822 822.808 256.062 814.234 249.916C780.55 226.87 735.23 220.418 702.465 245.307C675.517 265.894 662.656 302.153 646.733 334.109C630.81 366.066 605.087 398.022 572.628 397.1C537.413 396.179 512.916 356.848 501.892 319.053C490.868 281.258 486.581 239.469 464.533 208.127C426.256 153.432 349.702 155.583 294.582 187.232C251.712 210.585 210.985 236.396 171.483 263.436Z" fill="url(#paint1_linear_6094_102467)"/>
|
||||
<path d="M916.744 22.243C899.228 28.0088 899.857 78.0428 918.149 133.997C936.441 189.952 965.469 230.638 982.985 224.872C1000.5 219.106 999.872 169.072 981.58 113.118C963.288 57.1633 934.26 16.4773 916.744 22.243Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_6094_102467" x1="1024.16" y1="385.234" x2="0.133924" y2="385.234" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFE566"/>
|
||||
<stop offset="1" stop-color="#FFB0EB"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_6094_102467" x1="838.416" y1="198.467" x2="171.367" y2="198.467" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#75C4FD"/>
|
||||
<stop offset="0.1001" stop-color="#82C3F7"/>
|
||||
<stop offset="1" stop-color="#F1B9BE"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
@ -1,8 +1,8 @@
|
||||
import { endowmentPermissionBuilders } from '@metamask/snaps-controllers';
|
||||
import {
|
||||
restrictedMethodPermissionBuilders,
|
||||
selectHooks,
|
||||
} from '@metamask/rpc-methods';
|
||||
import { endowmentPermissionBuilders } from '@metamask/snaps-controllers';
|
||||
import {
|
||||
ExcludedSnapEndowments,
|
||||
ExcludedSnapPermissions,
|
||||
|
@ -4,6 +4,9 @@ import { IPFS_DEFAULT_GATEWAY_URL } from '../../../shared/constants/network';
|
||||
import { LedgerTransportTypes } from '../../../shared/constants/hardware-wallets';
|
||||
import { ThemeType } from '../../../shared/constants/preferences';
|
||||
import { shouldShowLineaMainnet } from '../../../shared/modules/network.utils';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
import { KEYRING_SNAPS_REGISTRY_URL } from '../../../shared/constants/app';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
export default class PreferencesController {
|
||||
/**
|
||||
@ -65,8 +68,12 @@ export default class PreferencesController {
|
||||
ledgerTransportType: window.navigator.hid
|
||||
? LedgerTransportTypes.webhid
|
||||
: LedgerTransportTypes.u2f,
|
||||
snapRegistryList: {},
|
||||
transactionSecurityCheckEnabled: false,
|
||||
theme: ThemeType.os,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
snapsAddSnapAccountModalDismissed: false,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
isLineaMainnetReleased: false,
|
||||
...opts.initState,
|
||||
};
|
||||
@ -511,6 +518,23 @@ export default class PreferencesController {
|
||||
return this.store.getState().disabledRpcMethodPreferences;
|
||||
}
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
setSnapsAddSnapAccountModalDismissed(value) {
|
||||
this.store.updateState({ snapsAddSnapAccountModalDismissed: value });
|
||||
}
|
||||
|
||||
async updateSnapRegistry() {
|
||||
let snapRegistry;
|
||||
try {
|
||||
snapRegistry = await fetch(KEYRING_SNAPS_REGISTRY_URL);
|
||||
} catch (error) {
|
||||
console.error(`Failed to fetch registry: `, error);
|
||||
snapRegistry = {};
|
||||
}
|
||||
this.store.updateState({ snapRegistryList: snapRegistry });
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
//
|
||||
// PRIVATE METHODS
|
||||
//
|
||||
|
@ -49,13 +49,12 @@ import {
|
||||
SubjectMetadataController,
|
||||
SubjectType,
|
||||
} from '@metamask/subject-metadata-controller';
|
||||
import SmartTransactionsController from '@metamask/smart-transactions-controller';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
import { encrypt, decrypt } from '@metamask/browser-passworder';
|
||||
import { RateLimitController } from '@metamask/rate-limit-controller';
|
||||
import { NotificationController } from '@metamask/notification-controller';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import SmartTransactionsController from '@metamask/smart-transactions-controller';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
|
||||
import {
|
||||
CronjobController,
|
||||
JsonSnapsRegistry,
|
||||
@ -63,6 +62,9 @@ import {
|
||||
IframeExecutionService,
|
||||
} from '@metamask/snaps-controllers';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
import { SnapKeyring } from '@metamask/eth-snap-keyring';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
import {
|
||||
@ -772,6 +774,16 @@ export default class MetamaskController extends EventEmitter {
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
}
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
additionalKeyrings.push(
|
||||
(() => {
|
||||
const builder = () => new SnapKeyring(this.snapController);
|
||||
builder.type = SnapKeyring.type;
|
||||
return builder;
|
||||
})(),
|
||||
);
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
this.keyringController = new KeyringController({
|
||||
keyringBuilders: additionalKeyrings,
|
||||
initState: initState.KeyringController,
|
||||
@ -1679,7 +1691,28 @@ export default class MetamaskController extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
/**
|
||||
* Initialize the snap keyring if it is not present.
|
||||
*/
|
||||
async getSnapKeyring() {
|
||||
if (!this.snapKeyring) {
|
||||
let [snapKeyring] = this.keyringController.getKeyringsByType(
|
||||
KeyringType.snap,
|
||||
);
|
||||
if (!snapKeyring) {
|
||||
snapKeyring = await this.keyringController.addNewKeyring(
|
||||
KeyringType.snap,
|
||||
);
|
||||
}
|
||||
this.snapKeyring = snapKeyring;
|
||||
}
|
||||
return this.snapKeyring;
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
|
||||
/**
|
||||
* Constructor helper for getting Snap permission specifications.
|
||||
*/
|
||||
@ -1735,6 +1768,16 @@ export default class MetamaskController extends EventEmitter {
|
||||
this.controllerMessenger,
|
||||
'SnapController:updateSnapState',
|
||||
),
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
getSnapKeyring: this.getSnapKeyring.bind(this),
|
||||
saveSnapKeyring: async () => {
|
||||
await this.keyringController.persistAllKeyrings();
|
||||
await this.keyringController._updateMemStoreKeyrings();
|
||||
await this.keyringController.fullUpdate();
|
||||
},
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
}),
|
||||
};
|
||||
}
|
||||
@ -2167,6 +2210,13 @@ export default class MetamaskController extends EventEmitter {
|
||||
preferencesController.setTransactionSecurityCheckEnabled.bind(
|
||||
preferencesController,
|
||||
),
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
setSnapsAddSnapAccountModalDismissed:
|
||||
preferencesController.setSnapsAddSnapAccountModalDismissed.bind(
|
||||
preferencesController,
|
||||
),
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
// AssetsContractController
|
||||
getTokenStandardAndDetails: this.getTokenStandardAndDetails.bind(this),
|
||||
|
||||
@ -2408,6 +2458,11 @@ export default class MetamaskController extends EventEmitter {
|
||||
dismissNotifications: this.dismissNotifications.bind(this),
|
||||
markNotificationsAsRead: this.markNotificationsAsRead.bind(this),
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
updateSnapRegistry: this.preferencesController.updateSnapRegistry.bind(
|
||||
preferencesController,
|
||||
),
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(desktop)
|
||||
// Desktop
|
||||
getDesktopEnabled: this.desktopController.getDesktopEnabled.bind(
|
||||
@ -2771,6 +2826,7 @@ export default class MetamaskController extends EventEmitter {
|
||||
// set new identities
|
||||
this.preferencesController.setAddresses(accounts);
|
||||
this.selectFirstIdentity();
|
||||
|
||||
return vault;
|
||||
} finally {
|
||||
releaseLock();
|
||||
|
@ -46,6 +46,7 @@ buildTypes:
|
||||
- snaps
|
||||
- desktop
|
||||
- build-flask
|
||||
- keyring-snaps
|
||||
env:
|
||||
- INFURA_FLASK_PROJECT_ID
|
||||
- SEGMENT_FLASK_WRITE_KEY
|
||||
@ -64,6 +65,7 @@ buildTypes:
|
||||
- snaps
|
||||
- desktop
|
||||
- build-flask
|
||||
- keyring-snaps
|
||||
env:
|
||||
- INFURA_FLASK_PROJECT_ID
|
||||
- SEGMENT_FLASK_WRITE_KEY
|
||||
@ -138,6 +140,11 @@ features:
|
||||
- src: ./app/build-types/flask/images/
|
||||
dest: images
|
||||
- ./{app,shared,ui}/**/flask/**
|
||||
keyring-snaps:
|
||||
env:
|
||||
- KEYRING_SNAPS_REGISTRY_URL: https://metamask.github.io/keyring-snaps-registry/prod/registry.json
|
||||
assets:
|
||||
- ./{app,shared,ui}/**/keyring-snaps/**
|
||||
|
||||
# Env variables that are required for all types of builds
|
||||
#
|
||||
|
@ -933,7 +933,7 @@
|
||||
"@metamask/eth-json-rpc-middleware>@metamask/utils": true,
|
||||
"@metamask/eth-json-rpc-middleware>pify": true,
|
||||
"@metamask/eth-json-rpc-middleware>safe-stable-stringify": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"eth-rpc-errors": true,
|
||||
"json-rpc-engine": true,
|
||||
"vinyl>clone": true
|
||||
@ -955,9 +955,9 @@
|
||||
"packages": {
|
||||
"@metamask/browser-passworder": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true,
|
||||
"@metamask/eth-keyring-controller>obs-store": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"browserify>events": true
|
||||
}
|
||||
},
|
||||
@ -968,7 +968,7 @@
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-hd-keyring>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/scure-bip39": true,
|
||||
"browserify>buffer": true
|
||||
}
|
||||
@ -1010,11 +1010,44 @@
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"browserify>buffer": true,
|
||||
"browserify>events": true,
|
||||
"ethereumjs-wallet>randombytes": true
|
||||
@ -1107,6 +1140,39 @@
|
||||
"ganache>secp256k1>elliptic": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-token-tracker": {
|
||||
"globals": {
|
||||
"console.warn": true
|
||||
@ -1234,42 +1300,9 @@
|
||||
"browserify>events": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": {
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@trezor/connect-web": {
|
||||
@ -1612,7 +1645,7 @@
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true,
|
||||
"@metamask/network-controller>@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>pify": true,
|
||||
"@metamask/safe-event-emitter": true,
|
||||
|
@ -1004,7 +1004,7 @@
|
||||
"@metamask/eth-json-rpc-middleware>@metamask/utils": true,
|
||||
"@metamask/eth-json-rpc-middleware>pify": true,
|
||||
"@metamask/eth-json-rpc-middleware>safe-stable-stringify": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"eth-rpc-errors": true,
|
||||
"json-rpc-engine": true,
|
||||
"vinyl>clone": true
|
||||
@ -1026,9 +1026,9 @@
|
||||
"packages": {
|
||||
"@metamask/browser-passworder": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true,
|
||||
"@metamask/eth-keyring-controller>obs-store": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"browserify>events": true
|
||||
}
|
||||
},
|
||||
@ -1039,7 +1039,7 @@
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-hd-keyring>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/scure-bip39": true,
|
||||
"browserify>buffer": true
|
||||
}
|
||||
@ -1081,11 +1081,44 @@
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"browserify>buffer": true,
|
||||
"browserify>events": true,
|
||||
"ethereumjs-wallet>randombytes": true
|
||||
@ -1178,6 +1211,94 @@
|
||||
"ganache>secp256k1>elliptic": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring": {
|
||||
"globals": {
|
||||
"console.error": true,
|
||||
"console.warn": true
|
||||
},
|
||||
"packages": {
|
||||
"@ethereumjs/tx": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/keyring-api": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/utils": true,
|
||||
"@metamask/eth-snap-keyring>uuid": true,
|
||||
"browserify>events": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/keyring-api": {
|
||||
"packages": {
|
||||
"@metamask/eth-snap-keyring>@metamask/keyring-api>@metamask/utils": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/keyring-api>uuid": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/keyring-api>@metamask/utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"nock>debug": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/keyring-api>uuid": {
|
||||
"globals": {
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"nock>debug": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>uuid": {
|
||||
"globals": {
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-token-tracker": {
|
||||
"globals": {
|
||||
"console.warn": true
|
||||
@ -1305,42 +1426,9 @@
|
||||
"browserify>events": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": {
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@trezor/connect-web": {
|
||||
@ -1683,7 +1771,7 @@
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true,
|
||||
"@metamask/network-controller>@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>pify": true,
|
||||
"@metamask/safe-event-emitter": true,
|
||||
|
@ -1004,7 +1004,7 @@
|
||||
"@metamask/eth-json-rpc-middleware>@metamask/utils": true,
|
||||
"@metamask/eth-json-rpc-middleware>pify": true,
|
||||
"@metamask/eth-json-rpc-middleware>safe-stable-stringify": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"eth-rpc-errors": true,
|
||||
"json-rpc-engine": true,
|
||||
"vinyl>clone": true
|
||||
@ -1026,9 +1026,9 @@
|
||||
"packages": {
|
||||
"@metamask/browser-passworder": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true,
|
||||
"@metamask/eth-keyring-controller>obs-store": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"browserify>events": true
|
||||
}
|
||||
},
|
||||
@ -1039,7 +1039,7 @@
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-hd-keyring>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/scure-bip39": true,
|
||||
"browserify>buffer": true
|
||||
}
|
||||
@ -1081,11 +1081,44 @@
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"browserify>buffer": true,
|
||||
"browserify>events": true,
|
||||
"ethereumjs-wallet>randombytes": true
|
||||
@ -1178,6 +1211,94 @@
|
||||
"ganache>secp256k1>elliptic": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring": {
|
||||
"globals": {
|
||||
"console.error": true,
|
||||
"console.warn": true
|
||||
},
|
||||
"packages": {
|
||||
"@ethereumjs/tx": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/keyring-api": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/utils": true,
|
||||
"@metamask/eth-snap-keyring>uuid": true,
|
||||
"browserify>events": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/keyring-api": {
|
||||
"packages": {
|
||||
"@metamask/eth-snap-keyring>@metamask/keyring-api>@metamask/utils": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/keyring-api>uuid": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/keyring-api>@metamask/utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"nock>debug": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/keyring-api>uuid": {
|
||||
"globals": {
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/utils": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"TextEncoder": true
|
||||
},
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"nock>debug": true,
|
||||
"semver": true,
|
||||
"superstruct": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>uuid": {
|
||||
"globals": {
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-token-tracker": {
|
||||
"globals": {
|
||||
"console.warn": true
|
||||
@ -1305,42 +1426,9 @@
|
||||
"browserify>events": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": {
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@trezor/connect-web": {
|
||||
@ -1683,7 +1771,7 @@
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true,
|
||||
"@metamask/network-controller>@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>pify": true,
|
||||
"@metamask/safe-event-emitter": true,
|
||||
|
@ -933,7 +933,7 @@
|
||||
"@metamask/eth-json-rpc-middleware>@metamask/utils": true,
|
||||
"@metamask/eth-json-rpc-middleware>pify": true,
|
||||
"@metamask/eth-json-rpc-middleware>safe-stable-stringify": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"eth-rpc-errors": true,
|
||||
"json-rpc-engine": true,
|
||||
"vinyl>clone": true
|
||||
@ -955,9 +955,9 @@
|
||||
"packages": {
|
||||
"@metamask/browser-passworder": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true,
|
||||
"@metamask/eth-keyring-controller>obs-store": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"browserify>events": true
|
||||
}
|
||||
},
|
||||
@ -968,7 +968,7 @@
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-hd-keyring>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/scure-bip39": true,
|
||||
"browserify>buffer": true
|
||||
}
|
||||
@ -1010,11 +1010,44 @@
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"browserify>buffer": true,
|
||||
"browserify>events": true,
|
||||
"ethereumjs-wallet>randombytes": true
|
||||
@ -1107,6 +1140,39 @@
|
||||
"ganache>secp256k1>elliptic": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-token-tracker": {
|
||||
"globals": {
|
||||
"console.warn": true
|
||||
@ -1234,42 +1300,9 @@
|
||||
"browserify>events": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": {
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@trezor/connect-web": {
|
||||
@ -1612,7 +1645,7 @@
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true,
|
||||
"@metamask/network-controller>@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>pify": true,
|
||||
"@metamask/safe-event-emitter": true,
|
||||
|
@ -1154,7 +1154,7 @@
|
||||
"@metamask/eth-json-rpc-middleware>@metamask/utils": true,
|
||||
"@metamask/eth-json-rpc-middleware>pify": true,
|
||||
"@metamask/eth-json-rpc-middleware>safe-stable-stringify": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"eth-rpc-errors": true,
|
||||
"json-rpc-engine": true,
|
||||
"vinyl>clone": true
|
||||
@ -1176,9 +1176,9 @@
|
||||
"packages": {
|
||||
"@metamask/browser-passworder": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-hd-keyring": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": true,
|
||||
"@metamask/eth-keyring-controller>obs-store": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"browserify>events": true
|
||||
}
|
||||
},
|
||||
@ -1189,7 +1189,7 @@
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-hd-keyring>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/scure-bip39": true,
|
||||
"browserify>buffer": true
|
||||
}
|
||||
@ -1231,11 +1231,44 @@
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-keyring-controller>@metamask/eth-simple-keyring>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"browserify>buffer": true,
|
||||
"browserify>events": true,
|
||||
"ethereumjs-wallet>randombytes": true
|
||||
@ -1328,6 +1361,39 @@
|
||||
"ganache>secp256k1>elliptic": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-token-tracker": {
|
||||
"globals": {
|
||||
"console.warn": true
|
||||
@ -1455,42 +1521,9 @@
|
||||
"browserify>events": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": {
|
||||
"packages": {
|
||||
"@ethereumjs/tx>@ethereumjs/util": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography": true,
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethjs-util": true,
|
||||
"bn.js": true,
|
||||
"browserify>buffer": true,
|
||||
"eth-sig-util>tweetnacl": true,
|
||||
"eth-sig-util>tweetnacl-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography": {
|
||||
"globals": {
|
||||
"TextDecoder": true,
|
||||
"crypto": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethereum-cryptography>@noble/hashes": {
|
||||
"globals": {
|
||||
"TextEncoder": true,
|
||||
"crypto": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util>ethjs-util": {
|
||||
"packages": {
|
||||
"browserify>buffer": true,
|
||||
"ethjs>ethjs-util>is-hex-prefixed": true,
|
||||
"ethjs>ethjs-util>strip-hex-prefix": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@trezor/connect-plugin-ethereum": {
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true
|
||||
}
|
||||
},
|
||||
"@metamask/eth-trezor-keyring>@trezor/connect-web": {
|
||||
@ -1833,7 +1866,7 @@
|
||||
"setTimeout": true
|
||||
},
|
||||
"packages": {
|
||||
"@metamask/eth-trezor-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/eth-snap-keyring>@metamask/eth-sig-util": true,
|
||||
"@metamask/network-controller>@metamask/eth-json-rpc-infura>@metamask/utils": true,
|
||||
"@metamask/network-controller>@metamask/eth-json-rpc-infura>eth-json-rpc-middleware>pify": true,
|
||||
"@metamask/safe-event-emitter": true,
|
||||
|
@ -51,8 +51,8 @@
|
||||
"sentry:publish": "node ./development/sentry-publish.js",
|
||||
"lint": "yarn lint:prettier && yarn lint:eslint && yarn lint:tsc && yarn lint:styles",
|
||||
"lint:fix": "yarn lint:prettier:fix && yarn lint:eslint:fix && yarn lint:styles:fix",
|
||||
"lint:prettier": "prettier --check -- **/*.json",
|
||||
"lint:prettier:fix": "prettier --write -- **/*.json",
|
||||
"lint:prettier": "prettier --check -- '**/*.json'",
|
||||
"lint:prettier:fix": "prettier --write -- '**/*.json'",
|
||||
"lint:changed": "./development/get-changed-file-names.sh | grep --regexp='[.]js$' | tr '\\n' '\\0' | xargs -0 eslint",
|
||||
"lint:changed:fix": "./development/get-changed-file-names.sh | grep --regexp='[.]js$' | tr '\\n' '\\0' | xargs -0 eslint --fix",
|
||||
"lint:changelog": "auto-changelog validate",
|
||||
@ -235,6 +235,7 @@
|
||||
"@metamask/eth-json-rpc-middleware": "^11.0.0",
|
||||
"@metamask/eth-keyring-controller": "^10.0.1",
|
||||
"@metamask/eth-ledger-bridge-keyring": "^0.15.0",
|
||||
"@metamask/eth-snap-keyring": "^0.1.3",
|
||||
"@metamask/eth-token-tracker": "^4.0.0",
|
||||
"@metamask/eth-trezor-keyring": "^1.0.0",
|
||||
"@metamask/etherscan-link": "^2.2.0",
|
||||
|
@ -63,6 +63,12 @@ export const MESSAGE_TYPE = {
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
} as const;
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
// eslint-disable-next-line prefer-destructuring
|
||||
export const KEYRING_SNAPS_REGISTRY_URL =
|
||||
process.env.KEYRING_SNAPS_REGISTRY_URL;
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
export const SNAP_DIALOG_TYPES = {
|
||||
[DialogType.Alert]: MESSAGE_TYPE.SNAP_DIALOG_ALERT,
|
||||
|
@ -8,10 +8,19 @@ export enum InternalKeyringType {
|
||||
imported = 'Simple Key Pair',
|
||||
}
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
export enum SnapKeyringType {
|
||||
snap = 'Snap Keyring',
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
/**
|
||||
* All keyrings supported by MetaMask.
|
||||
*/
|
||||
export const KeyringType = {
|
||||
...HardwareKeyringType,
|
||||
...InternalKeyringType,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
...SnapKeyringType,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
};
|
||||
|
@ -24,7 +24,13 @@ describe('EndowmentPermissions', () => {
|
||||
|
||||
describe('RestrictedMethods', () => {
|
||||
it('has the expected permission keys', () => {
|
||||
expect(Object.keys(RestrictedMethods).sort()).toStrictEqual(
|
||||
// this is done because we there is a difference between flask and stable permissions
|
||||
// the code fence in `shared/constants/snaps/permissions.ts` is not supported in jest
|
||||
const mainBuildRestrictedMethodPermissions = Object.keys(RestrictedMethods)
|
||||
.filter((key) => key !== 'snap_manageAccounts')
|
||||
.sort();
|
||||
|
||||
expect(mainBuildRestrictedMethodPermissions).toStrictEqual(
|
||||
[
|
||||
'eth_accounts',
|
||||
...Object.keys(restrictedMethodPermissionBuilders).filter(
|
||||
@ -35,3 +41,26 @@ describe('RestrictedMethods', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// Kept here because code fences are not supported in jest.
|
||||
// rpc methods flask has more restricted endowment permission builders
|
||||
jest.mock('@metamask/rpc-methods', () =>
|
||||
jest.requireActual('@metamask/rpc-methods-flask'),
|
||||
);
|
||||
|
||||
describe('Flask Restricted Methods', () => {
|
||||
it('has the expected flask permission keys', () => {
|
||||
const flaskExcludedSnapPermissions = Object.keys(
|
||||
ExcludedSnapPermissions,
|
||||
).filter((key) => key !== 'snap_manageAccounts');
|
||||
|
||||
expect(Object.keys(RestrictedMethods).sort()).toStrictEqual(
|
||||
[
|
||||
'eth_accounts',
|
||||
...Object.keys(restrictedMethodPermissionBuilders).filter(
|
||||
(targetName) => !flaskExcludedSnapPermissions.includes(targetName),
|
||||
),
|
||||
].sort(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
@ -14,6 +14,9 @@ export const RestrictedMethods = Object.freeze({
|
||||
snap_getEntropy: 'snap_getEntropy',
|
||||
wallet_snap: 'wallet_snap',
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
snap_manageAccounts: 'snap_manageAccounts',
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
} as const);
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
|
@ -13,7 +13,7 @@ export const EndowmentPermissions = Object.freeze({
|
||||
// Methods / permissions in external packages that we are temporarily excluding.
|
||||
export const ExcludedSnapPermissions = Object.freeze({
|
||||
// TODO: Enable in Flask
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-main,build-flask)
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-main)
|
||||
snap_manageAccounts:
|
||||
'This permission is still in development and therefore not available.',
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
@ -139,6 +139,10 @@
|
||||
{
|
||||
"type": "Simple Key Pair",
|
||||
"accounts": ["0xeb9e64b93097bc15f01f13eae97015c57ab64823"]
|
||||
},
|
||||
{
|
||||
"type": "Snap Keyring",
|
||||
"accounts": ["0xb552685e3d2790efd64a175b00d51f02cdafee5d"]
|
||||
}
|
||||
],
|
||||
"identities": {
|
||||
@ -172,6 +176,22 @@
|
||||
"subjectType": "snap"
|
||||
}
|
||||
},
|
||||
"snapRegistryList": {
|
||||
"a51ea3a8-f1b0-4613-9440-b80e2236713b": {
|
||||
"id": "a51ea3a8-f1b0-4613-9440-b80e2236713b",
|
||||
"snapId": "npm:@metamask/snap-simple-keyring",
|
||||
"iconUrl": "",
|
||||
"snapTitle": "Metamask Simple Keyring",
|
||||
"snapSlug": "Secure your account with MetaMask Mobile",
|
||||
"snapDescription": "A simple private key is a randomly generated string of characters that is used to sign transactions. This private key is stored securely within this snap.",
|
||||
"tags": ["EOA"],
|
||||
"developer": "Metamask",
|
||||
"website": "https://www.consensys.net/",
|
||||
"auditUrls": ["auditUrl1", "auditUrl2"],
|
||||
"version": "1.0.0",
|
||||
"lastUpdated": "April 20, 2023"
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"test": {
|
||||
"id": "test",
|
||||
|
@ -1,3 +1,5 @@
|
||||
module.exports = {
|
||||
TEST_SNAPS_WEBSITE_URL: 'https://metamask.github.io/test-snaps/5.5.0/',
|
||||
TEST_SNAPS_SIMPLE_KEYRING_WEBSITE_URL:
|
||||
'https://metamask.github.io/snap-simple-keyring/latest/',
|
||||
};
|
||||
|
113
test/e2e/snaps/test-snap-manageAccount.spec.js
Normal file
113
test/e2e/snaps/test-snap-manageAccount.spec.js
Normal file
@ -0,0 +1,113 @@
|
||||
const { strict: assert } = require('assert');
|
||||
const { withFixtures } = require('../helpers');
|
||||
const FixtureBuilder = require('../fixture-builder');
|
||||
const { TEST_SNAPS_SIMPLE_KEYRING_WEBSITE_URL } = require('./enums');
|
||||
|
||||
describe('Test Snap Account', function () {
|
||||
it('can create a new snap account', async function () {
|
||||
const ganacheOptions = {
|
||||
accounts: [
|
||||
{
|
||||
secretKey:
|
||||
'0x7C9529A67102755B7E6102D6D950AC5D5863C98713805CEC576B945B15B71EAC',
|
||||
balance: 25000000000000000000,
|
||||
},
|
||||
],
|
||||
};
|
||||
await withFixtures(
|
||||
{
|
||||
fixtures: new FixtureBuilder().build(),
|
||||
ganacheOptions,
|
||||
failOnConsoleError: false,
|
||||
title: this.test.title,
|
||||
},
|
||||
async ({ driver }) => {
|
||||
await driver.navigate();
|
||||
|
||||
// enter pw into extension
|
||||
await driver.fill('#password', 'correct horse battery staple');
|
||||
await driver.press('#password', driver.Key.ENTER);
|
||||
|
||||
// navigate to test snaps page and connect
|
||||
await driver.openNewPage(TEST_SNAPS_SIMPLE_KEYRING_WEBSITE_URL);
|
||||
await driver.delay(1000);
|
||||
const connectButton = await driver.findElement('#connectButton');
|
||||
await driver.scrollToElement(connectButton);
|
||||
await driver.delay(1000);
|
||||
await driver.clickElement('#connectButton');
|
||||
await driver.delay(500);
|
||||
|
||||
// switch to metamask extension and click connect
|
||||
const windowHandles = await driver.waitUntilXWindowHandles(
|
||||
3,
|
||||
1000,
|
||||
10000,
|
||||
);
|
||||
await driver.switchToWindowWithTitle(
|
||||
'MetaMask Notification',
|
||||
windowHandles,
|
||||
);
|
||||
await driver.clickElement({
|
||||
text: 'Connect',
|
||||
tag: 'button',
|
||||
});
|
||||
|
||||
try {
|
||||
await driver.clickElement('[data-testid="snap-install-scroll"]');
|
||||
} catch (_) {
|
||||
console.log('Missing scroll');
|
||||
}
|
||||
|
||||
await driver.waitForSelector({ text: 'Install' });
|
||||
|
||||
await driver.clickElement({
|
||||
text: 'Install',
|
||||
tag: 'button',
|
||||
});
|
||||
|
||||
await driver.waitForSelector({ text: 'OK' });
|
||||
|
||||
await driver.clickElement({
|
||||
text: 'OK',
|
||||
tag: 'button',
|
||||
});
|
||||
|
||||
await driver.switchToWindowWithTitle(
|
||||
'SSK - Snap Simple Keyring',
|
||||
windowHandles,
|
||||
);
|
||||
|
||||
// check the dapp connection status
|
||||
await driver.waitForSelector({
|
||||
css: '#snapConnected',
|
||||
text: 'Connected',
|
||||
});
|
||||
|
||||
// create new account on dapp
|
||||
await driver.clickElement({
|
||||
text: 'Create Account',
|
||||
tag: 'div',
|
||||
});
|
||||
|
||||
// create name for account
|
||||
await driver.fill("[placeholder='Name']", 'snap account');
|
||||
|
||||
await driver.clickElement({
|
||||
text: 'Execute',
|
||||
tag: 'button',
|
||||
});
|
||||
|
||||
await driver.delay(1000);
|
||||
|
||||
// switch to metamask extension
|
||||
await driver.switchToWindowWithTitle('MetaMask', windowHandles);
|
||||
|
||||
// click on accounts
|
||||
await driver.clickElement('[data-testid="account-menu-icon"]');
|
||||
|
||||
const label = await driver.findElement('.mm-tag');
|
||||
assert.strictEqual(await label.getText(), 'Snaps');
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
61
ui/components/app/account-menu/keyring-label.js
Normal file
61
ui/components/app/account-menu/keyring-label.js
Normal file
@ -0,0 +1,61 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
import { HardwareKeyringNames } from '../../../../shared/constants/hardware-wallets';
|
||||
import { KeyringType } from '../../../../shared/constants/keyring';
|
||||
|
||||
export default function KeyringLabel({ keyring }) {
|
||||
const t = useI18nContext();
|
||||
let label = null;
|
||||
|
||||
// Keyring value might take a while to get a value
|
||||
if (!keyring) {
|
||||
return null;
|
||||
}
|
||||
const { type } = keyring;
|
||||
|
||||
switch (type) {
|
||||
case KeyringType.qr:
|
||||
label = HardwareKeyringNames.qr;
|
||||
break;
|
||||
case KeyringType.imported:
|
||||
label = t('imported');
|
||||
break;
|
||||
case KeyringType.trezor:
|
||||
label = HardwareKeyringNames.trezor;
|
||||
break;
|
||||
case KeyringType.ledger:
|
||||
label = HardwareKeyringNames.ledger;
|
||||
break;
|
||||
case KeyringType.lattice:
|
||||
label = HardwareKeyringNames.lattice;
|
||||
break;
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
case KeyringType.snap:
|
||||
label = t('snaps');
|
||||
break;
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
default:
|
||||
label = null;
|
||||
}
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(mmi)
|
||||
if (type.startsWith('Custody') && /JSONRPC/u.test(type)) {
|
||||
label = type.split(' - ')[1];
|
||||
return null;
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
if (label === null) {
|
||||
return label;
|
||||
}
|
||||
|
||||
return (
|
||||
<>{label ? <div className="keyring-label allcaps">{label}</div> : null}</>
|
||||
);
|
||||
}
|
||||
|
||||
KeyringLabel.propTypes = {
|
||||
keyring: PropTypes.object,
|
||||
};
|
@ -0,0 +1,68 @@
|
||||
import React from 'react';
|
||||
import { fireEvent } from '@testing-library/react';
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||
import messages from '../../../../app/_locales/en/messages.json';
|
||||
import mockState from '../../../../test/data/mock-state.json';
|
||||
import ConfigureSnapPopup, {
|
||||
ConfigureSnapPopupType,
|
||||
} from './configure-snap-popup';
|
||||
|
||||
const mockOnClose = jest.fn();
|
||||
const mockStore = configureMockStore([])(mockState);
|
||||
describe('ConfigureSnapPopup', () => {
|
||||
global.platform = { openTab: jest.fn() };
|
||||
|
||||
it('should show configure popup title and description', async () => {
|
||||
const { getByText } = renderWithProvider(
|
||||
<ConfigureSnapPopup
|
||||
onClose={mockOnClose}
|
||||
link={'mockLink'}
|
||||
isOpen
|
||||
type={ConfigureSnapPopupType.CONFIGURE}
|
||||
/>,
|
||||
mockStore,
|
||||
);
|
||||
expect(
|
||||
getByText(messages.configureSnapPopupTitle.message),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
getByText(messages.configureSnapPopupDescription.message),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show install popup title and description', async () => {
|
||||
const { getByText } = renderWithProvider(
|
||||
<ConfigureSnapPopup
|
||||
onClose={mockOnClose}
|
||||
link={'mockLink'}
|
||||
isOpen
|
||||
type={ConfigureSnapPopupType.INSTALL}
|
||||
/>,
|
||||
mockStore,
|
||||
);
|
||||
expect(
|
||||
getByText(messages.configureSnapPopupInstallTitle.message),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
getByText(messages.configureSnapPopupInstallDescription.message),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should open link on click of link', async () => {
|
||||
const { getByText } = renderWithProvider(
|
||||
<ConfigureSnapPopup
|
||||
onClose={mockOnClose}
|
||||
link={'mockLink'}
|
||||
isOpen
|
||||
type={ConfigureSnapPopupType.CONFIGURE}
|
||||
/>,
|
||||
mockStore,
|
||||
);
|
||||
const link = getByText('mockLink');
|
||||
await fireEvent.click(link);
|
||||
expect(global.platform.openTab).toHaveBeenCalledWith({
|
||||
url: 'mockLink',
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,99 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
BUTTON_VARIANT,
|
||||
Button,
|
||||
Text,
|
||||
Box,
|
||||
Modal,
|
||||
ModalOverlay,
|
||||
ModalContent,
|
||||
ModalHeader,
|
||||
} from '../../component-library';
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
import {
|
||||
AlignItems,
|
||||
Display,
|
||||
FlexDirection,
|
||||
JustifyContent,
|
||||
TextAlign,
|
||||
TextVariant,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
|
||||
export enum ConfigureSnapPopupType {
|
||||
CONFIGURE = 'configure',
|
||||
INSTALL = 'install',
|
||||
}
|
||||
|
||||
export default function ConfigureSnapPopup({
|
||||
type,
|
||||
isOpen,
|
||||
onClose,
|
||||
link,
|
||||
}: {
|
||||
type: ConfigureSnapPopupType;
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
link: string;
|
||||
}) {
|
||||
const t = useI18nContext();
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={onClose}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader onClose={onClose} margin={[4, 4, 4, 4]}>
|
||||
{type === ConfigureSnapPopupType.CONFIGURE
|
||||
? t('configureSnapPopupTitle')
|
||||
: t('configureSnapPopupInstallTitle')}
|
||||
</ModalHeader>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
flexDirection={FlexDirection.Column}
|
||||
justifyContent={JustifyContent.flexStart}
|
||||
alignItems={AlignItems.center}
|
||||
>
|
||||
<img
|
||||
src="images/logo/metamask-fox.svg"
|
||||
width="54x"
|
||||
height="50px"
|
||||
style={{ marginBottom: '16px' }}
|
||||
/>
|
||||
<Text
|
||||
variant={TextVariant.bodyLgMedium}
|
||||
textAlign={TextAlign.Center}
|
||||
marginBottom={5}
|
||||
>
|
||||
{type === ConfigureSnapPopupType.CONFIGURE
|
||||
? t('configureSnapPopupDescription')
|
||||
: t('configureSnapPopupInstallDescription')}
|
||||
</Text>
|
||||
<Text variant={TextVariant.bodyLgMedium} marginBottom={4}>
|
||||
{t('configureSnapPopupLink')}
|
||||
</Text>
|
||||
<Button
|
||||
variant={BUTTON_VARIANT.LINK}
|
||||
marginBottom={8}
|
||||
onClick={() => {
|
||||
global.platform.openTab({
|
||||
url: link,
|
||||
});
|
||||
}}
|
||||
>
|
||||
{link}
|
||||
</Button>
|
||||
</Box>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
ConfigureSnapPopup.propTypes = {
|
||||
type: PropTypes.oneOf([
|
||||
ConfigureSnapPopupType.CONFIGURE,
|
||||
ConfigureSnapPopupType.INSTALL,
|
||||
]).isRequired,
|
||||
isOpen: PropTypes.bool.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
link: PropTypes.string.isRequired,
|
||||
};
|
1
ui/components/app/configure-snap-popup/index.js
Normal file
1
ui/components/app/configure-snap-popup/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default, ConfigureSnapPopupType } from './configure-snap-popup';
|
@ -6,8 +6,10 @@ import AccountModalContainer from '../account-modal-container';
|
||||
import QrView from '../../../ui/qr-code';
|
||||
import EditableLabel from '../../../ui/editable-label';
|
||||
import Button from '../../../ui/button';
|
||||
import { getURLHostName } from '../../../../helpers/utils/util';
|
||||
import { isHardwareKeyring } from '../../../../helpers/utils/hardware';
|
||||
import {
|
||||
getURLHostName,
|
||||
isAbleToExportAccount,
|
||||
} from '../../../../helpers/utils/util';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
import CustodyLabels from '../../../institutional/custody-labels/custody-labels';
|
||||
import { toChecksumHexAddress } from '../../../../../shared/modules/hexstring-utils';
|
||||
@ -65,11 +67,7 @@ export default class AccountDetailsModal extends Component {
|
||||
return kr.accounts.includes(address);
|
||||
});
|
||||
|
||||
let exportPrivateKeyFeatureEnabled = true;
|
||||
// This feature is disabled for hardware wallets
|
||||
if (isHardwareKeyring(keyring?.type)) {
|
||||
exportPrivateKeyFeatureEnabled = false;
|
||||
}
|
||||
let exportPrivateKeyFeatureEnabled = isAbleToExportAccount(keyring?.type);
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
if (keyring?.type?.search('Custody') !== -1) {
|
||||
|
@ -103,4 +103,133 @@ describe('Account Details Modal', () => {
|
||||
|
||||
expect(queryByText(/block.explorer/u)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not display export private key if the keyring is snaps', () => {
|
||||
const mockStateWithSnapKeyring = {
|
||||
appState: {
|
||||
networkDropdownOpen: false,
|
||||
gasIsLoading: false,
|
||||
isLoading: false,
|
||||
modal: {
|
||||
open: false,
|
||||
modalState: {
|
||||
name: null,
|
||||
props: {},
|
||||
},
|
||||
previousModalState: {
|
||||
name: null,
|
||||
},
|
||||
},
|
||||
warning: null,
|
||||
customTokenAmount: '10',
|
||||
},
|
||||
history: {
|
||||
mostRecentOverviewPage: '/mostRecentOverviewPage',
|
||||
},
|
||||
metamask: {
|
||||
providerConfig: {
|
||||
type: 'rpc',
|
||||
chainId: '0x5',
|
||||
ticker: 'ETH',
|
||||
id: 'testNetworkConfigurationId',
|
||||
},
|
||||
keyrings: [
|
||||
{
|
||||
type: 'Snap Keyring',
|
||||
accounts: [
|
||||
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
|
||||
'0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'Ledger Hardware',
|
||||
accounts: ['0xc42edfcc21ed14dda456aa0756c153f7985d8813'],
|
||||
},
|
||||
{
|
||||
type: 'Simple Key Pair',
|
||||
accounts: ['0xeb9e64b93097bc15f01f13eae97015c57ab64823'],
|
||||
},
|
||||
],
|
||||
identities: {
|
||||
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': {
|
||||
address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
|
||||
name: 'Test Account',
|
||||
},
|
||||
'0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b': {
|
||||
address: '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b',
|
||||
name: 'Test Account 2',
|
||||
},
|
||||
'0xc42edfcc21ed14dda456aa0756c153f7985d8813': {
|
||||
address: '0xc42edfcc21ed14dda456aa0756c153f7985d8813',
|
||||
name: 'Test Ledger 1',
|
||||
},
|
||||
'0xeb9e64b93097bc15f01f13eae97015c57ab64823': {
|
||||
name: 'Test Account 3',
|
||||
address: '0xeb9e64b93097bc15f01f13eae97015c57ab64823',
|
||||
},
|
||||
},
|
||||
networkDetails: {
|
||||
EIPS: {
|
||||
1559: true,
|
||||
},
|
||||
},
|
||||
frequentRpcListDetail: [],
|
||||
subjectMetadata: {
|
||||
'npm:@metamask/test-snap-bip44': {
|
||||
name: '@metamask/test-snap-bip44',
|
||||
version: '1.2.3',
|
||||
subjectType: 'snap',
|
||||
},
|
||||
},
|
||||
notifications: {
|
||||
test: {
|
||||
id: 'test',
|
||||
origin: 'local:http://localhost:8086/',
|
||||
createdDate: 1652967897732,
|
||||
readDate: null,
|
||||
message: 'Hello, http://localhost:8086!',
|
||||
},
|
||||
test2: {
|
||||
id: 'test2',
|
||||
origin: 'local:http://localhost:8086/',
|
||||
createdDate: 1652967897732,
|
||||
readDate: 1652967897732,
|
||||
message: 'Hello, http://localhost:8086!',
|
||||
},
|
||||
},
|
||||
cachedBalances: {},
|
||||
incomingTransactions: {},
|
||||
selectedAddress: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
|
||||
accounts: {
|
||||
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': {
|
||||
balance: '0x346ba7725f412cbfdb',
|
||||
address: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
|
||||
},
|
||||
'0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b': {
|
||||
address: '0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b',
|
||||
balance: '0x0',
|
||||
},
|
||||
'0xc42edfcc21ed14dda456aa0756c153f7985d8813': {
|
||||
address: '0xc42edfcc21ed14dda456aa0756c153f7985d8813',
|
||||
balance: '0x0',
|
||||
},
|
||||
'0xeb9e64b93097bc15f01f13eae97015c57ab64823': {
|
||||
address: '0xeb9e64b93097bc15f01f13eae97015c57ab64823',
|
||||
balance: '0x0',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const mockStoreWithSnapKeyring = configureMockState([thunk])(
|
||||
mockStateWithSnapKeyring,
|
||||
);
|
||||
const { queryByText } = renderWithProvider(
|
||||
<AccountDetailsModal />,
|
||||
mockStoreWithSnapKeyring,
|
||||
);
|
||||
|
||||
const exportPrivateKeyButton = queryByText(exportPrivateKey.message);
|
||||
|
||||
expect(exportPrivateKeyButton).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
getHardwareWalletType,
|
||||
getMetaMaskKeyrings,
|
||||
} from '../../../selectors';
|
||||
import { isHardwareKeyring } from '../../../helpers/utils/hardware';
|
||||
import { isAbleToExportAccount } from '../../../helpers/utils/util';
|
||||
import {
|
||||
BUTTON_SECONDARY_SIZES,
|
||||
ButtonSecondary,
|
||||
@ -43,7 +43,7 @@ export const AccountDetailsDisplay = ({
|
||||
|
||||
const keyrings = useSelector(getMetaMaskKeyrings);
|
||||
const keyring = keyrings.find((kr) => kr.accounts.includes(address));
|
||||
const exportPrivateKeyFeatureEnabled = !isHardwareKeyring(keyring?.type);
|
||||
const exportPrivateKeyFeatureEnabled = isAbleToExportAccount(keyring?.type);
|
||||
|
||||
const chainId = useSelector(getCurrentChainId);
|
||||
const deviceName = useSelector(getHardwareWalletType);
|
||||
|
@ -60,6 +60,10 @@ function getLabel(keyring = {}, t) {
|
||||
return HardwareKeyringNames.ledger;
|
||||
case KeyringType.lattice:
|
||||
return HardwareKeyringNames.lattice;
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
case KeyringType.snap:
|
||||
return t('snaps');
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@ -102,4 +102,17 @@ describe('AccountListItem', () => {
|
||||
|
||||
expect(getByAltText(`${connectedAvatarName} logo`)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
it('renders the snap label for snap accounts', () => {
|
||||
const { getByText } = render({
|
||||
identity: {
|
||||
address: '0xb552685e3d2790eFd64a175B00D51F02cdaFEe5D',
|
||||
name: 'Snap Account',
|
||||
},
|
||||
});
|
||||
|
||||
expect(getByText('Snaps')).toBeInTheDocument();
|
||||
});
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
});
|
||||
|
@ -33,6 +33,9 @@ import {
|
||||
} from '../../../../shared/constants/metametrics';
|
||||
import {
|
||||
CONNECT_HARDWARE_ROUTE,
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
ADD_SNAP_ACCOUNT_ROUTE,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
CUSTODY_ACCOUNT_ROUTE,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
@ -247,6 +250,30 @@ export const AccountListMenu = ({ onClose }) => {
|
||||
{t('hardwareWallet')}
|
||||
</ButtonLink>
|
||||
</Box>
|
||||
{
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
<>
|
||||
<Box marginTop={4}>
|
||||
<ButtonLink
|
||||
size={Size.SM}
|
||||
startIconName={IconName.Snaps}
|
||||
onClick={() => {
|
||||
dispatch(toggleAccountMenu());
|
||||
getEnvironmentType() === ENVIRONMENT_TYPE_POPUP
|
||||
? global.platform.openExtensionInBrowser(
|
||||
ADD_SNAP_ACCOUNT_ROUTE,
|
||||
null,
|
||||
true,
|
||||
)
|
||||
: history.push(ADD_SNAP_ACCOUNT_ROUTE);
|
||||
}}
|
||||
>
|
||||
{t('settingAddSnapAccount')}
|
||||
</ButtonLink>
|
||||
</Box>
|
||||
</>
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
}
|
||||
{
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
<Box>
|
||||
|
@ -1,12 +1,33 @@
|
||||
/* eslint-disable jest/require-top-level-describe */
|
||||
import React from 'react';
|
||||
import reactRouterDom from 'react-router-dom';
|
||||
import { fireEvent, renderWithProvider } from '../../../../test/jest';
|
||||
import { fireEvent, renderWithProvider, waitFor } from '../../../../test/jest';
|
||||
import configureStore from '../../../store/store';
|
||||
import mockState from '../../../../test/data/mock-state.json';
|
||||
import { CONNECT_HARDWARE_ROUTE } from '../../../helpers/constants/routes';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
import messages from '../../../../app/_locales/en/messages.json';
|
||||
import {
|
||||
CONNECT_HARDWARE_ROUTE,
|
||||
ADD_SNAP_ACCOUNT_ROUTE,
|
||||
} from '../../../helpers/constants/routes';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import { AccountListMenu } from '.';
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
const mockToggleAccountMenu = jest.fn();
|
||||
const mockGetEnvironmentType = jest.fn();
|
||||
|
||||
jest.mock('../../../store/actions.ts', () => ({
|
||||
...jest.requireActual('../../../store/actions.ts'),
|
||||
toggleAccountMenu: () => mockToggleAccountMenu,
|
||||
}));
|
||||
|
||||
jest.mock('../../../../app/scripts/lib/util', () => ({
|
||||
...jest.requireActual('../../../../app/scripts/lib/util'),
|
||||
getEnvironmentType: () => mockGetEnvironmentType,
|
||||
}));
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
const render = (props = { onClose: () => jest.fn() }) => {
|
||||
const store = configureStore({
|
||||
activeTab: {
|
||||
@ -137,4 +158,32 @@ describe('AccountListMenu', () => {
|
||||
const searchBox = document.querySelector('input[type=search]');
|
||||
expect(searchBox).toBeInTheDocument();
|
||||
});
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
it('renders the add snap account button', async () => {
|
||||
const { getByText } = render();
|
||||
const addSnapAccountButton = getByText(
|
||||
messages.settingAddSnapAccount.message,
|
||||
);
|
||||
expect(addSnapAccountButton).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(addSnapAccountButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockToggleAccountMenu).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('pushes history when clicking add snap account from extended view', async () => {
|
||||
const { getByText } = render();
|
||||
mockGetEnvironmentType.mockReturnValueOnce('fullscreen');
|
||||
const addSnapAccountButton = getByText(
|
||||
messages.settingAddSnapAccount.message,
|
||||
);
|
||||
fireEvent.click(addSnapAccountButton);
|
||||
await waitFor(() => {
|
||||
expect(historyPushMock).toHaveBeenCalledWith(ADD_SNAP_ACCOUNT_ROUTE);
|
||||
});
|
||||
});
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
});
|
||||
|
@ -50,6 +50,9 @@ const CONNECT_SNAP_UPDATE_ROUTE = '/snap-update';
|
||||
const CONNECT_SNAP_RESULT_ROUTE = '/snap-install-result';
|
||||
const NOTIFICATIONS_ROUTE = '/notifications';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
const ADD_SNAP_ACCOUNT_ROUTE = '/add-snap-account';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
const CONNECTED_ROUTE = '/connected';
|
||||
const CONNECTED_ACCOUNTS_ROUTE = '/connected/accounts';
|
||||
const SWAPS_ROUTE = '/swaps';
|
||||
@ -132,6 +135,10 @@ const PATH_NAME_MAP = {
|
||||
[CONFIRM_IMPORT_TOKEN_ROUTE]: 'Confirm Import Token Page',
|
||||
[CONFIRM_ADD_SUGGESTED_TOKEN_ROUTE]: 'Confirm Add Suggested Token Page',
|
||||
[NEW_ACCOUNT_ROUTE]: 'New Account Page',
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
[ADD_SNAP_ACCOUNT_ROUTE]: 'Add Snap Account List Page',
|
||||
[`${ADD_SNAP_ACCOUNT_ROUTE}/:snapId`]: `Add Snap Account Page`,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
[CONFIRM_ADD_SUGGESTED_NFT_ROUTE]: 'Confirm Add Suggested NFT Page',
|
||||
[CONNECT_HARDWARE_ROUTE]: 'Connect Hardware Wallet Page',
|
||||
///: BEGIN:ONLY_INCLUDE_IN(build-mmi)
|
||||
@ -249,6 +256,9 @@ export {
|
||||
CONNECT_SNAP_RESULT_ROUTE,
|
||||
NOTIFICATIONS_ROUTE,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
ADD_SNAP_ACCOUNT_ROUTE,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
CONNECTED_ROUTE,
|
||||
CONNECTED_ACCOUNTS_ROUTE,
|
||||
PATH_NAME_MAP,
|
||||
|
@ -255,6 +255,7 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({
|
||||
leftIcon: IconName.SecurityKey,
|
||||
weight: 3,
|
||||
}),
|
||||
|
||||
[RestrictedMethods.snap_manageState]: ({ t }) => ({
|
||||
label: t('permission_manageState'),
|
||||
description: t('permission_manageStateDescription'),
|
||||
@ -389,6 +390,14 @@ export const PERMISSION_DESCRIPTIONS = deepFreeze({
|
||||
return results;
|
||||
},
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
[RestrictedMethods.snap_manageAccounts]: ({ t }) => ({
|
||||
label: t('permission_manageAccounts'),
|
||||
leftIcon: getLeftIcon(IconName.UserCircleAdd),
|
||||
rightIcon: null,
|
||||
weight: 3,
|
||||
}),
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
[UNKNOWN_PERMISSION]: ({ t, permissionName }) => ({
|
||||
label: t('permission_unknown', [permissionName ?? 'undefined']),
|
||||
leftIcon: getLeftIcon(IconName.Question),
|
||||
|
@ -621,3 +621,13 @@ export const getNetworkNameFromProviderType = (providerName) => {
|
||||
}
|
||||
return providerName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the given keyring type is able to export an account.
|
||||
*
|
||||
* @param keyringType - The type of the keyring.
|
||||
* @returns {boolean} `false` if the keyring type includes 'Hardware' or 'Snap', `true` otherwise.
|
||||
*/
|
||||
export const isAbleToExportAccount = (keyringType = '') => {
|
||||
return !keyringType.includes('Hardware') && !keyringType.includes('Snap');
|
||||
};
|
||||
|
@ -0,0 +1,36 @@
|
||||
import { useArgs } from '@storybook/client-api';
|
||||
import { StoryFn } from '@storybook/react';
|
||||
import React from 'react';
|
||||
import { BUTTON_VARIANT, Button } from '../../../components/component-library';
|
||||
import AddSnapAccountModal from '.';
|
||||
|
||||
const AddSnapAccountModalStory = {
|
||||
title: 'Components/App/AddSnapAccountModal',
|
||||
component: AddSnapAccountModal,
|
||||
argTypes: {},
|
||||
};
|
||||
|
||||
export const DefaultStory: StoryFn<typeof AddSnapAccountModal> = () => {
|
||||
const [{ isShowingModal }, updateArgs] = useArgs();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
variant={BUTTON_VARIANT.PRIMARY}
|
||||
onClick={() => updateArgs({ isShowingModal: true })}
|
||||
>
|
||||
Open modal
|
||||
</Button>
|
||||
{isShowingModal && (
|
||||
<AddSnapAccountModal
|
||||
isOpen={isShowingModal}
|
||||
onClose={() => updateArgs({ isShowingModal: false })}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
DefaultStory.storyName = 'Default';
|
||||
|
||||
export default AddSnapAccountModalStory;
|
@ -0,0 +1,70 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
BUTTON_VARIANT,
|
||||
Box,
|
||||
Button,
|
||||
Modal,
|
||||
ModalContent,
|
||||
ModalHeader,
|
||||
ModalOverlay,
|
||||
Text,
|
||||
} from '../../../components/component-library';
|
||||
import {
|
||||
AlignItems,
|
||||
Display,
|
||||
FlexDirection,
|
||||
JustifyContent,
|
||||
TextAlign,
|
||||
TextVariant,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
|
||||
export default function AddSnapAccountModal({
|
||||
onClose,
|
||||
isOpen,
|
||||
}: {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
}) {
|
||||
const t = useI18nContext();
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={onClose}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader onClose={onClose} margin={[4, 4, 4, 4]}>
|
||||
{t('settingAddSnapAccount')}
|
||||
</ModalHeader>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
padding={[4, 4, 4, 4]}
|
||||
flexDirection={FlexDirection.Column}
|
||||
justifyContent={JustifyContent.center}
|
||||
alignItems={AlignItems.center}
|
||||
>
|
||||
<Box marginBottom={4}>
|
||||
<img src="/images/add-snaps-image.svg" />
|
||||
</Box>
|
||||
<Text
|
||||
variant={TextVariant.bodyLgMedium}
|
||||
textAlign={TextAlign.Center}
|
||||
marginBottom={4}
|
||||
>
|
||||
{t('addSnapAccountModalDescription')}
|
||||
</Text>
|
||||
<Button
|
||||
variant={BUTTON_VARIANT.PRIMARY}
|
||||
block
|
||||
className="get-started_button"
|
||||
data-testid="get-started-button"
|
||||
onClick={() => {
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
{t('getStarted')}
|
||||
</Button>
|
||||
</Box>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
);
|
||||
}
|
1
ui/pages/keyring-snaps/add-snap-account-modal/index.ts
Normal file
1
ui/pages/keyring-snaps/add-snap-account-modal/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './add-snap-account-modal';
|
38
ui/pages/keyring-snaps/add-snap-account.tsx
Normal file
38
ui/pages/keyring-snaps/add-snap-account.tsx
Normal file
@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
import { ADD_SNAP_ACCOUNT_ROUTE } from '../../helpers/constants/routes';
|
||||
import {
|
||||
BackgroundColor,
|
||||
Display,
|
||||
JustifyContent,
|
||||
} from '../../helpers/constants/design-system';
|
||||
import { Box } from '../../components/component-library';
|
||||
import NewSnapAccountPage from './new-snap-account-page';
|
||||
import SnapAccountDetailPage from './snap-account-detail-page';
|
||||
|
||||
export default function AddSnapAccountPage() {
|
||||
return (
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
justifyContent={JustifyContent.center}
|
||||
backgroundColor={BackgroundColor.backgroundDefault}
|
||||
marginLeft={10}
|
||||
marginRight={10}
|
||||
>
|
||||
<Switch>
|
||||
<>
|
||||
<Route
|
||||
exact
|
||||
path={`${ADD_SNAP_ACCOUNT_ROUTE}/:snapId`}
|
||||
component={SnapAccountDetailPage}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path={ADD_SNAP_ACCOUNT_ROUTE}
|
||||
component={NewSnapAccountPage}
|
||||
/>
|
||||
</>
|
||||
</Switch>
|
||||
</Box>
|
||||
);
|
||||
}
|
1
ui/pages/keyring-snaps/constants.ts
Normal file
1
ui/pages/keyring-snaps/constants.ts
Normal file
@ -0,0 +1 @@
|
||||
export const METAMASK_DEVELOPER = 'metamask';
|
2
ui/pages/keyring-snaps/index.scss
Normal file
2
ui/pages/keyring-snaps/index.scss
Normal file
@ -0,0 +1,2 @@
|
||||
@import "./snap-account-detail-page/snap-account-detail-page";
|
||||
@import "./new-snap-account-page/new-snap-account-page";
|
1
ui/pages/keyring-snaps/index.ts
Normal file
1
ui/pages/keyring-snaps/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './add-snap-account';
|
2
ui/pages/keyring-snaps/new-snap-account-page/index.ts
Normal file
2
ui/pages/keyring-snaps/new-snap-account-page/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export { default } from './new-snap-account-page';
|
||||
export type { SnapCardProps, SnapDetails } from './new-snap-account-page';
|
@ -0,0 +1,32 @@
|
||||
.snap-account-page {
|
||||
$width-screen-sm-min: 85vw;
|
||||
$width-screen-md-min: 80vw;
|
||||
$width-screen-lg-min: 62vw;
|
||||
|
||||
@include screen-sm-min {
|
||||
width: $width-screen-sm-min;
|
||||
}
|
||||
|
||||
@include screen-md-min {
|
||||
width: $width-screen-md-min;
|
||||
}
|
||||
|
||||
@include screen-lg-min {
|
||||
width: $width-screen-lg-min;
|
||||
}
|
||||
|
||||
background-image: url('images/snap-account-page.svg');
|
||||
background-size: 100% auto;
|
||||
background-repeat: no-repeat;
|
||||
background-position: bottom;
|
||||
}
|
||||
|
||||
.snap-account-cards {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
.snap-account-color-text {
|
||||
background-image: linear-gradient(0.45deg, #f6851b, #43aefc);
|
||||
background-clip: text;
|
||||
color: transparent;
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
import { fireEvent, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
import messages from '../../../../app/_locales/en/messages.json';
|
||||
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||
import NewSnapAccountPage from '.';
|
||||
|
||||
const mockHistoryPush = jest.fn();
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useHistory: () => ({
|
||||
push: mockHistoryPush,
|
||||
}),
|
||||
}));
|
||||
|
||||
const mockState = {
|
||||
metamask: {
|
||||
snapRegistryList: {
|
||||
'a51ea3a8-f1b0-4613-9440-b80e2236713b': {
|
||||
id: 'a51ea3a8-f1b0-4613-9440-b80e2236713b',
|
||||
snapId: 'npm:@metamask/snap-simple-keyring',
|
||||
iconUrl: '',
|
||||
snapTitle: 'Metamask Simple Keyring',
|
||||
snapSlug: 'Secure your account with MetaMask Mobile',
|
||||
snapDescription:
|
||||
'A simple private key is a randomly generated string of characters that is used to sign transactions. This private key is stored securely within this snap.',
|
||||
tags: ['EOA'],
|
||||
developer: 'Metamask',
|
||||
website: 'https://www.consensys.net/',
|
||||
auditUrls: ['auditUrl1', 'auditUrl2'],
|
||||
version: '1.0.0',
|
||||
lastUpdated: 'April 20, 2023',
|
||||
},
|
||||
},
|
||||
snaps: {
|
||||
'npm:@metamask/snap-simple-keyring': {
|
||||
id: 'npm:@metamask/snap-simple-keyring',
|
||||
origin: 'npm:@metamask/snap-simple-keyring',
|
||||
version: '5.1.2',
|
||||
iconUrl: null,
|
||||
initialPermissions: {
|
||||
'endowment:manageAccount': {},
|
||||
},
|
||||
manifest: {
|
||||
description: 'An example keymanagement snap',
|
||||
proposedName: 'Example Key Management Test Snap',
|
||||
repository: {
|
||||
type: 'git',
|
||||
url: 'https://github.com/MetaMask/snap-simple-keyring.git',
|
||||
},
|
||||
source: {
|
||||
location: {
|
||||
npm: {
|
||||
filePath: 'dist/bundle.js',
|
||||
packageName: '@metamask/test-snap-account',
|
||||
registry: 'https://registry.npmjs.org',
|
||||
},
|
||||
},
|
||||
shasum: 'L1k+dT9Q+y3KfIqzaH09MpDZVPS9ZowEh9w01ZMTWMU=',
|
||||
},
|
||||
version: '0.0.1',
|
||||
},
|
||||
versionHistory: [
|
||||
{
|
||||
date: 1680686075921,
|
||||
origin: 'https://metamask.github.io',
|
||||
version: '0.0.1',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const renderComponent = (props = {}) => {
|
||||
const mockStore = configureMockStore([])(mockState);
|
||||
return renderWithProvider(<NewSnapAccountPage {...props} />, mockStore);
|
||||
};
|
||||
|
||||
describe('NewSnapAccountPage', () => {
|
||||
it('should render the popup', async () => {
|
||||
const { getByText } = renderComponent();
|
||||
const popupTitle = getByText(messages.settingAddSnapAccount.message);
|
||||
expect(popupTitle).toBeInTheDocument();
|
||||
|
||||
const closeButton = getByText(messages.getStarted.message);
|
||||
await fireEvent.click(closeButton);
|
||||
await waitFor(() => {
|
||||
expect(popupTitle).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it('should render the texts', async () => {
|
||||
const { getByText } = renderComponent();
|
||||
expect(
|
||||
getByText(messages.settingAddSnapAccount.message),
|
||||
).toBeInTheDocument();
|
||||
expect(
|
||||
getByText(messages.addSnapAccountModalDescription.message),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render all the keymanagement snaps', async () => {
|
||||
const { getAllByTestId } = renderComponent();
|
||||
const keyManagementSnaps = getAllByTestId('key-management-snap');
|
||||
expect(keyManagementSnaps.length).toBe(
|
||||
Object.values(mockState.metamask.snapRegistryList).length,
|
||||
);
|
||||
});
|
||||
|
||||
it('should go to snap detail page on click of snap carot', async () => {
|
||||
const { getAllByTestId } = renderComponent();
|
||||
const iconCarot = getAllByTestId('to-snap-detail')[0];
|
||||
|
||||
await fireEvent.click(iconCarot);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockHistoryPush).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should show configure button after clicking', async () => {
|
||||
const { getByTestId, getByText } = renderComponent();
|
||||
const configureButton = getByTestId('configure-snap-button');
|
||||
|
||||
await fireEvent.click(configureButton);
|
||||
await waitFor(() => {
|
||||
const configureSnapTitleInPopup = getByText(
|
||||
messages.configureSnapPopupTitle.message,
|
||||
);
|
||||
expect(configureSnapTitleInPopup).toBeInTheDocument();
|
||||
});
|
||||
|
||||
const closeButton = getByText(messages.getStarted.message);
|
||||
await fireEvent.click(closeButton);
|
||||
|
||||
await waitFor(() => {
|
||||
const configureSnapTitleInPopup = getByText(
|
||||
messages.configureSnapPopupTitle.message,
|
||||
);
|
||||
expect(configureSnapTitleInPopup).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,134 @@
|
||||
import { Snap } from '@metamask/snaps-utils';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { shallowEqual, useSelector } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { Box, Text } from '../../../components/component-library';
|
||||
import {
|
||||
AlignItems,
|
||||
Display,
|
||||
FlexDirection,
|
||||
FlexWrap,
|
||||
JustifyContent,
|
||||
TextColor,
|
||||
TextVariant,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
import {
|
||||
getSnaps,
|
||||
getsnapsAddSnapAccountModalDismissed,
|
||||
getSnapRegistry,
|
||||
} from '../../../selectors';
|
||||
import {
|
||||
setSnapsAddSnapAccountModalDismissed,
|
||||
updateSnapRegistry,
|
||||
} from '../../../store/actions';
|
||||
import AddSnapAccountModal from '../add-snap-account-modal';
|
||||
import SnapCard from '../snap-card/snap-card';
|
||||
|
||||
export interface SnapDetails {
|
||||
id: string;
|
||||
snapId: string;
|
||||
iconUrl: string;
|
||||
snapTitle: string;
|
||||
snapSlug: string;
|
||||
snapDescription: string;
|
||||
tags: string[];
|
||||
developer: string;
|
||||
website: string;
|
||||
auditUrls: string[];
|
||||
version: string;
|
||||
lastUpdated: string;
|
||||
}
|
||||
|
||||
export interface SnapCardProps extends SnapDetails {
|
||||
isInstalled: boolean;
|
||||
updateAvailable: boolean;
|
||||
}
|
||||
|
||||
export default function NewSnapAccountPage() {
|
||||
const t = useI18nContext();
|
||||
const history = useHistory();
|
||||
const [showPopup, setShowPopup] = useState(true);
|
||||
const installedSnaps: Record<string, Snap> = useSelector(getSnaps);
|
||||
const snapRegistryList: Record<string, SnapDetails> = useSelector(
|
||||
getSnapRegistry,
|
||||
shallowEqual,
|
||||
);
|
||||
useEffect(() => {
|
||||
updateSnapRegistry().catch((err) =>
|
||||
console.log(`Failed to fetch snap list: ${err}`),
|
||||
);
|
||||
}, []);
|
||||
|
||||
const hidePopup = async () => {
|
||||
setShowPopup(false);
|
||||
await setSnapsAddSnapAccountModalDismissed();
|
||||
};
|
||||
|
||||
const snapsAddSnapAccountModalDismissed = useSelector(
|
||||
getsnapsAddSnapAccountModalDismissed,
|
||||
);
|
||||
|
||||
return (
|
||||
<Box className="snap-account-page">
|
||||
<AddSnapAccountModal
|
||||
onClose={async () => {
|
||||
await hidePopup();
|
||||
}}
|
||||
isOpen={showPopup && !snapsAddSnapAccountModalDismissed}
|
||||
/>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
flexDirection={FlexDirection.Column}
|
||||
alignItems={AlignItems.center}
|
||||
justifyContent={JustifyContent.center}
|
||||
marginTop={11}
|
||||
marginBottom={11}
|
||||
>
|
||||
<Text variant={TextVariant.headingLg}>
|
||||
{t('snapCreateAccountTitle', [
|
||||
<Text
|
||||
variant={TextVariant.headingLg}
|
||||
as="span"
|
||||
className="snap-account-color-text"
|
||||
key="snap-title-2"
|
||||
>
|
||||
{t('snapCreateAccountTitle2')}
|
||||
</Text>,
|
||||
])}
|
||||
</Text>
|
||||
<Text variant={TextVariant.bodyMd} color={TextColor.textAlternative}>
|
||||
{t('snapCreateAccountSubtitle')}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box
|
||||
display={Display.Grid}
|
||||
flexWrap={FlexWrap.Wrap}
|
||||
gap={4}
|
||||
padding={[0, 10, 0, 10]}
|
||||
className="snap-account-cards"
|
||||
>
|
||||
{Object.values(snapRegistryList).map(
|
||||
(snap: SnapDetails, index: number) => {
|
||||
const foundSnap = Object.values(installedSnaps).find(
|
||||
(installedSnap) => installedSnap.id === snap.snapId,
|
||||
);
|
||||
|
||||
const isInstalled = Boolean(foundSnap);
|
||||
|
||||
return (
|
||||
<SnapCard
|
||||
{...snap}
|
||||
key={index}
|
||||
isInstalled={isInstalled}
|
||||
onClickFunc={() => {
|
||||
history.push(`/add-snap-account/${snap.id}`);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
@ -0,0 +1,232 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`SnapAccountDetails should take a snapshot 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mm-box snap-details-page mm-box--padding-10 mm-box--sm:padding-10 mm-box--md:padding-10 mm-box--lg:padding-10 mm-box--display-flex mm-box--flex-direction-column"
|
||||
>
|
||||
<div
|
||||
class="mm-box mm-box--margin-bottom-5"
|
||||
>
|
||||
<div
|
||||
class="mm-box mm-box--margin-bottom-4 mm-box--display-flex mm-box--flex-direction-row mm-box--align-items-center"
|
||||
>
|
||||
<button
|
||||
class="box mm-text mm-button-base mm-button-link mm-button-link--size-auto mm-text--body-md box--margin-right-4 box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-default box--background-color-transparent"
|
||||
>
|
||||
Create a Snap Account
|
||||
</button>
|
||||
<span
|
||||
class="box mm-icon mm-icon--size-md box--margin-right-4 box--display-inline-block box--flex-direction-row box--color-inherit"
|
||||
style="mask-image: url('./images/icons/arrow-right.svg');"
|
||||
/>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Metamask Simple Keyring
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="mm-box mm-box--display-flex mm-box--justify-content-space-between"
|
||||
>
|
||||
<div
|
||||
class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--align-items-center"
|
||||
>
|
||||
<h2
|
||||
class="box mm-text mm-text--heading-lg box--margin-right-1 box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Metamask Simple Keyring
|
||||
</h2>
|
||||
</div>
|
||||
<div
|
||||
class="mm-box"
|
||||
>
|
||||
<button
|
||||
class="box mm-text mm-button-base mm-button-base--size-md mm-button-primary mm-text--body-md box--padding-right-4 box--padding-left-4 box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-inverse box--background-color-primary-default box--rounded-pill"
|
||||
>
|
||||
Install snap
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mm-box mm-box--display-flex mm-box--flex-direction-row mm-box--align-items-center"
|
||||
>
|
||||
<div
|
||||
class="mm-box mm-box--margin-right-1 mm-box--padding-2 mm-box--sm:padding-2 mm-box--md:padding-2 mm-box--lg:padding-2 mm-box--display-flex mm-box--justify-content-center mm-box--align-items-center mm-box--border-color-border-muted mm-box--border-width-1 box--border-style-solid"
|
||||
style="border-radius: 50%; height: 32px; width: 32px;"
|
||||
>
|
||||
<img
|
||||
class="snap-detail-icon"
|
||||
src=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="box mm-tag box--margin-right-1 box--padding-right-1 box--padding-left-1 box--display-inline-block box--flex-direction-row box--justify-content-center box--align-items-center box--color-info-default box--background-color-info-muted box--rounded-pill box--border-color-info-muted box--border-width-1 box--border-style-solid"
|
||||
>
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm box--flex-direction-row box--color-info-default"
|
||||
>
|
||||
<div
|
||||
class="mm-box mm-box--display-flex mm-box--justify-content-center mm-box--align-items-center"
|
||||
>
|
||||
<span
|
||||
class="box mm-icon mm-icon--size-md box--display-inline-block box--flex-direction-row box--color-inherit"
|
||||
style="mask-image: url('./images/icons/star.svg');"
|
||||
/>
|
||||
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm box--flex-direction-row box--color-info-default"
|
||||
>
|
||||
By MetaMask
|
||||
</p>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="box mm-tag box--padding-right-1 box--padding-left-1 box--display-inline-block box--flex-direction-row box--justify-content-center box--align-items-center box--color-info-default box--background-color-info-muted box--rounded-pill box--border-color-info-muted box--border-width-1 box--border-style-solid"
|
||||
>
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm box--flex-direction-row box--color-info-default"
|
||||
>
|
||||
<div
|
||||
class="mm-box mm-box--display-flex mm-box--justify-content-center mm-box--align-items-center"
|
||||
>
|
||||
<span
|
||||
class="box mm-icon mm-icon--size-md box--display-inline-block box--flex-direction-row box--color-inherit"
|
||||
style="mask-image: url('./images/icons/star.svg');"
|
||||
/>
|
||||
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm box--flex-direction-row box--color-info-default"
|
||||
>
|
||||
Audited
|
||||
</p>
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mm-box mm-box--display-flex"
|
||||
>
|
||||
<div
|
||||
class="mm-box mm-box--display-flex mm-box--flex-direction-column mm-box--width-4/5"
|
||||
>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md-bold box--margin-bottom-2 box--flex-direction-row box--color-text-alternative"
|
||||
>
|
||||
Secure your account with MetaMask Mobile
|
||||
</p>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md box--flex-direction-row box--color-text-alternative"
|
||||
>
|
||||
A simple private key is a randomly generated string of characters that is used to sign transactions. This private key is stored securely within this snap.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="mm-box mm-box--padding-left-4 mm-box--display-flex mm-box--flex-direction-column mm-box--width-1/5"
|
||||
>
|
||||
<div
|
||||
class="mm-box mm-box--margin-bottom-4 mm-box--flex-direction-column"
|
||||
>
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm-bold box--margin-bottom-1 box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Tags
|
||||
</p>
|
||||
<div
|
||||
class="box mm-tag box--margin-right-1 box--padding-right-1 box--padding-left-1 box--display-inline-block box--flex-direction-row box--justify-content-center box--align-items-center box--background-color-background-default box--rounded-pill box--border-color-border-default box--border-width-1 box--border-style-solid"
|
||||
>
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm box--flex-direction-row box--color-text-alternative"
|
||||
>
|
||||
EOA
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mm-box mm-box--margin-bottom-4 mm-box--flex-direction-column"
|
||||
>
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm-bold box--margin-bottom-1 box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Developer
|
||||
</p>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Metamask
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="mm-box mm-box--margin-bottom-4 mm-box--flex-direction-column"
|
||||
>
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm-bold box--margin-bottom-1 box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Website
|
||||
</p>
|
||||
https://www.consensys.net/
|
||||
</div>
|
||||
<div
|
||||
class="mm-box mm-box--margin-bottom-4 mm-box--flex-direction-column"
|
||||
>
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm-bold box--margin-bottom-1 box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Audit
|
||||
</p>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
<a
|
||||
class="box mm-text mm-button-base mm-button-link mm-button-link--size-auto mm-text--body-md box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-default box--background-color-transparent"
|
||||
href="auditUrl1"
|
||||
>
|
||||
auditUrl1
|
||||
</a>
|
||||
</p>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
<a
|
||||
class="box mm-text mm-button-base mm-button-link mm-button-link--size-auto mm-text--body-md box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-default box--background-color-transparent"
|
||||
href="auditUrl2"
|
||||
>
|
||||
auditUrl2
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="mm-box mm-box--margin-bottom-4 mm-box--flex-direction-column"
|
||||
>
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm-bold box--margin-bottom-1 box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Version
|
||||
</p>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
1.0.0
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="mm-box mm-box--margin-bottom-4 mm-box--flex-direction-column"
|
||||
>
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm-bold box--margin-bottom-1 box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Updated
|
||||
</p>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
April 20, 2023
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
22
ui/pages/keyring-snaps/snap-account-detail-page/detail.tsx
Normal file
22
ui/pages/keyring-snaps/snap-account-detail-page/detail.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import { Box, Text } from '../../../components/component-library';
|
||||
import {
|
||||
FlexDirection,
|
||||
TextVariant,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
|
||||
const Detail = ({
|
||||
title,
|
||||
children,
|
||||
}: React.PropsWithChildren<{ title: string }>) => {
|
||||
return (
|
||||
<Box flexDirection={FlexDirection.Column} marginBottom={4}>
|
||||
<Text variant={TextVariant.bodySmBold} marginBottom={1}>
|
||||
{title}
|
||||
</Text>
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default Detail;
|
214
ui/pages/keyring-snaps/snap-account-detail-page/header.tsx
Normal file
214
ui/pages/keyring-snaps/snap-account-detail-page/header.tsx
Normal file
@ -0,0 +1,214 @@
|
||||
import React, { useState } from 'react';
|
||||
import ConfigureSnapPopup, {
|
||||
ConfigureSnapPopupType,
|
||||
} from '../../../components/app/configure-snap-popup/configure-snap-popup';
|
||||
import {
|
||||
BUTTON_VARIANT,
|
||||
Box,
|
||||
Button,
|
||||
Icon,
|
||||
IconName,
|
||||
Tag,
|
||||
Text,
|
||||
} from '../../../components/component-library';
|
||||
import {
|
||||
AlignItems,
|
||||
BackgroundColor,
|
||||
BorderColor,
|
||||
Display,
|
||||
FlexDirection,
|
||||
JustifyContent,
|
||||
TextColor,
|
||||
TextVariant,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
import { SnapCardProps } from '../new-snap-account-page/new-snap-account-page';
|
||||
import { METAMASK_DEVELOPER } from '../constants';
|
||||
|
||||
export const SnapDetailHeader = ({
|
||||
updateAvailable,
|
||||
snapTitle,
|
||||
isInstalled,
|
||||
iconUrl,
|
||||
developer,
|
||||
auditUrls,
|
||||
website,
|
||||
}: Pick<
|
||||
SnapCardProps,
|
||||
| 'updateAvailable'
|
||||
| 'snapTitle'
|
||||
| 'isInstalled'
|
||||
| 'iconUrl'
|
||||
| 'developer'
|
||||
| 'auditUrls'
|
||||
| 'website'
|
||||
>) => {
|
||||
const t = useI18nContext();
|
||||
const [showConfigPopover, setShowConfigPopover] = useState(false);
|
||||
const [showConfigPopoverType, setShowConfigPopoverType] =
|
||||
useState<ConfigureSnapPopupType>(ConfigureSnapPopupType.INSTALL);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box marginBottom={5}>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
flexDirection={FlexDirection.Row}
|
||||
alignItems={AlignItems.center}
|
||||
marginBottom={4}
|
||||
>
|
||||
<Button
|
||||
variant={BUTTON_VARIANT.LINK}
|
||||
marginRight={4}
|
||||
onClick={() => history.back()}
|
||||
>
|
||||
{t('snapDetailsCreateASnapAccount')}
|
||||
</Button>
|
||||
<Icon name={IconName.ArrowRight} marginRight={4} />
|
||||
<Text>{snapTitle}</Text>
|
||||
</Box>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
justifyContent={JustifyContent.spaceBetween}
|
||||
>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
flexDirection={FlexDirection.Row}
|
||||
alignItems={AlignItems.center}
|
||||
>
|
||||
<Text variant={TextVariant.headingLg} marginRight={1}>
|
||||
{snapTitle}
|
||||
</Text>
|
||||
{isInstalled && (
|
||||
<Tag
|
||||
label={t('snapDetailsInstalled') as string}
|
||||
labelProps={{
|
||||
color: TextColor.textAlternative,
|
||||
}}
|
||||
className=""
|
||||
height={2}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
<Box>
|
||||
{isInstalled && updateAvailable && (
|
||||
<Button
|
||||
variant={BUTTON_VARIANT.PRIMARY}
|
||||
marginRight={1}
|
||||
onClick={() => {
|
||||
setShowConfigPopoverType(ConfigureSnapPopupType.INSTALL);
|
||||
setShowConfigPopover(true);
|
||||
}}
|
||||
>
|
||||
{t('snapUpdateAvailable')}
|
||||
</Button>
|
||||
)}
|
||||
{isInstalled && (
|
||||
<Button
|
||||
variant={BUTTON_VARIANT.PRIMARY}
|
||||
onClick={() => {
|
||||
setShowConfigPopoverType(ConfigureSnapPopupType.CONFIGURE);
|
||||
setShowConfigPopover(true);
|
||||
}}
|
||||
>
|
||||
{t('snapConfigure')}
|
||||
</Button>
|
||||
)}
|
||||
{!isInstalled && (
|
||||
<Button
|
||||
variant={BUTTON_VARIANT.PRIMARY}
|
||||
onClick={() => {
|
||||
setShowConfigPopoverType(ConfigureSnapPopupType.INSTALL);
|
||||
setShowConfigPopover(true);
|
||||
}}
|
||||
>
|
||||
{t('snapInstall')}
|
||||
</Button>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
flexDirection={FlexDirection.Row}
|
||||
alignItems={AlignItems.center}
|
||||
>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
justifyContent={JustifyContent.center}
|
||||
alignItems={AlignItems.center}
|
||||
style={{
|
||||
borderRadius: '50%',
|
||||
height: '32px',
|
||||
width: '32px',
|
||||
}}
|
||||
borderWidth={1}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
padding={[2, 2, 2, 2]}
|
||||
marginRight={1}
|
||||
>
|
||||
<img src={iconUrl} className="snap-detail-icon" />
|
||||
</Box>
|
||||
{developer.toLowerCase() === METAMASK_DEVELOPER && (
|
||||
<Tag
|
||||
color={TextColor.infoDefault}
|
||||
backgroundColor={BackgroundColor.infoMuted}
|
||||
borderColor={BackgroundColor.infoMuted}
|
||||
label={
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
justifyContent={JustifyContent.center}
|
||||
alignItems={AlignItems.center}
|
||||
>
|
||||
<Icon name={IconName.Star} />{' '}
|
||||
<Text
|
||||
color={TextColor.infoDefault}
|
||||
variant={TextVariant.bodySm}
|
||||
>
|
||||
{t('snapCreatedByMetaMask')}
|
||||
</Text>
|
||||
</Box>
|
||||
}
|
||||
labelProps={{
|
||||
color: TextColor.infoDefault,
|
||||
}}
|
||||
className=""
|
||||
marginRight={1}
|
||||
/>
|
||||
)}
|
||||
{auditUrls.length > 0 && (
|
||||
<Tag
|
||||
className=""
|
||||
color={TextColor.infoDefault}
|
||||
backgroundColor={BackgroundColor.infoMuted}
|
||||
borderColor={BackgroundColor.infoMuted}
|
||||
label={
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
justifyContent={JustifyContent.center}
|
||||
alignItems={AlignItems.center}
|
||||
>
|
||||
<Icon name={IconName.Star} />{' '}
|
||||
<Text
|
||||
color={TextColor.infoDefault}
|
||||
variant={TextVariant.bodySm}
|
||||
>
|
||||
{t('snapIsAudited')}
|
||||
</Text>
|
||||
</Box>
|
||||
}
|
||||
labelProps={{
|
||||
color: TextColor.infoDefault,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
<ConfigureSnapPopup
|
||||
type={showConfigPopoverType}
|
||||
isOpen={showConfigPopover}
|
||||
onClose={() => setShowConfigPopover(false)}
|
||||
link={website}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
1
ui/pages/keyring-snaps/snap-account-detail-page/index.ts
Normal file
1
ui/pages/keyring-snaps/snap-account-detail-page/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './snap-account-detail-page';
|
@ -0,0 +1,24 @@
|
||||
|
||||
.snap-details-page {
|
||||
$width-screen-sm-min: 85vw;
|
||||
$width-screen-md-min: 80vw;
|
||||
$width-screen-lg-min: 62vw;
|
||||
|
||||
@include screen-sm-min {
|
||||
width: $width-screen-sm-min;
|
||||
}
|
||||
|
||||
@include screen-md-min {
|
||||
width: $width-screen-md-min;
|
||||
}
|
||||
|
||||
@include screen-lg-min {
|
||||
width: $width-screen-lg-min;
|
||||
}
|
||||
|
||||
|
||||
.snap-detail-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
@ -0,0 +1,239 @@
|
||||
import { fireEvent, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
import thunk from 'redux-thunk';
|
||||
import messages from '../../../../app/_locales/en/messages.json';
|
||||
import mockState from '../../../../test/data/mock-state.json';
|
||||
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||
import SnapAccountDetailPage from '.';
|
||||
|
||||
const snap = {
|
||||
id: 'a51ea3a8-f1b0-4613-9440-b80e2236713b',
|
||||
snapId: 'npm:@metamask/snap-simple-keyring',
|
||||
iconUrl: '',
|
||||
snapTitle: 'Metamask Simple Keyring',
|
||||
snapSlug: 'Secure your account with MetaMask Mobile',
|
||||
snapDescription:
|
||||
'A simple private key is a randomly generated string of characters that is used to sign transactions. This private key is stored securely within this snap.',
|
||||
tags: ['EOA'],
|
||||
developer: 'Metamask',
|
||||
website: 'https://www.consensys.net/',
|
||||
auditUrls: ['auditUrl1', 'auditUrl2'],
|
||||
version: '1.0.0',
|
||||
lastUpdated: 'April 20, 2023',
|
||||
};
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useHistory: () => ({
|
||||
push: jest.fn(),
|
||||
}),
|
||||
useParams: jest
|
||||
.fn()
|
||||
.mockReturnValue({ snapId: 'a51ea3a8-f1b0-4613-9440-b80e2236713b' }),
|
||||
}));
|
||||
|
||||
const renderComponent = (state, props = {}) => {
|
||||
const mockStore = configureMockStore([thunk])(state);
|
||||
return renderWithProvider(
|
||||
<SnapAccountDetailPage {...props} />,
|
||||
mockStore,
|
||||
`/add-snap-account/${snap.id}`,
|
||||
);
|
||||
};
|
||||
describe('SnapAccountDetails', () => {
|
||||
it('should take a snapshot', () => {
|
||||
const { container } = renderComponent(mockState);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the snap details', async () => {
|
||||
const { getAllByText, getByText } = renderComponent(mockState);
|
||||
|
||||
expect(getAllByText(snap.snapTitle).length).toBe(2);
|
||||
expect(getByText(snap.snapSlug)).toBeInTheDocument();
|
||||
expect(getByText(snap.snapDescription)).toBeInTheDocument();
|
||||
snap.tags.forEach((tag) => {
|
||||
expect(getByText(tag)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(getByText(snap.developer)).toBeInTheDocument();
|
||||
expect(getByText(snap.website)).toBeInTheDocument();
|
||||
|
||||
snap.auditUrls.forEach((auditUrl) => {
|
||||
expect(getByText(auditUrl)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
expect(getByText(snap.version)).toBeInTheDocument();
|
||||
expect(getByText(snap.lastUpdated)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('it should render configure if snap is already installed', async () => {
|
||||
const mockStateForConfig = {
|
||||
metamask: {
|
||||
snapRegistryList: {
|
||||
'a51ea3a8-f1b0-4613-9440-b80e2236713b': {
|
||||
id: 'a51ea3a8-f1b0-4613-9440-b80e2236713b',
|
||||
snapId: 'npm:@metamask/snap-simple-keyring',
|
||||
iconUrl: '',
|
||||
snapTitle: 'Metamask Simple Keyring',
|
||||
snapSlug: 'Secure your account with MetaMask Mobile',
|
||||
snapDescription:
|
||||
'A simple private key is a randomly generated string of characters that is used to sign transactions. This private key is stored securely within this snap.',
|
||||
tags: ['EOA'],
|
||||
developer: 'Metamask',
|
||||
website: 'https://www.consensys.net/',
|
||||
auditUrls: ['auditUrl1', 'auditUrl2'],
|
||||
version: '1.0.0',
|
||||
lastUpdated: 'April 20, 2023',
|
||||
},
|
||||
},
|
||||
snaps: {
|
||||
'npm:@metamask/snap-simple-keyring': {
|
||||
id: 'npm:@metamask/snap-simple-keyring',
|
||||
origin: 'npm:@metamask/snap-simple-keyring',
|
||||
version: '1.0.0',
|
||||
iconUrl: null,
|
||||
initialPermissions: {
|
||||
'endowment:manageAccount': {},
|
||||
},
|
||||
manifest: {
|
||||
description: 'An example keymanagement snap',
|
||||
proposedName: 'Example Key Management Test Snap',
|
||||
repository: {
|
||||
type: 'git',
|
||||
url: 'https://github.com/MetaMask/snap-simple-keyring.git',
|
||||
},
|
||||
source: {
|
||||
location: {
|
||||
npm: {
|
||||
filePath: 'dist/bundle.js',
|
||||
packageName: '@metamask/test-snap-account',
|
||||
registry: 'https://registry.npmjs.org',
|
||||
},
|
||||
},
|
||||
shasum: 'L1k+dT9Q+y3KfIqzaH09MpDZVPS9ZowEh9w01ZMTWMU=',
|
||||
},
|
||||
version: '0.0.1',
|
||||
},
|
||||
versionHistory: [
|
||||
{
|
||||
date: 1680686075921,
|
||||
origin: 'https://metamask.github.io',
|
||||
version: '0.0.1',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const { queryByText, getByText } = renderComponent(mockStateForConfig);
|
||||
expect(queryByText(messages.snapInstall.message)).not.toBeInTheDocument();
|
||||
|
||||
expect(
|
||||
queryByText(messages.snapUpdateAvailable.message),
|
||||
).not.toBeInTheDocument();
|
||||
|
||||
const configureButton = getByText(messages.snapConfigure.message);
|
||||
expect(configureButton).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('it should render install if snap is not installed', async () => {
|
||||
const { queryByText, getByText, getAllByText } = renderComponent(mockState);
|
||||
expect(
|
||||
queryByText(messages.snapUpdateAvailable.message),
|
||||
).not.toBeInTheDocument();
|
||||
|
||||
expect(queryByText(messages.snapConfigure.message)).not.toBeInTheDocument();
|
||||
|
||||
const installButton = getByText(messages.snapInstall.message);
|
||||
expect(installButton).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(installButton);
|
||||
|
||||
// expect(mockInstallSnapFromSnapAccounts).toHaveBeenCalledTimes(1);
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
getAllByText(messages.configureSnapPopupInstallTitle.message).length,
|
||||
).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
it('it should render update if snap update is available', async () => {
|
||||
const mockStateForConfig = {
|
||||
metamask: {
|
||||
snapRegistryList: {
|
||||
'a51ea3a8-f1b0-4613-9440-b80e2236713b': {
|
||||
id: 'a51ea3a8-f1b0-4613-9440-b80e2236713b',
|
||||
snapId: 'npm:@metamask/snap-simple-keyring',
|
||||
iconUrl: '',
|
||||
snapTitle: 'MetaMask Simple Keyring',
|
||||
snapSlug: 'Secure your account with MetaMask Mobile',
|
||||
snapDescription:
|
||||
'A simple private key is a randomly generated string of characters that is used to sign transactions. This private key is stored securely within this snap.',
|
||||
tags: ['EOA'],
|
||||
developer: 'MetaMask',
|
||||
website: 'https://www.consensys.net/',
|
||||
auditUrls: ['auditUrl1', 'auditUrl2'],
|
||||
version: '1.0.0',
|
||||
lastUpdated: 'April 20, 2023',
|
||||
},
|
||||
},
|
||||
snaps: {
|
||||
'npm:@metamask/snap-simple-keyring': {
|
||||
id: 'npm:@metamask/snap-simple-keyring',
|
||||
origin: 'npm:@metamask/snap-simple-keyring',
|
||||
version: '0.0.0',
|
||||
iconUrl: null,
|
||||
initialPermissions: {
|
||||
'endowment:manageAccount': {},
|
||||
},
|
||||
manifest: {
|
||||
description: 'An example keymanagement snap',
|
||||
proposedName: 'Example Key Management Test Snap',
|
||||
repository: {
|
||||
type: 'git',
|
||||
url: 'https://github.com/MetaMask/snap-simple-keyring.git',
|
||||
},
|
||||
source: {
|
||||
location: {
|
||||
npm: {
|
||||
filePath: 'dist/bundle.js',
|
||||
packageName: '@metamask/test-snap-account',
|
||||
registry: 'https://registry.npmjs.org',
|
||||
},
|
||||
},
|
||||
shasum: 'L1k+dT9Q+y3KfIqzaH09MpDZVPS9ZowEh9w01ZMTWMU=',
|
||||
},
|
||||
version: '0.0.1',
|
||||
},
|
||||
versionHistory: [
|
||||
{
|
||||
date: 1680686075921,
|
||||
origin: 'https://metamask.github.io',
|
||||
version: '0.0.1',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const { queryByText, getByText } = renderComponent(mockStateForConfig);
|
||||
expect(queryByText(messages.snapInstall.message)).not.toBeInTheDocument();
|
||||
|
||||
expect(
|
||||
queryByText(messages.snapUpdateAvailable.message),
|
||||
).toBeInTheDocument();
|
||||
|
||||
const configureButton = getByText(messages.snapConfigure.message);
|
||||
expect(configureButton).toBeInTheDocument();
|
||||
|
||||
fireEvent.click(configureButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
getByText(messages.configureSnapPopupTitle.message),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,147 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useHistory, useParams } from 'react-router-dom';
|
||||
import semver from 'semver';
|
||||
import {
|
||||
BUTTON_VARIANT,
|
||||
Box,
|
||||
Button,
|
||||
Tag,
|
||||
Text,
|
||||
} from '../../../components/component-library';
|
||||
import {
|
||||
BlockSize,
|
||||
Display,
|
||||
FlexDirection,
|
||||
TextColor,
|
||||
TextVariant,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import {
|
||||
ADD_SNAP_ACCOUNT_ROUTE,
|
||||
SNAPS_VIEW_ROUTE,
|
||||
} from '../../../helpers/constants/routes';
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
import { getSnapRegistry, getSnaps } from '../../../selectors';
|
||||
import { SnapDetails } from '../new-snap-account-page';
|
||||
import Detail from './detail';
|
||||
import { SnapDetailHeader } from './header';
|
||||
|
||||
interface RouteParams {
|
||||
snapId: string;
|
||||
}
|
||||
|
||||
export default function SnapAccountDetailPage() {
|
||||
const t = useI18nContext();
|
||||
const history = useHistory();
|
||||
|
||||
const { snapId } = useParams<RouteParams>();
|
||||
const installedSnaps = useSelector(getSnaps);
|
||||
const snapRegistryList: Record<string, SnapDetails> =
|
||||
useSelector(getSnapRegistry);
|
||||
const currentSnap = Object.values(snapRegistryList).find(
|
||||
(snap) => snap.id === snapId,
|
||||
);
|
||||
|
||||
if (!currentSnap) {
|
||||
history.push(ADD_SNAP_ACCOUNT_ROUTE);
|
||||
return null;
|
||||
}
|
||||
|
||||
const isInstalled = Boolean(installedSnaps[currentSnap.snapId]);
|
||||
|
||||
const updateAvailable =
|
||||
isInstalled &&
|
||||
semver.gt(currentSnap.version, installedSnaps[currentSnap.snapId].version);
|
||||
|
||||
return (
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
flexDirection={FlexDirection.Column}
|
||||
padding={[10, 10, 10, 10]}
|
||||
className="snap-details-page"
|
||||
>
|
||||
<SnapDetailHeader
|
||||
{...currentSnap}
|
||||
updateAvailable={updateAvailable}
|
||||
isInstalled={isInstalled}
|
||||
/>
|
||||
<Box display={Display.Flex}>
|
||||
<Box
|
||||
width={BlockSize.FourFifths}
|
||||
display={Display.Flex}
|
||||
flexDirection={FlexDirection.Column}
|
||||
>
|
||||
<Text
|
||||
variant={TextVariant.bodyMdBold}
|
||||
marginBottom={2}
|
||||
color={TextColor.textAlternative}
|
||||
>
|
||||
{currentSnap.snapSlug}
|
||||
</Text>
|
||||
<Text variant={TextVariant.bodyMd} color={TextColor.textAlternative}>
|
||||
{currentSnap.snapDescription}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box
|
||||
width={BlockSize.OneFifth}
|
||||
display={Display.Flex}
|
||||
flexDirection={FlexDirection.Column}
|
||||
paddingLeft={4}
|
||||
>
|
||||
<Detail title={t('snapDetailTags')}>
|
||||
{currentSnap.tags.map((tag, index) => {
|
||||
return (
|
||||
<Tag
|
||||
label={tag}
|
||||
labelProps={{
|
||||
color: TextColor.textAlternative,
|
||||
}}
|
||||
className=""
|
||||
key={`tag-${index}`}
|
||||
marginRight={1}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Detail>
|
||||
<Detail title={t('snapDetailDeveloper')}>
|
||||
<Text variant={TextVariant.bodyMd}>{currentSnap.developer}</Text>
|
||||
</Detail>
|
||||
<Detail title={t('snapDetailWebsite')}>{currentSnap.website}</Detail>
|
||||
<Detail title={t('snapDetailAudits')}>
|
||||
{currentSnap.auditUrls.map((auditLink, index) => {
|
||||
return (
|
||||
<Text key={`audit-link-${index}`}>
|
||||
<Button variant={BUTTON_VARIANT.LINK} href={auditLink}>
|
||||
{auditLink}
|
||||
</Button>
|
||||
</Text>
|
||||
);
|
||||
})}
|
||||
</Detail>
|
||||
<Detail title={t('snapDetailVersion')}>
|
||||
<Text variant={TextVariant.bodyMd}>{currentSnap.version}</Text>
|
||||
</Detail>
|
||||
<Detail title={t('snapDetailLastUpdated')}>
|
||||
<Text variant={TextVariant.bodyMd}>{currentSnap.lastUpdated}</Text>
|
||||
</Detail>
|
||||
{isInstalled && (
|
||||
<Box>
|
||||
<Button
|
||||
variant={BUTTON_VARIANT.LINK}
|
||||
onClick={() =>
|
||||
history.push(
|
||||
`${SNAPS_VIEW_ROUTE}/${encodeURIComponent(
|
||||
currentSnap.snapId,
|
||||
)}`,
|
||||
)
|
||||
}
|
||||
>
|
||||
{t('snapDetailManageSnap')}
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`SnapCard should render 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="mm-box mm-box--padding-4 mm-box--sm:padding-4 mm-box--md:padding-4 mm-box--lg:padding-4 mm-box--display-flex mm-box--flex-direction-column mm-box--background-color-background-default mm-box--rounded-sm mm-box--border-color-border-muted mm-box--border-width-1 box--border-style-solid"
|
||||
data-testid="key-management-snap"
|
||||
>
|
||||
<div
|
||||
class="mm-box mm-box--margin-bottom-2 mm-box--display-flex mm-box--justify-content-space-between mm-box--align-items-center"
|
||||
>
|
||||
<div
|
||||
class="mm-box mm-box--margin-right-1 mm-box--padding-2 mm-box--sm:padding-2 mm-box--md:padding-2 mm-box--lg:padding-2 mm-box--display-flex mm-box--justify-content-center mm-box--align-items-center mm-box--border-color-border-muted mm-box--border-width-1 box--border-style-solid"
|
||||
style="border-radius: 50%; height: 32px; width: 32px;"
|
||||
>
|
||||
<div
|
||||
class="mm-box snap-detail-icon mm-box--display-flex mm-box--justify-content-center mm-box--align-items-center"
|
||||
>
|
||||
<p
|
||||
class="box mm-text mm-text--body-md box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
M
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="box mm-text mm-button-base mm-button-base--size-md mm-button-secondary mm-text--body-md box--padding-right-4 box--padding-left-4 box--display-inline-flex box--flex-direction-row box--justify-content-center box--align-items-center box--color-primary-default box--background-color-transparent box--rounded-pill box--border-color-primary-default box--border-style-solid box--border-width-1"
|
||||
data-testid="install-snap-button"
|
||||
>
|
||||
Install
|
||||
</button>
|
||||
</div>
|
||||
<p
|
||||
class="box mm-text mm-text--body-sm box--margin-bottom-2 box--flex-direction-row box--color-text-alternative"
|
||||
>
|
||||
Metamask Simple Keyring
|
||||
</p>
|
||||
<h3
|
||||
class="box mm-text mm-text--heading-md box--margin-bottom-auto box--flex-direction-row box--color-text-default"
|
||||
>
|
||||
Secure your account with MetaMask Mobile
|
||||
</h3>
|
||||
<div
|
||||
class="mm-box mm-box--display-flex mm-box--justify-content-space-between"
|
||||
>
|
||||
<span
|
||||
class="box mm-icon mm-icon--size-md box--margin-left-auto box--display-inline-block box--flex-direction-row box--color-icon-alternative"
|
||||
data-testid="to-snap-detail"
|
||||
style="mask-image: url('./images/icons/arrow-2-right.svg');"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
1
ui/pages/keyring-snaps/snap-card/index.ts
Normal file
1
ui/pages/keyring-snaps/snap-card/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './snap-card';
|
75
ui/pages/keyring-snaps/snap-card/snap-card.test.tsx
Normal file
75
ui/pages/keyring-snaps/snap-card/snap-card.test.tsx
Normal file
@ -0,0 +1,75 @@
|
||||
import { fireEvent, waitFor } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
import thunk from 'redux-thunk';
|
||||
import messages from '../../../../app/_locales/en/messages.json';
|
||||
import { renderWithProvider } from '../../../../test/lib/render-helpers';
|
||||
import SnapCard from './snap-card';
|
||||
|
||||
const mockHistoryPush = jest.fn();
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'),
|
||||
useHistory: () => ({
|
||||
push: mockHistoryPush,
|
||||
}),
|
||||
}));
|
||||
|
||||
const snap = {
|
||||
id: 'a51ea3a8-f1b0-4613-9440-b80e2236713b',
|
||||
snapId: 'npm:@metamask/snap-simple-keyring',
|
||||
iconUrl: '',
|
||||
snapTitle: 'Metamask Simple Keyring',
|
||||
snapSlug: 'Secure your account with MetaMask Mobile',
|
||||
snapDescription:
|
||||
'A simple private key is a randomly generated string of characters that is used to sign transactions. This private key is stored securely within this snap.',
|
||||
tags: ['EOA'],
|
||||
developer: 'Metamask',
|
||||
website: 'https://www.consensys.net/',
|
||||
auditUrls: ['auditUrl1', 'auditUrl2'],
|
||||
version: '1.0.0',
|
||||
lastUpdated: 'April 20, 2023',
|
||||
};
|
||||
|
||||
const renderComponent = (props) => {
|
||||
const mockStore = configureMockStore([thunk])({});
|
||||
return renderWithProvider(<SnapCard {...props} />, mockStore);
|
||||
};
|
||||
describe('SnapCard', () => {
|
||||
it('should render', () => {
|
||||
const { container } = renderComponent(snap);
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should show install button', async () => {
|
||||
const { getByText } = renderComponent({ ...snap, isInstalled: false });
|
||||
expect(getByText(snap.snapTitle)).toBeInTheDocument();
|
||||
expect(getByText(snap.snapSlug)).toBeInTheDocument();
|
||||
const installButton = getByText(messages.install.message);
|
||||
|
||||
expect(installButton).toBeInTheDocument();
|
||||
fireEvent.click(installButton);
|
||||
await waitFor(() => {
|
||||
expect(mockHistoryPush).toHaveBeenCalledWith(
|
||||
`/add-snap-account/${snap.id}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should show configure button', async () => {
|
||||
const { getByText } = renderComponent({ ...snap, isInstalled: true });
|
||||
expect(getByText(snap.snapTitle)).toBeInTheDocument();
|
||||
expect(getByText(snap.snapSlug)).toBeInTheDocument();
|
||||
const configureButton = getByText(messages.snapConfigure.message);
|
||||
|
||||
expect(configureButton).toBeInTheDocument();
|
||||
fireEvent.click(configureButton);
|
||||
|
||||
// shows popover
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
getByText(messages.configureSnapPopupTitle.message),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
139
ui/pages/keyring-snaps/snap-card/snap-card.tsx
Normal file
139
ui/pages/keyring-snaps/snap-card/snap-card.tsx
Normal file
@ -0,0 +1,139 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import ConfigureSnapPopup, {
|
||||
ConfigureSnapPopupType,
|
||||
} from '../../../components/app/configure-snap-popup';
|
||||
import {
|
||||
BUTTON_VARIANT,
|
||||
Box,
|
||||
Button,
|
||||
Icon,
|
||||
IconName,
|
||||
Text,
|
||||
} from '../../../components/component-library';
|
||||
import {
|
||||
AlignItems,
|
||||
BackgroundColor,
|
||||
BorderColor,
|
||||
BorderRadius,
|
||||
Color,
|
||||
Display,
|
||||
FlexDirection,
|
||||
IconColor,
|
||||
JustifyContent,
|
||||
TextVariant,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
import { SnapCardProps } from '../new-snap-account-page/new-snap-account-page';
|
||||
|
||||
export default function SnapCard({
|
||||
iconUrl,
|
||||
snapTitle,
|
||||
snapSlug,
|
||||
isInstalled,
|
||||
website,
|
||||
id,
|
||||
onClickFunc,
|
||||
}: Pick<
|
||||
SnapCardProps,
|
||||
'iconUrl' | 'snapTitle' | 'snapSlug' | 'isInstalled' | 'website' | 'id'
|
||||
> & { onClickFunc: () => void }) {
|
||||
const t = useI18nContext();
|
||||
const history = useHistory();
|
||||
const [showConfigPopover, setShowConfigPopover] = useState(false);
|
||||
|
||||
return (
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
flexDirection={FlexDirection.Column}
|
||||
backgroundColor={BackgroundColor.backgroundDefault}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
borderRadius={BorderRadius.SM}
|
||||
borderWidth={1}
|
||||
padding={[4, 4, 4, 4]}
|
||||
data-testid="key-management-snap"
|
||||
>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
justifyContent={JustifyContent.spaceBetween}
|
||||
alignItems={AlignItems.center}
|
||||
marginBottom={2}
|
||||
>
|
||||
<Box
|
||||
display={Display.Flex}
|
||||
justifyContent={JustifyContent.center}
|
||||
alignItems={AlignItems.center}
|
||||
style={{
|
||||
borderRadius: '50%',
|
||||
height: '32px',
|
||||
width: '32px',
|
||||
backgroundColor: BackgroundColor.infoDefault,
|
||||
}}
|
||||
borderWidth={1}
|
||||
borderColor={BorderColor.borderMuted}
|
||||
padding={[2, 2, 2, 2]}
|
||||
marginRight={1}
|
||||
>
|
||||
{iconUrl ? (
|
||||
<img src={iconUrl} className="snap-detail-icon" />
|
||||
) : (
|
||||
// This is the fallback icon based on the first letter of the snap name.
|
||||
<Box
|
||||
className="snap-detail-icon"
|
||||
display={Display.Flex}
|
||||
justifyContent={JustifyContent.center}
|
||||
alignItems={AlignItems.center}
|
||||
>
|
||||
<Text>{snapTitle ? snapTitle[0] : '?'}</Text>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
{isInstalled ? (
|
||||
<Button
|
||||
data-testid="configure-snap-button"
|
||||
variant={BUTTON_VARIANT.SECONDARY}
|
||||
onClick={() => setShowConfigPopover(true)}
|
||||
>
|
||||
{t('snapConfigure')}
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
data-testid="install-snap-button"
|
||||
variant={BUTTON_VARIANT.SECONDARY}
|
||||
onClick={() => {
|
||||
history.push(`/add-snap-account/${id}`);
|
||||
}}
|
||||
>
|
||||
{t('install')}
|
||||
</Button>
|
||||
)}
|
||||
</Box>
|
||||
<Text
|
||||
variant={TextVariant.bodySm}
|
||||
color={Color.textAlternative}
|
||||
marginBottom={2}
|
||||
>
|
||||
{snapTitle}
|
||||
</Text>
|
||||
<Text variant={TextVariant.headingMd} marginBottom="auto">
|
||||
{snapSlug}
|
||||
</Text>
|
||||
|
||||
<Box display={Display.Flex} justifyContent={JustifyContent.spaceBetween}>
|
||||
<Icon
|
||||
data-testid="to-snap-detail"
|
||||
name={IconName.Arrow2Right}
|
||||
color={IconColor.iconAlternative}
|
||||
onClick={onClickFunc}
|
||||
marginLeft="auto"
|
||||
/>
|
||||
</Box>
|
||||
<ConfigureSnapPopup
|
||||
isOpen={showConfigPopover}
|
||||
type={ConfigureSnapPopupType.CONFIGURE}
|
||||
onClose={() => setShowConfigPopover(false)}
|
||||
link={website}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
/** Please import your files in alphabetical order **/
|
||||
@import 'add-nft/index';
|
||||
@import 'keyring-snaps/index';
|
||||
@import 'import-token/index';
|
||||
@import 'asset/asset';
|
||||
@import 'confirm-import-token/index';
|
||||
|
@ -42,6 +42,9 @@ import TokenDetailsPage from '../token-details';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
import Notifications from '../notifications';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
import AddSnapAccountPage from '../keyring-snaps/add-snap-account';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(desktop)
|
||||
import { registerOnDesktopDisconnect } from '../../hooks/desktopHooks';
|
||||
import DesktopErrorPage from '../desktop-error';
|
||||
@ -90,6 +93,9 @@ import {
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
NOTIFICATIONS_ROUTE,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
ADD_SNAP_ACCOUNT_ROUTE,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(desktop)
|
||||
DESKTOP_PAIRING_ROUTE,
|
||||
DESKTOP_ERROR_ROUTE,
|
||||
@ -335,6 +341,14 @@ export default class Routes extends Component {
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
}
|
||||
<Authenticated path={NEW_ACCOUNT_ROUTE} component={CreateAccountPage} />
|
||||
{
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
<Authenticated
|
||||
path={ADD_SNAP_ACCOUNT_ROUTE}
|
||||
component={AddSnapAccountPage}
|
||||
/>
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
}
|
||||
<Authenticated
|
||||
path={`${CONNECT_ROUTE}/:id`}
|
||||
component={PermissionsConnect}
|
||||
|
@ -1537,3 +1537,15 @@ export function getSnapsInstallPrivacyWarningShown(state) {
|
||||
return snapsInstallPrivacyWarningShown;
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
export function getsnapsAddSnapAccountModalDismissed(state) {
|
||||
const { snapsAddSnapAccountModalDismissed } = state.metamask;
|
||||
|
||||
return snapsAddSnapAccountModalDismissed;
|
||||
}
|
||||
|
||||
export function getSnapRegistry(state) {
|
||||
const { snapRegistryList } = state.metamask;
|
||||
return snapRegistryList;
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
@ -6,6 +6,9 @@ import { ThunkAction } from 'redux-thunk';
|
||||
import { Action, AnyAction } from 'redux';
|
||||
import { ethErrors, serializeError } from 'eth-rpc-errors';
|
||||
import { Hex, Json } from '@metamask/utils';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
import { v4 as uuidV4 } from 'uuid';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import {
|
||||
AssetsContractController,
|
||||
BalanceMap,
|
||||
@ -16,6 +19,9 @@ import { PayloadAction } from '@reduxjs/toolkit';
|
||||
import { GasFeeController } from '@metamask/gas-fee-controller';
|
||||
import { PermissionsRequest } from '@metamask/permission-controller';
|
||||
import { NonEmptyArray } from '@metamask/controller-utils';
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
import { HandlerType } from '@metamask/snaps-utils';
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
import { getMethodDataAsync } from '../helpers/utils/transactions.util';
|
||||
import switchDirection from '../../shared/lib/switch-direction';
|
||||
import {
|
||||
@ -32,6 +38,9 @@ import {
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
getNotifications,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
getPermissionSubjects,
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
} from '../selectors';
|
||||
import {
|
||||
computeEstimatedGasLimit,
|
||||
@ -1120,9 +1129,46 @@ export function enableSnap(
|
||||
export function removeSnap(
|
||||
snapId: string,
|
||||
): ThunkAction<void, MetaMaskReduxState, unknown, AnyAction> {
|
||||
return async (dispatch: MetaMaskReduxDispatch) => {
|
||||
await submitRequestToBackground('removeSnap', [snapId]);
|
||||
await forceUpdateMetamaskState(dispatch);
|
||||
return async (dispatch: MetaMaskReduxDispatch, getState) => {
|
||||
dispatch(showLoadingIndication());
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
const subjects = getPermissionSubjects(getState()) as {
|
||||
[k: string]: { permissions: Record<string, any> };
|
||||
};
|
||||
|
||||
const isAccountsSnap =
|
||||
subjects[snapId]?.permissions?.snap_manageAccounts !== undefined;
|
||||
|
||||
try {
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
if (isAccountsSnap) {
|
||||
const accounts = (await handleSnapRequest({
|
||||
snapId,
|
||||
origin: 'metamask',
|
||||
handler: HandlerType.OnRpcRequest,
|
||||
request: {
|
||||
id: uuidV4(),
|
||||
jsonrpc: '2.0',
|
||||
method: 'keyring_listAccounts',
|
||||
},
|
||||
})) as unknown as any[];
|
||||
for (const account of accounts) {
|
||||
dispatch(removeAccount(account.address.toLowerCase()));
|
||||
}
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
///: BEGIN:ONLY_INCLUDE_IN(snaps)
|
||||
|
||||
await submitRequestToBackground('removeSnap', [snapId]);
|
||||
await forceUpdateMetamaskState(dispatch);
|
||||
} catch (error) {
|
||||
dispatch(displayWarning(error));
|
||||
throw error;
|
||||
} finally {
|
||||
dispatch(hideLoadingIndication());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -1135,9 +1181,10 @@ export async function handleSnapRequest(args: {
|
||||
origin: string;
|
||||
handler: string;
|
||||
request: {
|
||||
id?: string;
|
||||
jsonrpc: '2.0';
|
||||
method: string;
|
||||
params: Record<string, any>;
|
||||
params?: Record<string, any>;
|
||||
};
|
||||
}): Promise<void> {
|
||||
return submitRequestToBackground('handleSnapRequest', [args]);
|
||||
@ -4343,3 +4390,15 @@ export function setSnapsInstallPrivacyWarningShownStatus(shown: boolean) {
|
||||
};
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
||||
///: BEGIN:ONLY_INCLUDE_IN(keyring-snaps)
|
||||
export async function setSnapsAddSnapAccountModalDismissed() {
|
||||
await submitRequestToBackground('setSnapsAddSnapAccountModalDismissed', [
|
||||
true,
|
||||
]);
|
||||
}
|
||||
|
||||
export async function updateSnapRegistry() {
|
||||
await submitRequestToBackground('updateSnapRegistry', []);
|
||||
}
|
||||
///: END:ONLY_INCLUDE_IN
|
||||
|
89
yarn.lock
89
yarn.lock
@ -4186,7 +4186,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask/eth-sig-util@npm:5.0.2, @metamask/eth-sig-util@npm:^5.0.0, @metamask/eth-sig-util@npm:^5.0.1, @metamask/eth-sig-util@npm:^5.0.2":
|
||||
"@metamask/eth-sig-util@npm:5.0.2":
|
||||
version: 5.0.2
|
||||
resolution: "@metamask/eth-sig-util@npm:5.0.2"
|
||||
dependencies:
|
||||
@ -4200,6 +4200,20 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask/eth-sig-util@npm:^5.0.0, @metamask/eth-sig-util@npm:^5.0.1, @metamask/eth-sig-util@npm:^5.0.2, @metamask/eth-sig-util@npm:^5.1.0":
|
||||
version: 5.1.0
|
||||
resolution: "@metamask/eth-sig-util@npm:5.1.0"
|
||||
dependencies:
|
||||
"@ethereumjs/util": ^8.0.6
|
||||
bn.js: ^4.12.0
|
||||
ethereum-cryptography: ^2.0.0
|
||||
ethjs-util: ^0.1.6
|
||||
tweetnacl: ^1.0.3
|
||||
tweetnacl-util: ^0.15.1
|
||||
checksum: c639e3bf91625faeb0230a6314f0b2d05e8f5e2989542d3e0eed1d21b7b286e1860f68629870fd7e568c1a599b3993c4210403fb4c84a625fb1e75ef676eab4f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask/eth-simple-keyring@npm:^5.0.0":
|
||||
version: 5.0.0
|
||||
resolution: "@metamask/eth-simple-keyring@npm:5.0.0"
|
||||
@ -4212,6 +4226,22 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask/eth-snap-keyring@npm:^0.1.3":
|
||||
version: 0.1.3
|
||||
resolution: "@metamask/eth-snap-keyring@npm:0.1.3"
|
||||
dependencies:
|
||||
"@ethereumjs/tx": ^4.1.2
|
||||
"@metamask/eth-sig-util": ^5.1.0
|
||||
"@metamask/keyring-api": ^0.1.3
|
||||
"@metamask/snaps-controllers": ^0.35.2-flask.1
|
||||
"@metamask/utils": ^6.1.0
|
||||
"@types/uuid": ^9.0.1
|
||||
superstruct: ^1.0.3
|
||||
uuid: ^9.0.0
|
||||
checksum: f77cb75fcbd05024693488c42d244f78e7ee87f3f295ac95971182a78f1399428acc5f10aaf6d6ba08fa28cc3519d4e644226ac7cdf22e77a8659f945d9686ce
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask/eth-token-tracker@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "@metamask/eth-token-tracker@npm:4.0.0"
|
||||
@ -4300,6 +4330,21 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask/keyring-api@npm:^0.1.3":
|
||||
version: 0.1.3
|
||||
resolution: "@metamask/keyring-api@npm:0.1.3"
|
||||
dependencies:
|
||||
"@metamask/providers": ^11.0.0
|
||||
"@metamask/snaps-controllers": ^0.35.2-flask.1
|
||||
"@metamask/snaps-utils": ^0.35.2-flask.1
|
||||
"@metamask/utils": ^6.0.1
|
||||
"@types/uuid": ^9.0.1
|
||||
superstruct: ^1.0.3
|
||||
uuid: ^9.0.0
|
||||
checksum: 2307b5162dbb66d82f7d8ab8e9f1c3a0ef581b915702187b6b8fa5d8e8533838d0539d6f35853ef4f25096f13c9dbf4505fadff247b73f6d489d9c904015d21c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask/logo@npm:^3.1.1":
|
||||
version: 3.1.1
|
||||
resolution: "@metamask/logo@npm:3.1.1"
|
||||
@ -4705,7 +4750,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask/snaps-controllers-flask@npm:@metamask/snaps-controllers@0.35.2-flask.1":
|
||||
"@metamask/snaps-controllers-flask@npm:@metamask/snaps-controllers@0.35.2-flask.1, @metamask/snaps-controllers@npm:^0.35.2-flask.1":
|
||||
version: 0.35.2-flask.1
|
||||
resolution: "@metamask/snaps-controllers@npm:0.35.2-flask.1"
|
||||
dependencies:
|
||||
@ -4952,7 +4997,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@metamask/utils@npm:^6.0.0, @metamask/utils@npm:^6.0.1":
|
||||
"@metamask/utils@npm:^6.0.0, @metamask/utils@npm:^6.0.1, @metamask/utils@npm:^6.1.0":
|
||||
version: 6.1.0
|
||||
resolution: "@metamask/utils@npm:6.1.0"
|
||||
dependencies:
|
||||
@ -7925,17 +7970,17 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:*, @types/node@npm:>=13.7.0, @types/node@npm:^18.15.11":
|
||||
version: 18.16.12
|
||||
resolution: "@types/node@npm:18.16.12"
|
||||
checksum: 90b316c097a059534870bc8e358c7996d99e3bb4395c88a91b893b925ad34e32ff1177009ec6c16a6467266414dca64ec9613e9e6bb3f91b6de0ab629d3bb3b9
|
||||
"@types/node@npm:*, @types/node@npm:>=13.7.0":
|
||||
version: 20.2.5
|
||||
resolution: "@types/node@npm:20.2.5"
|
||||
checksum: 38ce7c7e9d76880dc632f71d71e0d5914fcda9d5e9a7095d6c339abda55ca4affb0f2a882aeb29398f8e09d2c5151f0b6586c81c8ccdfe529c34b1ea3337425e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:^16.0.0, @types/node@npm:^16.11.26, @types/node@npm:^16.7.10":
|
||||
version: 16.18.31
|
||||
resolution: "@types/node@npm:16.18.31"
|
||||
checksum: 1e0bbbdcfdb80ebb9c5544a58b9692964dca08175a9d2f787a1ed8c75c253d106d56cf7d94c5ba0b44e1627000d093d599f995aeb657f5edbf577e66565b017a
|
||||
version: 16.18.34
|
||||
resolution: "@types/node@npm:16.18.34"
|
||||
checksum: 35c0ffe09687578d002ceb7e706d0ba450546aeb3d2716f28691f2af0063bd274dbde0f741d087ea217f2a8db413eb700d22dfb4f08a67986ff801423bd7be8d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -7946,6 +7991,13 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:^18.15.11":
|
||||
version: 18.16.16
|
||||
resolution: "@types/node@npm:18.16.16"
|
||||
checksum: 0efad726dd1e0bef71c392c708fc5d78c5b39c46b0ac5186fee74de4ccb1b2e847b3fa468da67d62812f56569da721b15bf31bdc795e6c69b56c73a45079ed2d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/normalize-package-data@npm:^2.4.0":
|
||||
version: 2.4.0
|
||||
resolution: "@types/normalize-package-data@npm:2.4.0"
|
||||
@ -8229,10 +8281,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/uuid@npm:^9.0.0":
|
||||
version: 9.0.1
|
||||
resolution: "@types/uuid@npm:9.0.1"
|
||||
checksum: c472b8a77cbeded4bc529220b8611afa39bd64677f507838f8083d8aac8033b1f88cb9ddaa2f8589e0dcd2317291d0f6e1379f82d5ceebd6f74f3b4825288e00
|
||||
"@types/uuid@npm:^9.0.0, @types/uuid@npm:^9.0.1":
|
||||
version: 9.0.2
|
||||
resolution: "@types/uuid@npm:9.0.2"
|
||||
checksum: 1754bcf3444e1e3aeadd6e774fc328eb53bc956665e2e8fb6ec127aa8e1f43d9a224c3d22a9a6233dca8dd81a12dc7fed4d84b8876dd5ec82d40f574f7ff8b68
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -10804,7 +10856,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bn.js@npm:^4.0.0, bn.js@npm:^4.1.0, bn.js@npm:^4.1.1, bn.js@npm:^4.11.0, bn.js@npm:^4.11.7, bn.js@npm:^4.11.8, bn.js@npm:^4.11.9":
|
||||
"bn.js@npm:^4.0.0, bn.js@npm:^4.1.0, bn.js@npm:^4.1.1, bn.js@npm:^4.11.0, bn.js@npm:^4.11.7, bn.js@npm:^4.11.8, bn.js@npm:^4.11.9, bn.js@npm:^4.12.0":
|
||||
version: 4.12.0
|
||||
resolution: "bn.js@npm:4.12.0"
|
||||
checksum: 39afb4f15f4ea537b55eaf1446c896af28ac948fdcf47171961475724d1bb65118cca49fa6e3d67706e4790955ec0e74de584e45c8f1ef89f46c812bee5b5a12
|
||||
@ -11745,9 +11797,9 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001426, caniuse-lite@npm:^1.0.30001449":
|
||||
version: 1.0.30001481
|
||||
resolution: "caniuse-lite@npm:1.0.30001481"
|
||||
checksum: 8200a043c191b4fd4fe0beda37a58fd61869c895ab93f87bdd0420e5927453f48434d716ce9da8552ff6c3ecc4dcd1366354cda3a134f3cc844af741574a7cab
|
||||
version: 1.0.30001497
|
||||
resolution: "caniuse-lite@npm:1.0.30001497"
|
||||
checksum: 6721120f9a588c442a81cf32f911b4e97a88cb129c27bd2cb0fce6447ad058baa12affa1ee09c517f9e088c7ce74964154d032b6631f66d75dd37c6bc59a67f6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -24447,6 +24499,7 @@ __metadata:
|
||||
"@metamask/eth-json-rpc-middleware": ^11.0.0
|
||||
"@metamask/eth-keyring-controller": ^10.0.1
|
||||
"@metamask/eth-ledger-bridge-keyring": ^0.15.0
|
||||
"@metamask/eth-snap-keyring": ^0.1.3
|
||||
"@metamask/eth-token-tracker": ^4.0.0
|
||||
"@metamask/eth-trezor-keyring": ^1.0.0
|
||||
"@metamask/etherscan-link": ^2.2.0
|
||||
|
Loading…
Reference in New Issue
Block a user