From cc8d48775703306ae5ead0a9f276051e234a9d9d Mon Sep 17 00:00:00 2001
From: MetaMask Bot
Date: Fri, 30 Aug 2024 09:15:46 +0000
Subject: [PATCH 01/41] Version v12.4.0
---
CHANGELOG.md | 411 ++++++++++++++++++++++++++++++++++++++++++++++++++-
package.json | 2 +-
2 files changed, 411 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 41f3091f878e..4a26b1fb619d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,414 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [12.4.0]
+### Uncategorized
+- fix: flaky test `Test Snap Interactive UI test interactive ui elements` ([#26792](https://github.com/MetaMask/metamask-extension/pull/26792))
+- feat: Update Polygon from `MATIC` to `POL` ([#26671](https://github.com/MetaMask/metamask-extension/pull/26671))
+- feat: implement client side malicious network request detection ([#25839](https://github.com/MetaMask/metamask-extension/pull/25839))
+- fix: Improve migration 121.1 state validation ([#26773](https://github.com/MetaMask/metamask-extension/pull/26773))
+- chore: Bump Snaps dependencies ([#26675](https://github.com/MetaMask/metamask-extension/pull/26675))
+- refactor: extract Send-specific functionality out of AssetPicker ([#26558](https://github.com/MetaMask/metamask-extension/pull/26558))
+- fix: rename migration 126 to 121.1 ([#26742](https://github.com/MetaMask/metamask-extension/pull/26742))
+- chore: Bump `storybook`, `@storybook/*` to `^7.6.20`, `storybook-dark-mode` from `^3.0.3` to `^4.0.2` ([#26703](https://github.com/MetaMask/metamask-extension/pull/26703))
+- fix: Sentry app state null data to show null as value. ([#26522](https://github.com/MetaMask/metamask-extension/pull/26522))
+- chore: Master sync ([#26737](https://github.com/MetaMask/metamask-extension/pull/26737))
+- fix: Stop using a hardcoded Snap ID for notifications ([#26739](https://github.com/MetaMask/metamask-extension/pull/26739))
+- chore: MMI Fixes passing the state to route using history.push ([#26722](https://github.com/MetaMask/metamask-extension/pull/26722))
+- Merge origin/develop into master-sync
+- test: Add integration test for insufficient gas ([#26711](https://github.com/MetaMask/metamask-extension/pull/26711))
+- test: [Snaps E2E] Add changes to fix flakiness in Snaps UI Images test ([#26725](https://github.com/MetaMask/metamask-extension/pull/26725))
+- test: Add integration test for gas estimate failed alert ([#26681](https://github.com/MetaMask/metamask-extension/pull/26681))
+- fix: flaky test `Click bridge button @no-mmi loads portfolio tab from asset overview when flag is turned off` ([#26654](https://github.com/MetaMask/metamask-extension/pull/26654))
+- fix: flaky test `Navigation Signature - Different signature types initiates and queues multiple signatures and confirms` ([#26707](https://github.com/MetaMask/metamask-extension/pull/26707))
+- feat: adding context to get current confirmation in re-designed confirmation pages PR-1 ([#26587](https://github.com/MetaMask/metamask-extension/pull/26587))
+- fix: `wallet_addEthereumChain` does not attach a `result` under certain conditions ([#26726](https://github.com/MetaMask/metamask-extension/pull/26726))
+- fix: Add IOTX icon ([#26723](https://github.com/MetaMask/metamask-extension/pull/26723))
+- test: Add integration tests for network busy alert ([#26679](https://github.com/MetaMask/metamask-extension/pull/26679))
+- feat: Temporarily hide Approve redesigned pages ([#26676](https://github.com/MetaMask/metamask-extension/pull/26676))
+- perf: use an interstitial page to load `popup.html`; load scripts using `defer`ed script tags ([#26555](https://github.com/MetaMask/metamask-extension/pull/26555))
+- feat: Add metrics to track where signature rejection occurred ([#26469](https://github.com/MetaMask/metamask-extension/pull/26469))
+- chore: update @metamask/bitcoin-wallet-snap to 0.5.0 ([#26701](https://github.com/MetaMask/metamask-extension/pull/26701))
+- fix: adding missing token images ([#26708](https://github.com/MetaMask/metamask-extension/pull/26708))
+- feat: Added Edit networks screen modal ([#26097](https://github.com/MetaMask/metamask-extension/pull/26097))
+- perf: add trace for UI startup ([#26636](https://github.com/MetaMask/metamask-extension/pull/26636))
+- fix: Address design review on contract interaction and deployment red… ([#26659](https://github.com/MetaMask/metamask-extension/pull/26659))
+- test: [Snaps E2E] Add test cases for signature confirmations redesign to signature insights snaps test ([#26691](https://github.com/MetaMask/metamask-extension/pull/26691))
+- feat: updated ui for adding chain id screen ([#25777](https://github.com/MetaMask/metamask-extension/pull/25777))
+- fix: update moonbeam and moonriver network and token logos ([#26677](https://github.com/MetaMask/metamask-extension/pull/26677))
+- chore: MMI adds back the current Tx confirmation view to MMI ([#26539](https://github.com/MetaMask/metamask-extension/pull/26539))
+- fix(snaps): Use ApprovalType instead DIALOG_APPROVAL_TYPES in confirmation page ([#26655](https://github.com/MetaMask/metamask-extension/pull/26655))
+- fix: catch error for getTokenStandardAndDetails ([#26269](https://github.com/MetaMask/metamask-extension/pull/26269))
+- chore: Master sync ([#26641](https://github.com/MetaMask/metamask-extension/pull/26641))
+- chore: update gitignore ([#26642](https://github.com/MetaMask/metamask-extension/pull/26642))
+- fix: flaky test `Phishing Detection should navigate the user to PhishFort to dispute a Phishfort Block` ([#26651](https://github.com/MetaMask/metamask-extension/pull/26651))
+- fix: flaky tests `Sentry errors before initialization, after opting into metrics @no-mmi should capture UI application state`... ([#26648](https://github.com/MetaMask/metamask-extension/pull/26648))
+- fix: flaky test `Vault Decryptor Page is able to decrypt the vault us..` due to empty file load ([#26612](https://github.com/MetaMask/metamask-extension/pull/26612))
+- Merge branch 'develop' into master-sync
+- fix: flaky test `Increase Token Allowance increases token spending ca..` ([#26640](https://github.com/MetaMask/metamask-extension/pull/26640))
+- chore: bump smart transactions controller ([#26644](https://github.com/MetaMask/metamask-extension/pull/26644))
+- chore: Polish multichain token list styles ([#26300](https://github.com/MetaMask/metamask-extension/pull/26300))
+- Merge origin/develop into master-sync
+- feat: upgrade network controller to v20 ([#26150](https://github.com/MetaMask/metamask-extension/pull/26150))
+- docs: Add publish a release to Sentry flow steps ([#26605](https://github.com/MetaMask/metamask-extension/pull/26605))
+- chore: set bridge network allowlists from feature flags ([#26147](https://github.com/MetaMask/metamask-extension/pull/26147))
+- chore: anonymize send analytic properties #26627 ([#26628](https://github.com/MetaMask/metamask-extension/pull/26628))
+- chore: add user IDs to send page analytics ([#26600](https://github.com/MetaMask/metamask-extension/pull/26600))
+- fix: bump accounts controller and migration to fix undefined selectedAccount ([#26573](https://github.com/MetaMask/metamask-extension/pull/26573))
+- feat: Integrate Snaps into the redesigned confirmations ([#26435](https://github.com/MetaMask/metamask-extension/pull/26435))
+- refactor: Replace usages of the deprecated `setProviderType` ([#22619](https://github.com/MetaMask/metamask-extension/pull/22619))
+- refactor: Use generic helper function to initiate signatures ([#26584](https://github.com/MetaMask/metamask-extension/pull/26584))
+- test: [Snaps E2E] Update snaps dialog test to include Custom dialog type ([#26598](https://github.com/MetaMask/metamask-extension/pull/26598))
+- feat: new receive flow ([#26148](https://github.com/MetaMask/metamask-extension/pull/26148))
+- fix: remove speed up and cancel controller validation ([#26492](https://github.com/MetaMask/metamask-extension/pull/26492))
+- fix: flaky test `Test Snap Name Lookup tests name-lookup functionalit...` ([#26583](https://github.com/MetaMask/metamask-extension/pull/26583))
+- feat: Add contract deployment redesigned transaction screen ([#26382](https://github.com/MetaMask/metamask-extension/pull/26382))
+- feat: add transaction performance metrics ([#26332](https://github.com/MetaMask/metamask-extension/pull/26332))
+- test: add tests for insufficient funds alert ([#26512](https://github.com/MetaMask/metamask-extension/pull/26512))
+- feat: account watcher e2e ([#26524](https://github.com/MetaMask/metamask-extension/pull/26524))
+- feat: update add team label workflow ([#26548](https://github.com/MetaMask/metamask-extension/pull/26548))
+- feat: Add approval static simulation ([#26514](https://github.com/MetaMask/metamask-extension/pull/26514))
+- fix: Snapshot unit tests ([#26585](https://github.com/MetaMask/metamask-extension/pull/26585))
+- chore: Rename `permittedChains` permission to `endowment:permitted-chains` ([#26534](https://github.com/MetaMask/metamask-extension/pull/26534))
+- feat: Redesign Approve confirmation ([#26464](https://github.com/MetaMask/metamask-extension/pull/26464))
+- feat: Enable hardware wallets for smart transactions, sign a transaction only once ([#26251](https://github.com/MetaMask/metamask-extension/pull/26251))
+- fix: Allowlist Snap UI card component ([#26565](https://github.com/MetaMask/metamask-extension/pull/26565))
+- fix(deps): Bump `@metamask/eth-json-rpc-middleware` to `^14.0.0`, `@metamask/transaction-controller` to `^35.1.1` ([#26143](https://github.com/MetaMask/metamask-extension/pull/26143))
+- fix: adding warning for origin on redesigned pages ([#26306](https://github.com/MetaMask/metamask-extension/pull/26306))
+- fix: track `swapAndSend` transaction type ([#26535](https://github.com/MetaMask/metamask-extension/pull/26535))
+- feat: added AccountWatcher as preinstalled snap and added to menu list ([#26402](https://github.com/MetaMask/metamask-extension/pull/26402))
+- fix: stick add team label version to commit hash ([#26540](https://github.com/MetaMask/metamask-extension/pull/26540))
+- fix: correct duplicate notifications event tracking in global menu ([#26525](https://github.com/MetaMask/metamask-extension/pull/26525))
+- feat: migrate protect intrinsics test to e2e ([#26197](https://github.com/MetaMask/metamask-extension/pull/26197))
+- fix: NetworkChangeToast width in wide screen mode ([#26532](https://github.com/MetaMask/metamask-extension/pull/26532))
+- fix: missing deadline in swaps stx status screen ([#25779](https://github.com/MetaMask/metamask-extension/pull/25779))
+- fix: Snap Address component UI/UX (Snaps custom UI) ([#26477](https://github.com/MetaMask/metamask-extension/pull/26477))
+- feat(snaps): Removed Snaps name-lookup permission code fences ([#26393](https://github.com/MetaMask/metamask-extension/pull/26393))
+- docs: Include MV2 build commands in README ([#26486](https://github.com/MetaMask/metamask-extension/pull/26486))
+- test: add `driver.clickElementAndWaitForWindowToClose` helper method ([#26449](https://github.com/MetaMask/metamask-extension/pull/26449))
+- chore: Integrate SnapInsightsController ([#26411](https://github.com/MetaMask/metamask-extension/pull/26411))
+- feat: Update @blockaid/ppom_release to release 1.5.2 ([#26494](https://github.com/MetaMask/metamask-extension/pull/26494))
+- chore: Master sync ([#26497](https://github.com/MetaMask/metamask-extension/pull/26497))
+- Merge origin/develop into master-sync
+- feat(notifications): use shared libraries NotificationServicesController ([#26480](https://github.com/MetaMask/metamask-extension/pull/26480))
+- perf: add parallel fetching for the network fee dropdown ([#26489](https://github.com/MetaMask/metamask-extension/pull/26489))
+- chore: remove token and nft detection modals ([#26403](https://github.com/MetaMask/metamask-extension/pull/26403))
+- chore: Add Near Icon ([#26459](https://github.com/MetaMask/metamask-extension/pull/26459))
+- fix: Restore `responsive` e2e driver option ([#25932](https://github.com/MetaMask/metamask-extension/pull/25932))
+- chore: downgrade prettier-eslint to match prettier version ([#26145](https://github.com/MetaMask/metamask-extension/pull/26145))
+- test: Add manual scenario for upgrade testing ([#26317](https://github.com/MetaMask/metamask-extension/pull/26317))
+- build(chore): switch to `defer` since it guarantees execution order once chunked ([#26425](https://github.com/MetaMask/metamask-extension/pull/26425))
+- fix: Update send transactions with custom nonce.csv ([#26451](https://github.com/MetaMask/metamask-extension/pull/26451))
+- fix: `rpcIdentifierUtility` client side grouping before emitting CustomRPC event ([#26266](https://github.com/MetaMask/metamask-extension/pull/26266))
+- feat(notifications): use notification services push controller ([#26448](https://github.com/MetaMask/metamask-extension/pull/26448))
+- feat: Add footers to Snap home pages ([#26463](https://github.com/MetaMask/metamask-extension/pull/26463))
+- fix: Remove double padding on Snap home page ([#26462](https://github.com/MetaMask/metamask-extension/pull/26462))
+- chore(webpack): update `html-bundler-webpack-plugin` from `v3.6.5` to `v3.17.3` ([#26371](https://github.com/MetaMask/metamask-extension/pull/26371))
+- chore: Master sync ([#26395](https://github.com/MetaMask/metamask-extension/pull/26395))
+- chore: Bump Snaps packages ([#26086](https://github.com/MetaMask/metamask-extension/pull/26086))
+- fix: Improve AccountListMenu/Item performance ([#26379](https://github.com/MetaMask/metamask-extension/pull/26379))
+- fix: Codespaces `corepack enable` ([#25161](https://github.com/MetaMask/metamask-extension/pull/25161))
+- fix: display toast message if user quickly sends transaction on different networks ([#26114](https://github.com/MetaMask/metamask-extension/pull/26114))
+- fix: problem with origins in the Snaps permission UI ([#26422](https://github.com/MetaMask/metamask-extension/pull/26422))
+- feat: Add abstraction for Snaps permissions ([#25175](https://github.com/MetaMask/metamask-extension/pull/25175))
+- test: add transaction contract interaction integration tests ([#26272](https://github.com/MetaMask/metamask-extension/pull/26272))
+- fix: timeout and "Rerun failed tests" ([#26239](https://github.com/MetaMask/metamask-extension/pull/26239))
+- chore: migrate BridgeController to BaseController v2 ([#26109](https://github.com/MetaMask/metamask-extension/pull/26109))
+- feat: Enable why did you render ([#26339](https://github.com/MetaMask/metamask-extension/pull/26339))
+- fix: Delete invalid `SelectedNetworkController` state ([#26428](https://github.com/MetaMask/metamask-extension/pull/26428))
+- test: ensure bridge button handles clicks according to feature flags ([#25812](https://github.com/MetaMask/metamask-extension/pull/25812))
+- build(webpack): polyfill `setImmediate` ([#26398](https://github.com/MetaMask/metamask-extension/pull/26398))
+- feat: feature-flagged cross-chain swaps route [METABRIDGE-867] ([#25811](https://github.com/MetaMask/metamask-extension/pull/25811))
+- chore: Remove i18n translations from Developer Options Settings Page ([#26380](https://github.com/MetaMask/metamask-extension/pull/26380))
+- fix: Do not break application if no token details are found using getTokenStandardAndDetails ([#26324](https://github.com/MetaMask/metamask-extension/pull/26324))
+- fix: Flaky contract interaction test ([#26420](https://github.com/MetaMask/metamask-extension/pull/26420))
+- fix: Enter key on Create Account checkbox should not trigger show/hide ([#26394](https://github.com/MetaMask/metamask-extension/pull/26394))
+- fix: notifications use better events ([#26410](https://github.com/MetaMask/metamask-extension/pull/26410))
+- fix: Restore snaps-controllers version following patch ([#26412](https://github.com/MetaMask/metamask-extension/pull/26412))
+- fix: Improve hex copy button ([#26384](https://github.com/MetaMask/metamask-extension/pull/26384))
+- refactor: use core profile syncing controllers. ([#26370](https://github.com/MetaMask/metamask-extension/pull/26370))
+- test: snap account contract interaction ([#26234](https://github.com/MetaMask/metamask-extension/pull/26234))
+- feat: updated SSK version in e2e and added test for creating multiple… ([#26378](https://github.com/MetaMask/metamask-extension/pull/26378))
+- Merge origin/develop into master-sync
+- chore: MMI move duck and selector to TS ([#26125](https://github.com/MetaMask/metamask-extension/pull/26125))
+- refactor(notifications): use contentful package as dev dependency ([#26381](https://github.com/MetaMask/metamask-extension/pull/26381))
+- fix: remove submitRequest from dapp permission ([#26319](https://github.com/MetaMask/metamask-extension/pull/26319))
+- feat: Add integration test for blockaid on contract interaction ([#26366](https://github.com/MetaMask/metamask-extension/pull/26366))
+- refactor: add performance tracing infrastructure ([#26044](https://github.com/MetaMask/metamask-extension/pull/26044))
+- refactor: replace deprecated mixins with Text component in slippage-buttons ([#25638](https://github.com/MetaMask/metamask-extension/pull/25638))
+- refactor: replace deprecated mixins with text component in loading-swaps-quotes ([#25553](https://github.com/MetaMask/metamask-extension/pull/25553))
+- feat: Add metrics for alerts (transactions redesign) ([#26121](https://github.com/MetaMask/metamask-extension/pull/26121))
+- fix(25350): fix flakey token importing e2e test ([#26351](https://github.com/MetaMask/metamask-extension/pull/26351))
+- fix: enable Save button on Add Contact page for address input ([#26155](https://github.com/MetaMask/metamask-extension/pull/26155))
+- test: Add test for migration 120.2 and fix docs ([#26333](https://github.com/MetaMask/metamask-extension/pull/26333))
+- chore: normalize separator in `content` on the `viewport` `meta` tag ([#26268](https://github.com/MetaMask/metamask-extension/pull/26268))
+- fix: Stop logging pipeline stream errors in the service worker if they match 'Premature close' ([#26336](https://github.com/MetaMask/metamask-extension/pull/26336))
+- build: add alternative build process to enable faster developer builds ([#22506](https://github.com/MetaMask/metamask-extension/pull/22506))
+- fix: issue where `setNetworkClientIdForDomain` was called without checking whether the origin was eligible for setting its own network ([#26323](https://github.com/MetaMask/metamask-extension/pull/26323))
+- fix: get permit and order signatures token decimals ([#26292](https://github.com/MetaMask/metamask-extension/pull/26292))
+- feat: Update Redesign Signature Permit to show ellipsis at max 15 digits ([#26227](https://github.com/MetaMask/metamask-extension/pull/26227))
+- fix: remove the ability to send to btc accounts in send page ([#26271](https://github.com/MetaMask/metamask-extension/pull/26271))
+- fix: Adding migration 125 to remove Deprecated TxController Key from state ([#26267](https://github.com/MetaMask/metamask-extension/pull/26267))
+- fix: Revert "fix: remove submitRequest from dapp permission" ([#26293](https://github.com/MetaMask/metamask-extension/pull/26293))
+- refactor: convert `icon-factory.js` to typescript ([#23823](https://github.com/MetaMask/metamask-extension/pull/23823))
+- fix(26065): remove persisted state mostRecentRetrievedState after initialization if no errors ([#26206](https://github.com/MetaMask/metamask-extension/pull/26206))
+- refactor: ENABLE_MV3 flag cleanup ([#26059](https://github.com/MetaMask/metamask-extension/pull/26059))
+- test: fix flaky test Import flow @no-mmi Import wallet using Secret Recovery Phrase ([#26275](https://github.com/MetaMask/metamask-extension/pull/26275))
+- chore: Fully remove `eth_sign` ([#24756](https://github.com/MetaMask/metamask-extension/pull/24756))
+- fix: remove submitRequest from dapp permission ([#26276](https://github.com/MetaMask/metamask-extension/pull/26276))
+- chore: Update `actions/cache` from v3 to v4 ([#26020](https://github.com/MetaMask/metamask-extension/pull/26020))
+- feat: QR-based add NGRAVE ZERO Hardware ([#25080](https://github.com/MetaMask/metamask-extension/pull/25080))
+- fix: Fix GitHub release description ([#26247](https://github.com/MetaMask/metamask-extension/pull/26247))
+- feat(btc): use new snap account flow for Bitcoin accounts ([#26183](https://github.com/MetaMask/metamask-extension/pull/26183))
+- refactor: replace deprecated mixins with text component in transaction-confirmed ([#25551](https://github.com/MetaMask/metamask-extension/pull/25551))
+- fix: improve warning in add network modal ([#26250](https://github.com/MetaMask/metamask-extension/pull/26250))
+- fix: Fix `create_release_pull_request` OOM error ([#26249](https://github.com/MetaMask/metamask-extension/pull/26249))
+- chore: Create a story for TokenCurrencyDisplay component ([#26172](https://github.com/MetaMask/metamask-extension/pull/26172))
+- chore: refactoring onboarding to remove deprecated components ([#26207](https://github.com/MetaMask/metamask-extension/pull/26207))
+- fix: Fix CircleCI `create_release_pull_request` job ([#26246](https://github.com/MetaMask/metamask-extension/pull/26246))
+- fix: flaky test `Import flow @no-mmi Import Account using json file` ([#26240](https://github.com/MetaMask/metamask-extension/pull/26240))
+- fix: sentry sessions ([#26192](https://github.com/MetaMask/metamask-extension/pull/26192))
+- test: [Page Object Model] rename process to flow ([#26228](https://github.com/MetaMask/metamask-extension/pull/26228))
+- test: header integration test for contract interaction ([#25981](https://github.com/MetaMask/metamask-extension/pull/25981))
+- chore: Pass along hashed `rpcUrl` during `CustomNetworkAdded` event ([#26203](https://github.com/MetaMask/metamask-extension/pull/26203))
+- chore: Create a story for PageContainerHeader component ([#26031](https://github.com/MetaMask/metamask-extension/pull/26031))
+- chore: Create a story for GasTiming component ([#25557](https://github.com/MetaMask/metamask-extension/pull/25557))
+- New Crowdin translations by Github Action ([#26230](https://github.com/MetaMask/metamask-extension/pull/26230))
+- chore: update @metamask/bitcoin-wallet-snap to 0.4.0 ([#26229](https://github.com/MetaMask/metamask-extension/pull/26229))
+- fix: flaky test `Sentry errors before initialization, after opting into metrics @no-mmi should send error events in background` ([#26216](https://github.com/MetaMask/metamask-extension/pull/26216))
+- chore: Create a story for NftCollectionImage component ([#26069](https://github.com/MetaMask/metamask-extension/pull/26069))
+- fix: update icons ([#26180](https://github.com/MetaMask/metamask-extension/pull/26180))
+- refactor: replace Typography with Text component in restore-vault.js ([#25636](https://github.com/MetaMask/metamask-extension/pull/25636))
+- chore: Create a story for convert-token-to-nft-modal component ([#25561](https://github.com/MetaMask/metamask-extension/pull/25561))
+- refactor: replace deprecated mixins with Text component in qr-code-view ([#25637](https://github.com/MetaMask/metamask-extension/pull/25637))
+- test: Add manual scenario for network polling scenario ([#26195](https://github.com/MetaMask/metamask-extension/pull/26195))
+- feat: Add experimental settings toggle for transactions redesign ([#26010](https://github.com/MetaMask/metamask-extension/pull/26010))
+- feat: Support Permit variants: PermitSingle, PermitBatch, PermitTransferFrom, PermitBatchTransferFrom, TradeOrder, Seaport ([#26107](https://github.com/MetaMask/metamask-extension/pull/26107))
+- feat: updated dapp permission screen ([#25703](https://github.com/MetaMask/metamask-extension/pull/25703))
+- fix: improve performance in large signature request confirmations ([#26209](https://github.com/MetaMask/metamask-extension/pull/26209))
+- refactor: remove password manager mention ([#25985](https://github.com/MetaMask/metamask-extension/pull/25985))
+- New Crowdin translations by Github Action ([#25939](https://github.com/MetaMask/metamask-extension/pull/25939))
+- chore: remove opera manifest files as they are not used ([#26200](https://github.com/MetaMask/metamask-extension/pull/26200))
+- fix(deps): bump fast-xml-parser from 4.3.4 to 4.4.1. ([#26202](https://github.com/MetaMask/metamask-extension/pull/26202))
+- test: [Snaps E2E] remove unnecessary steps from snaps UI Images test ([#25640](https://github.com/MetaMask/metamask-extension/pull/25640))
+- fix: truncate long tokenId ([#26179](https://github.com/MetaMask/metamask-extension/pull/26179))
+- chore: Add en_GB locale ([#26196](https://github.com/MetaMask/metamask-extension/pull/26196))
+- chore: upgrade to Sentry 8 ([#25999](https://github.com/MetaMask/metamask-extension/pull/25999))
+- refactor: add unlock checks for notification related controllers ([#26189](https://github.com/MetaMask/metamask-extension/pull/26189))
+- fix: interpret multipart errors correctly and allow ignore ([#26113](https://github.com/MetaMask/metamask-extension/pull/26113))
+- feat: migrate global unit tests from Mocha to Jest ([#26104](https://github.com/MetaMask/metamask-extension/pull/26104))
+- fix: node being setup twice ([#26052](https://github.com/MetaMask/metamask-extension/pull/26052))
+- fix: setupControllerConnection outstream end event listener ([#26141](https://github.com/MetaMask/metamask-extension/pull/26141))
+- fix: Address performance issues with 'Portfolio Dashboard' loading in test environment ([#26182](https://github.com/MetaMask/metamask-extension/pull/26182))
+- chore: migrating interactive-replacement-token-page to ts ([#26115](https://github.com/MetaMask/metamask-extension/pull/26115))
+- chore: update @metamask/bitcoin-wallet-snap to 0.3.0 ([#26168](https://github.com/MetaMask/metamask-extension/pull/26168))
+- test: fix potential api-spec test race condition when adding to task queue ([#26171](https://github.com/MetaMask/metamask-extension/pull/26171))
+- fix(user-preference-currency-display): remove unused prop ethLogoHeight ([#24517](https://github.com/MetaMask/metamask-extension/pull/24517))
+- fix: update logos for flare-mainnet and songbird ([#25560](https://github.com/MetaMask/metamask-extension/pull/25560))
+- feat: define account name during creation ([#25191](https://github.com/MetaMask/metamask-extension/pull/25191))
+- chore: MMI move custody component to TS ([#26096](https://github.com/MetaMask/metamask-extension/pull/26096))
+- chore: add portfolio ephemeral domain URL ([#26163](https://github.com/MetaMask/metamask-extension/pull/26163))
+- fix: Flaky test `4byte setting ` ([#26111](https://github.com/MetaMask/metamask-extension/pull/26111))
+- fix: PPOM blockaid update ([#26154](https://github.com/MetaMask/metamask-extension/pull/26154))
+- fix: flaky BTC e2e tests ([#26082](https://github.com/MetaMask/metamask-extension/pull/26082))
+- chore: Add extra event props ([#26123](https://github.com/MetaMask/metamask-extension/pull/26123))
+- refactor: fix event names used to track notifications ([#25521](https://github.com/MetaMask/metamask-extension/pull/25521))
+- test: [Snaps E2E] Create test for snap dialog JSX functionality ([#25493](https://github.com/MetaMask/metamask-extension/pull/25493))
+- chore: update BNB logos ([#26140](https://github.com/MetaMask/metamask-extension/pull/26140))
+- chore: cleanup `.prettierignore` file ([#24828](https://github.com/MetaMask/metamask-extension/pull/24828))
+- chore: Bump `@metamask/ens-controller` to v12 ([#26127](https://github.com/MetaMask/metamask-extension/pull/26127))
+- chore: Bump `@metamask/transaction-controller` to v34 ([#26124](https://github.com/MetaMask/metamask-extension/pull/26124))
+- chore: Create a story for Snackbar component ([#25515](https://github.com/MetaMask/metamask-extension/pull/25515))
+- fix: add new helper function for `openMenuSafe` to mitigate all ocurrences for opening menu with MMI build ([#26079](https://github.com/MetaMask/metamask-extension/pull/26079))
+- feat: make add-team-label use the reusable workflow ([#25807](https://github.com/MetaMask/metamask-extension/pull/25807))
+- chore: MMI-5301 adds enums for custody type and status ([#26006](https://github.com/MetaMask/metamask-extension/pull/26006))
+- fix: remove btc account from permission connect lists ([#25980](https://github.com/MetaMask/metamask-extension/pull/25980))
+- feat: update network list item to include start accessory and end ([#25507](https://github.com/MetaMask/metamask-extension/pull/25507))
+- chore: mmi 5305 mmi pages typescript migration ([#26081](https://github.com/MetaMask/metamask-extension/pull/26081))
+- fix: Move Snaps hooks out of code fence ([#26120](https://github.com/MetaMask/metamask-extension/pull/26120))
+- feat: Mitigate risk for distracted users on queued transactions from different dApps ([#25852](https://github.com/MetaMask/metamask-extension/pull/25852))
+- feat: Add metrics event for advanced details section toggling ([#26083](https://github.com/MetaMask/metamask-extension/pull/26083))
+- fix: display link to privacy-policy explanation in onboarding flow ([#26038](https://github.com/MetaMask/metamask-extension/pull/26038))
+- chore: Create a story for InvalidCustomNetworkAlert component ([#25600](https://github.com/MetaMask/metamask-extension/pull/25600))
+- fix: number formatting on swap + send tx detail ([#26029](https://github.com/MetaMask/metamask-extension/pull/26029))
+- fix: Flaky test `Account Custom Name..` ([#26062](https://github.com/MetaMask/metamask-extension/pull/26062))
+- fix: snap flakiness on `installSnapSimpleKeyring` function ([#26039](https://github.com/MetaMask/metamask-extension/pull/26039))
+- fix: lock Chrome version to 126 ([#26101](https://github.com/MetaMask/metamask-extension/pull/26101))
+- fix: remove halo for tokens ([#26016](https://github.com/MetaMask/metamask-extension/pull/26016))
+- refactor: replace typography with text component in creation-successful.js ([#25552](https://github.com/MetaMask/metamask-extension/pull/25552))
+- fix: `vault decryption` broken tests due to update on window handling ([#26074](https://github.com/MetaMask/metamask-extension/pull/26074))
+- docs: Centralize Author/Team Mapping for Commit Tracking ([#25986](https://github.com/MetaMask/metamask-extension/pull/25986))
+- fix: flaky test: Check the toggle for hex data ([#25899](https://github.com/MetaMask/metamask-extension/pull/25899))
+- chore: migrated institutional ui components to ts ([#25858](https://github.com/MetaMask/metamask-extension/pull/25858))
+- chore: removed unused component ([#26000](https://github.com/MetaMask/metamask-extension/pull/26000))
+- chore: update Bitcoin Snap to version 0.2.5 ([#26058](https://github.com/MetaMask/metamask-extension/pull/26058))
+- refactor: replace Typography with Text component in metametrics.js ([#25630](https://github.com/MetaMask/metamask-extension/pull/25630))
+- refactor: replace typography with text component in review recovery phrase ([#25265](https://github.com/MetaMask/metamask-extension/pull/25265))
+- test: new switchToWindowWithTitle w/ Extension communication ([#25362](https://github.com/MetaMask/metamask-extension/pull/25362))
+- ci: Trimming the gitdiff output before writing to output file ([#26057](https://github.com/MetaMask/metamask-extension/pull/26057))
+- chore: tweak send page styling ([#25982](https://github.com/MetaMask/metamask-extension/pull/25982))
+- fix: mmi flaky tests `Reveal SRP through settings completes quiz and reveals SRP QR after wrong answers` , `Sign Typed Data Signature Request can initiate and reject a Signature Request of Sign Typed Data`, `Sign Typed Data Signature Request can queue multiple Signature Requests of Sign Typed Data and confirm` ([#26055](https://github.com/MetaMask/metamask-extension/pull/26055))
+- chore: Create a story for IconButton component ([#25277](https://github.com/MetaMask/metamask-extension/pull/25277))
+- fix: center token icon ([#26013](https://github.com/MetaMask/metamask-extension/pull/26013))
+- fix: flaky test `Import flow @no-mmi Import wallet using Secret Recovery Phrase with pasting word by word` ([#26049](https://github.com/MetaMask/metamask-extension/pull/26049))
+- fix: flaky test 25912 ([#25913](https://github.com/MetaMask/metamask-extension/pull/25913))
+- chore: add privacy query params to portfolio navigation ([#25958](https://github.com/MetaMask/metamask-extension/pull/25958))
+- chore: Temporarily disable Playwright Swaps tests ([#26050](https://github.com/MetaMask/metamask-extension/pull/26050))
+- fix: Remove special reject button case from api spec tests ([#26048](https://github.com/MetaMask/metamask-extension/pull/26048))
+- test(e2e): unlock trezor account ([#25824](https://github.com/MetaMask/metamask-extension/pull/25824))
+- fix: Flaky "Signature Approved Event" e2e test ([#26040](https://github.com/MetaMask/metamask-extension/pull/26040))
+- feat: Migration #122 set redesignedConfirmationsEnabled to true ([#25769](https://github.com/MetaMask/metamask-extension/pull/25769))
+- fix: Revert "refactor: use withKeyring method (#25435)" ([#25435](https://github.com/MetaMask/metamask-extension/pull/25435))
+- fix: :label: update the text in the popup to enable notifications ([#26026](https://github.com/MetaMask/metamask-extension/pull/26026))
+- fix: map the supported block explorers ([#25908](https://github.com/MetaMask/metamask-extension/pull/25908))
+- fix: update css for modals ([#25961](https://github.com/MetaMask/metamask-extension/pull/25961))
+- fix: Fix permssions for `update-attributions` workflow ([#26019](https://github.com/MetaMask/metamask-extension/pull/26019))
+- fix: add migration for profile syncing controller ([#26004](https://github.com/MetaMask/metamask-extension/pull/26004))
+- test: Adding e2e for SIWE and re-enabling redesign for SIWE ([#25831](https://github.com/MetaMask/metamask-extension/pull/25831))
+- test: UX: Multichain: Add E2E for signaling network change from Network menu to dapp, Autoswitching networks ([#25765](https://github.com/MetaMask/metamask-extension/pull/25765))
+- feat: Move ENABLE_CONFIRMATION_REDESIGN feature flag to the developer settings page ([#25520](https://github.com/MetaMask/metamask-extension/pull/25520))
+- fix: `yarn:start:test:flask` is broken `Lavapack is not defined` ([#25995](https://github.com/MetaMask/metamask-extension/pull/25995))
+- feat: add utility function to get supported chains from the Security Alerts API ([#25716](https://github.com/MetaMask/metamask-extension/pull/25716))
+- fix: `vault-decryption` test since the order of announcement modals changed ([#25997](https://github.com/MetaMask/metamask-extension/pull/25997))
+- fix: updated switch to this account condition ([#25609](https://github.com/MetaMask/metamask-extension/pull/25609))
+- fix: flaky test Settings Redirects to ENS domains when user inputs ENS into address bar ([#25782](https://github.com/MetaMask/metamask-extension/pull/25782))
+- chore: MMI-5248 introduce the token allowance functionality for MMI ([#25967](https://github.com/MetaMask/metamask-extension/pull/25967))
+- fix: vertically align asset image ([#25988](https://github.com/MetaMask/metamask-extension/pull/25988))
+- feat: Adding state per window in e2e, excluding null state ([#25900](https://github.com/MetaMask/metamask-extension/pull/25900))
+- fix: attribution link ([#25947](https://github.com/MetaMask/metamask-extension/pull/25947))
+- feat: Enable hardware wallets for smart transactions in swaps ([#25742](https://github.com/MetaMask/metamask-extension/pull/25742))
+- fix: fix link redirection ([#25983](https://github.com/MetaMask/metamask-extension/pull/25983))
+- fix: fix overlapping modals ([#25962](https://github.com/MetaMask/metamask-extension/pull/25962))
+- feat: Show the Close extension button on the Smart Transaction Status Page for a pending dapp transaction ([#25965](https://github.com/MetaMask/metamask-extension/pull/25965))
+- fix(multichain): use accounts{Added,Removed} to fetch/clear balances ([#25884](https://github.com/MetaMask/metamask-extension/pull/25884))
+- test: Add integration tests for permit simulation section ([#25856](https://github.com/MetaMask/metamask-extension/pull/25856))
+- fix: fixed max width for permissions page ([#25870](https://github.com/MetaMask/metamask-extension/pull/25870))
+- fix: show current network if domains are undefined ([#25960](https://github.com/MetaMask/metamask-extension/pull/25960))
+- fix: notification slowness and crashes ([#25946](https://github.com/MetaMask/metamask-extension/pull/25946))
+- ci: Disabling non-lint CI on the l10n_crowdin_action branch ([#25809](https://github.com/MetaMask/metamask-extension/pull/25809))
+- refactor: use `withKeyring` method ([#25435](https://github.com/MetaMask/metamask-extension/pull/25435))
+- feat: add BTC support survey link ([#25875](https://github.com/MetaMask/metamask-extension/pull/25875))
+- fix: re-organize files under assets folder ([#25897](https://github.com/MetaMask/metamask-extension/pull/25897))
+- fix: fix css nft detail ([#25931](https://github.com/MetaMask/metamask-extension/pull/25931))
+- fix: Implement Auto-Enable Feature for Basic Functionality in Metamask Extension v12.1.0 ([#25944](https://github.com/MetaMask/metamask-extension/pull/25944))
+- fix: Handle error when offscreen document already exists ([#25138](https://github.com/MetaMask/metamask-extension/pull/25138))
+- test: Expand coverage of sourcemap validator ([#25115](https://github.com/MetaMask/metamask-extension/pull/25115))
+- feat: Add full screen Snap Home and Dialog ([#25670](https://github.com/MetaMask/metamask-extension/pull/25670))
+- chore: swaps codeowners reorg ([#24803](https://github.com/MetaMask/metamask-extension/pull/24803))
+- fix: track token detection enabled ([#25822](https://github.com/MetaMask/metamask-extension/pull/25822))
+- fix: rm locales in other languages ([#25936](https://github.com/MetaMask/metamask-extension/pull/25936))
+- fix: fix ([#25907](https://github.com/MetaMask/metamask-extension/pull/25907))
+- fix: password reset ([#25847](https://github.com/MetaMask/metamask-extension/pull/25847))
+- New Crowdin translations by Github Action ([#24889](https://github.com/MetaMask/metamask-extension/pull/24889))
+- fix: Remove abandoned test:unit:jest command ([#25905](https://github.com/MetaMask/metamask-extension/pull/25905))
+- fix(22851): check if active device to prevent autoconnect for hw ([#25503](https://github.com/MetaMask/metamask-extension/pull/25503))
+- test: Removed step from e2e tests ([#25910](https://github.com/MetaMask/metamask-extension/pull/25910))
+- fix: calcTokenAmount BigNumber more than 15 digits error ([#25799](https://github.com/MetaMask/metamask-extension/pull/25799))
+- feat: add custom form check alerts ([#25259](https://github.com/MetaMask/metamask-extension/pull/25259))
+- fix: test failure on firefox ([#25895](https://github.com/MetaMask/metamask-extension/pull/25895))
+- fix: disables "swap and send" for MMI ([#25886](https://github.com/MetaMask/metamask-extension/pull/25886))
+- fix: Fixed flaky test 24645 ([#25786](https://github.com/MetaMask/metamask-extension/pull/25786))
+- chore: refactor SwapsController so it extends from BaseControllerV2 ([#25681](https://github.com/MetaMask/metamask-extension/pull/25681))
+- feat: Replace "Manage in settings" with "No thanks" in the STX Opt In modal, only show the modal for non-zero balances ([#25848](https://github.com/MetaMask/metamask-extension/pull/25848))
+- feat: Display advanced section within confirmation by default for some users ([#25687](https://github.com/MetaMask/metamask-extension/pull/25687))
+- chore: bump assets-controllers to v36.0.0 ([#25857](https://github.com/MetaMask/metamask-extension/pull/25857))
+- fix: add name to scuttling exception list ([#25849](https://github.com/MetaMask/metamask-extension/pull/25849))
+- fix: update build version to align with firefox's newer version restrictions ([#25456](https://github.com/MetaMask/metamask-extension/pull/25456))
+- feat: regression label ([#25691](https://github.com/MetaMask/metamask-extension/pull/25691))
+- chore: Master sync ([#25816](https://github.com/MetaMask/metamask-extension/pull/25816))
+- fix: contract data in metrics ([#25759](https://github.com/MetaMask/metamask-extension/pull/25759))
+- fix: flaky test `ERC721 NFTs testdapp interaction` ([#25854](https://github.com/MetaMask/metamask-extension/pull/25854))
+- fix: flaky test `Create BTC Account cannot create multiple BTC accounts...` ([#25861](https://github.com/MetaMask/metamask-extension/pull/25861))
+- feat: support creation of Bitcoin testnet accounts ([#25772](https://github.com/MetaMask/metamask-extension/pull/25772))
+- fix: use of an header in a dedicated call ([#25828](https://github.com/MetaMask/metamask-extension/pull/25828))
+- feat(tests): add btc e2e tests ([#25663](https://github.com/MetaMask/metamask-extension/pull/25663))
+- feat: NFT details new design ([#25524](https://github.com/MetaMask/metamask-extension/pull/25524))
+- feat: Add fuzzy matching for name lookup ([#25264](https://github.com/MetaMask/metamask-extension/pull/25264))
+- fix: edit path to dist folder ([#25826](https://github.com/MetaMask/metamask-extension/pull/25826))
+- chore: Patch security issue in snaps-utils ([#25827](https://github.com/MetaMask/metamask-extension/pull/25827))
+- feat: add option of copy to info row component ([#25682](https://github.com/MetaMask/metamask-extension/pull/25682))
+- fix: skip blockaid validations for users internal accounts ([#25695](https://github.com/MetaMask/metamask-extension/pull/25695))
+- chore: refactor custody component ([#25684](https://github.com/MetaMask/metamask-extension/pull/25684))
+- Merge origin/develop into master-sync
+- chore: update @metamask/bitcoin-wallet-snap to 0.2.4 ([#25808](https://github.com/MetaMask/metamask-extension/pull/25808))
+- chore: removed unused getCustodianAccountsByAddress method ([#25798](https://github.com/MetaMask/metamask-extension/pull/25798))
+- feat: Make Jest unit tests run faster in GitHub actions ([#25726](https://github.com/MetaMask/metamask-extension/pull/25726))
+- revert: un-revert metrics and signature refactor test ([#25758](https://github.com/MetaMask/metamask-extension/pull/25758))
+- feat: Add `ui_customizations` metric for transactions ([#25736](https://github.com/MetaMask/metamask-extension/pull/25736))
+- test: add e2e tests for navigation (#25652) ([#25652](https://github.com/MetaMask/metamask-extension/pull/25652))
+- chore: remove `BTC_BETA_SUPPORT` flag ([#25776](https://github.com/MetaMask/metamask-extension/pull/25776))
+- chore: update @metamask/bitcoin-wallet-snap to 0.2.3 ([#25775](https://github.com/MetaMask/metamask-extension/pull/25775))
+- feat: add more whitelisted portfolio URLs ([#25767](https://github.com/MetaMask/metamask-extension/pull/25767))
+- fix: Fix page width for fullscreen mode send page ([#25639](https://github.com/MetaMask/metamask-extension/pull/25639))
+- chore: Update Snaps codeowners list ([#25581](https://github.com/MetaMask/metamask-extension/pull/25581))
+- fix: fine-tune for `Delineator` component styles ([#25760](https://github.com/MetaMask/metamask-extension/pull/25760))
+- feat: decode transaction data ([#25597](https://github.com/MetaMask/metamask-extension/pull/25597))
+- feat: add `Delineator` component ([#25610](https://github.com/MetaMask/metamask-extension/pull/25610))
+- feat(ramps): update isNativeTokenBuyable to include BTC ([#25621](https://github.com/MetaMask/metamask-extension/pull/25621))
+- fix: Fix issue 25285 max insufficient funds for gas ([#25574](https://github.com/MetaMask/metamask-extension/pull/25574))
+- feat: add BTC experimental toggle ([#25672](https://github.com/MetaMask/metamask-extension/pull/25672))
+- build: bump gas-fee-controller to v18 and remove patch ([#25679](https://github.com/MetaMask/metamask-extension/pull/25679))
+- fix: show correct asset and balance when BTC account is the selected account ([#25719](https://github.com/MetaMask/metamask-extension/pull/25719))
+- feat(btc): add BTC account creation menu entry ([#25625](https://github.com/MetaMask/metamask-extension/pull/25625))
+- fix: flaky test `Test Snap Metrics test snap update rejected metric` ([#25744](https://github.com/MetaMask/metamask-extension/pull/25744))
+- chore(deps): bump @metamask/accounts-controller from ^17.0.0 to ^17.2.0 ([#25676](https://github.com/MetaMask/metamask-extension/pull/25676))
+- fix: use LAVAMOAT_UPDATE_TOKEN in attributions workflow ([#25731](https://github.com/MetaMask/metamask-extension/pull/25731))
+- fix: caveat mutations for non-EVM accounts ([#25739](https://github.com/MetaMask/metamask-extension/pull/25739))
+- test: Add UI integration tests ([#24428](https://github.com/MetaMask/metamask-extension/pull/24428))
+- fix: revert "test: add e2e tests for navigation (#25652)" ([#25652](https://github.com/MetaMask/metamask-extension/pull/25652))
+- chore: Revert "test: e2e metrics test and refactor" ([#25722](https://github.com/MetaMask/metamask-extension/pull/25722))
+- feat: bundle pre-installed Bitcoin Wallet Snap ([#25715](https://github.com/MetaMask/metamask-extension/pull/25715))
+- fix: protect against phishing domain redirects in main/sub frames for http(s) requests ([#25153](https://github.com/MetaMask/metamask-extension/pull/25153))
+- fix: Fix crash of Transaction screen with smart transaction ([#25717](https://github.com/MetaMask/metamask-extension/pull/25717))
+- fix: Hide MMI Account Mistmatch BannerAlert from Sign-in with Ethereum (SIWE) Redesign Page ([#25662](https://github.com/MetaMask/metamask-extension/pull/25662))
+- fix: flaky test `Create token, approve token and approve token without gas approves an already created token and displays the token approval data` ([#25706](https://github.com/MetaMask/metamask-extension/pull/25706))
+- feat: Enable SIWE Signature Redesign ([#25660](https://github.com/MetaMask/metamask-extension/pull/25660))
+- fix: flaky test `Request-queue UI changes handles three confirmations on three confirmations concurrently` ([#25675](https://github.com/MetaMask/metamask-extension/pull/25675))
+- feat: move unit tests from Circleci to Github actions ([#25570](https://github.com/MetaMask/metamask-extension/pull/25570))
+- test: e2e metrics test and refactor ([#25632](https://github.com/MetaMask/metamask-extension/pull/25632))
+- test: add e2e tests for navigation ([#25652](https://github.com/MetaMask/metamask-extension/pull/25652))
+- feat: support security alerts API ([#25544](https://github.com/MetaMask/metamask-extension/pull/25544))
+- feat(ramps): add flag to ensure ramp networks are only fetched once ([#25686](https://github.com/MetaMask/metamask-extension/pull/25686))
+- fix: allow ramps dev environment on Flask ([#25659](https://github.com/MetaMask/metamask-extension/pull/25659))
+- feat: added check for if the selected account is BTC in transaction-list ([#25642](https://github.com/MetaMask/metamask-extension/pull/25642))
+- feat: Gas Fees Redesign PoC ([#24714](https://github.com/MetaMask/metamask-extension/pull/24714))
+- fix: show connected toast only for EVM accounts ([#25628](https://github.com/MetaMask/metamask-extension/pull/25628))
+- fix: changed logic to use the new banner alert ([#25626](https://github.com/MetaMask/metamask-extension/pull/25626))
+- fix: set network client id for domain ([#25646](https://github.com/MetaMask/metamask-extension/pull/25646))
+- feat: improvement for how we display big and small numbers ([#25438](https://github.com/MetaMask/metamask-extension/pull/25438))
+- chore: restore bot workflow to update attributions ([#25211](https://github.com/MetaMask/metamask-extension/pull/25211))
+- test: add swap e2e tests on Tenderly network ([#25060](https://github.com/MetaMask/metamask-extension/pull/25060))
+- fix: UX: Multichain: Add safeguard to throw error when confirmation chainId doesn't match current chainId ([#25634](https://github.com/MetaMask/metamask-extension/pull/25634))
+- chore: updates MMI custody controller ([#25631](https://github.com/MetaMask/metamask-extension/pull/25631))
+- fix: flaky test `Test Snap Get Locale test snap_getLocale functionality` ([#25648](https://github.com/MetaMask/metamask-extension/pull/25648))
+- fix: Skip blockaid validation for SIWE signature types ([#25612](https://github.com/MetaMask/metamask-extension/pull/25612))
+- feat: Add support for security alerts on zkSync, Berachain, Scroll and Metachain One on extension ([#25555](https://github.com/MetaMask/metamask-extension/pull/25555))
+- fix: Multichain: UX: Check for transactions on all networks and QueuedRequestCount ([#25614](https://github.com/MetaMask/metamask-extension/pull/25614))
+- feat: define which keyring methods Portfolio can call ([#25633](https://github.com/MetaMask/metamask-extension/pull/25633))
+- chore: flaky E2E tests improved ([#25565](https://github.com/MetaMask/metamask-extension/pull/25565))
+- feat: add SIWE mismatch account warning alert ([#25613](https://github.com/MetaMask/metamask-extension/pull/25613))
+- fix: support multichain in blockexplorer and qr code ([#25526](https://github.com/MetaMask/metamask-extension/pull/25526))
+- fix: decimal places displayed on token value on permit pages ([#25410](https://github.com/MetaMask/metamask-extension/pull/25410))
+- feat: added BTC variant to ramps-card and illustration image ([#25615](https://github.com/MetaMask/metamask-extension/pull/25615))
+- fix: Remove unused fixtures and fix test name in smart swaps disabled spec ([#25616](https://github.com/MetaMask/metamask-extension/pull/25616))
+- chore: Update @metamask/smart-transactions-controller from 10.1.2 to 10.1.6 ([#25611](https://github.com/MetaMask/metamask-extension/pull/25611))
+- fix: Fix issue 22837 about unknown error during ledger pair ([#25462](https://github.com/MetaMask/metamask-extension/pull/25462))
+- test: add e2e to swap with snap account ([#25558](https://github.com/MetaMask/metamask-extension/pull/25558))
+- chore: exclude running git diff job for the e2e quality gate in `develop`, `master` and release branches ([#25605](https://github.com/MetaMask/metamask-extension/pull/25605))
+- chore: [Delivery] Update author mapping list for PR ([#25606](https://github.com/MetaMask/metamask-extension/pull/25606))
+- fix: page object selector not found ([#25624](https://github.com/MetaMask/metamask-extension/pull/25624))
+- test: Initial PR for integrating the Page Object Model (POM) into e2e test suite ([#25373](https://github.com/MetaMask/metamask-extension/pull/25373))
+- refactor: Replace deprecated mixins with Text component in selected-account.component.js ([#25262](https://github.com/MetaMask/metamask-extension/pull/25262))
+- refactor: Replace deprecated mixins with Text component in unlock-page.component.js ([#25227](https://github.com/MetaMask/metamask-extension/pull/25227))
+- chore: Create a story for RestoreVaultPage component ([#25284](https://github.com/MetaMask/metamask-extension/pull/25284))
+- fix(snaps): Fix alignment of install origin is `snap-authorship-expanded` ([#25583](https://github.com/MetaMask/metamask-extension/pull/25583))
+- feat: Remove blockaid migration BannerAlert ([#25556](https://github.com/MetaMask/metamask-extension/pull/25556))
+- fix: failingt e2e `Click bridge button from asset page @no-mmi loads portfolio tab when flag is turned off` ([#25607](https://github.com/MetaMask/metamask-extension/pull/25607))
+- chore: adds quality gate for rerunning e2e spec files that are new or have been modified ([#24556](https://github.com/MetaMask/metamask-extension/pull/24556))
+- chore(deps): bump assets controller to v34.0.0 ([#25540](https://github.com/MetaMask/metamask-extension/pull/25540))
+- chore: add bridge controller, store and api utils ([#25044](https://github.com/MetaMask/metamask-extension/pull/25044))
+- fix: add eth_signTypedData and eth_signTypedData_v3 to `methodsRequiringNetworkSwitch` ([#25562](https://github.com/MetaMask/metamask-extension/pull/25562))
+
## [12.1.0]
### Added
- Launched a feature displaying the percentage increase or decrease for tokens within the UI ([#24223](https://github.com/MetaMask/metamask-extension/pull/24223))
@@ -4996,7 +5404,8 @@ Update styles and spacing on the critical error page ([#20350](https://github.c
- Added the ability to restore accounts from seed words.
-[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v12.1.0...HEAD
+[Unreleased]: https://github.com/MetaMask/metamask-extension/compare/v12.4.0...HEAD
+[12.4.0]: https://github.com/MetaMask/metamask-extension/compare/v12.1.0...v12.4.0
[12.1.0]: https://github.com/MetaMask/metamask-extension/compare/v12.0.6...v12.1.0
[12.0.6]: https://github.com/MetaMask/metamask-extension/compare/v12.0.5...v12.0.6
[12.0.5]: https://github.com/MetaMask/metamask-extension/compare/v12.0.4...v12.0.5
diff --git a/package.json b/package.json
index ce10cc9eda9a..f9fafd91540d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "metamask-crx",
- "version": "12.1.0",
+ "version": "12.4.0",
"private": true,
"repository": {
"type": "git",
From bdc819ae9aa954e625b48e8c6fdb7a871e894379 Mon Sep 17 00:00:00 2001
From: Jony Bursztyn
Date: Wed, 4 Sep 2024 17:11:59 +0100
Subject: [PATCH 02/41] fix: move porfolio button next to price amount (#26867)
(#26897)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Cherry picks: https://github.com/MetaMask/metamask-extension/pull/26867
into V12.5.0
## **Description**
Moves the portfolio button so that it's next to the token price amount.
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/26867?quickstart=1)
## **Related issues**
Fixes: https://github.com/MetaMask/MetaMask-planning/issues/3201
## **Manual testing steps**
1. Go to the portfolio page
2. Check that the Portfolio button is present next to the price amount
of token
3. Click it to test it works fine
## **Screenshots/Recordings**
### **Before**
### **After**
## **Pre-merge author checklist**
- [X] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [X] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [X] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [X] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [X] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
.../app/wallet-overview/coin-buttons.tsx | 32 ++++++------
.../app/wallet-overview/coin-overview.tsx | 51 +++++++++++--------
ui/components/app/wallet-overview/index.scss | 6 +++
.../__snapshots__/asset-page.test.tsx.snap | 24 ++++-----
4 files changed, 63 insertions(+), 50 deletions(-)
diff --git a/ui/components/app/wallet-overview/coin-buttons.tsx b/ui/components/app/wallet-overview/coin-buttons.tsx
index 1bd24c23ecdb..73b0679b49a7 100644
--- a/ui/components/app/wallet-overview/coin-buttons.tsx
+++ b/ui/components/app/wallet-overview/coin-buttons.tsx
@@ -326,22 +326,6 @@ const CoinButtons = ({
///: END:ONLY_INCLUDE_IF
}
-
- }
- disabled={!isSigningEnabled}
- label={t('send')}
- onClick={handleSendOnClick}
- tooltipRender={(contents: React.ReactElement) =>
- generateTooltip('sendButton', contents)
- }
- />
///: END:ONLY_INCLUDE_IF
}
+
+ }
+ disabled={!isSigningEnabled}
+ label={t('send')}
+ onClick={handleSendOnClick}
+ tooltipRender={(contents: React.ReactElement) =>
+ generateTooltip('sendButton', contents)
+ }
+ />
{
<>
{showReceiveModal && (
diff --git a/ui/components/app/wallet-overview/coin-overview.tsx b/ui/components/app/wallet-overview/coin-overview.tsx
index 547ef107b05d..1a5e408bcac5 100644
--- a/ui/components/app/wallet-overview/coin-overview.tsx
+++ b/ui/components/app/wallet-overview/coin-overview.tsx
@@ -4,7 +4,7 @@ import classnames from 'classnames';
import { zeroAddress } from 'ethereumjs-util';
import { CaipChainId } from '@metamask/utils';
import type { Hex } from '@metamask/utils';
-import { Icon, IconName } from '../../component-library';
+import { Icon, IconName, IconSize } from '../../component-library';
import { IconColor } from '../../../helpers/constants/design-system';
import { MetaMetricsContext } from '../../../contexts/metametrics';
import {
@@ -122,14 +122,6 @@ export const CoinOverview = ({
disabled={!balanceIsCached}
>
-
- {t('portfolio')}
-
-
{balance ? (
)}
- {showFiat && isOriginalNativeSymbol && balance && (
-
- )}
+
+ {showFiat && isOriginalNativeSymbol && balance && (
+
+ )}
+
+ {t('portfolio')}
+
+
+
{isEvm && (
- Send
+ Swap
- Swap
+ Bridge
- Bridge
+ Send
Date: Wed, 25 Sep 2024 13:06:32 +0000
Subject: [PATCH 03/41] Update LavaMoat policies
---
lavamoat/browserify/beta/policy.json | 880 ++++++++++----------------
lavamoat/browserify/flask/policy.json | 880 ++++++++++----------------
lavamoat/browserify/main/policy.json | 880 ++++++++++----------------
lavamoat/browserify/mmi/policy.json | 880 ++++++++++----------------
4 files changed, 1292 insertions(+), 2228 deletions(-)
diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json
index 605c88c89ea1..cc0b0f53fd56 100644
--- a/lavamoat/browserify/beta/policy.json
+++ b/lavamoat/browserify/beta/policy.json
@@ -180,8 +180,8 @@
},
"packages": {
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": true,
- "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true,
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true
+ "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true,
+ "@noble/hashes": true
}
},
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": {
@@ -189,20 +189,14 @@
"TextEncoder": true
},
"packages": {
- "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true
- }
- },
- "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": {
- "globals": {
- "TextEncoder": true,
- "crypto": true
+ "@noble/hashes": true
}
},
"@ethereumjs/tx>ethereum-cryptography>@scure/bip32": {
"packages": {
"@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/curves": true,
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": true,
- "@metamask/utils>@scure/base": true
+ "@metamask/utils>@scure/base": true,
+ "@noble/hashes": true
}
},
"@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/curves": {
@@ -210,13 +204,7 @@
"TextEncoder": true
},
"packages": {
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": true
- }
- },
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": {
- "globals": {
- "TextEncoder": true,
- "crypto": true
+ "@noble/hashes": true
}
},
"@ethersproject/abi": {
@@ -922,12 +910,12 @@
"@ethersproject/providers": true,
"@metamask/abi-utils": true,
"@metamask/assets-controllers>@metamask/base-controller": true,
- "@metamask/assets-controllers>@metamask/controller-utils": true,
"@metamask/assets-controllers>@metamask/polling-controller": true,
"@metamask/assets-controllers>@metamask/utils": true,
"@metamask/assets-controllers>cockatiel": true,
"@metamask/assets-controllers>multiformats": true,
"@metamask/contract-metadata": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/metamask-eth-abis": true,
"@metamask/name-controller>async-mutex": true,
@@ -946,24 +934,6 @@
"immer": true
}
},
- "@metamask/assets-controllers>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/assets-controllers>@metamask/utils": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/assets-controllers>@metamask/polling-controller": {
"globals": {
"clearTimeout": true,
@@ -1045,15 +1015,30 @@
},
"packages": {
"@ethereumjs/tx>@ethereumjs/util": true,
+ "@metamask/controller-utils>@metamask/utils": true,
"@metamask/controller-utils>@spruceid/siwe-parser": true,
"@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true
}
},
+ "@metamask/controller-utils>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/abi-utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/controller-utils>@spruceid/siwe-parser": {
"globals": {
"console.error": true,
@@ -1087,9 +1072,9 @@
"@metamask/ens-controller": {
"packages": {
"@ethersproject/providers": true,
+ "@metamask/controller-utils": true,
"@metamask/ens-controller>@metamask/base-controller": true,
- "@metamask/ens-controller>@metamask/controller-utils": true,
- "@metamask/utils": true,
+ "@metamask/ens-controller>@metamask/utils": true,
"punycode": true
}
},
@@ -1101,25 +1086,7 @@
"immer": true
}
},
- "@metamask/ens-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ens-controller>@metamask/controller-utils>@metamask/utils": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/ens-controller>@metamask/controller-utils>@metamask/utils": {
+ "@metamask/ens-controller>@metamask/utils": {
"globals": {
"TextDecoder": true,
"TextEncoder": true
@@ -1550,46 +1517,13 @@
"setInterval": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
- "@metamask/gas-fee-controller>@metamask/controller-utils": true,
"@metamask/gas-fee-controller>@metamask/polling-controller": true,
"bn.js": true,
"uuid": true
}
},
- "@metamask/gas-fee-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/gas-fee-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/gas-fee-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/gas-fee-controller>@metamask/polling-controller": {
"globals": {
"clearTimeout": true,
@@ -1861,8 +1795,8 @@
"fetch": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/name-controller>@metamask/base-controller": true,
- "@metamask/name-controller>@metamask/controller-utils": true,
"@metamask/name-controller>async-mutex": true,
"@metamask/utils": true
}
@@ -1875,39 +1809,6 @@
"immer": true
}
},
- "@metamask/name-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/name-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/name-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/name-controller>async-mutex": {
"globals": {
"clearTimeout": true,
@@ -1925,17 +1826,17 @@
"setTimeout": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/eth-token-tracker>@metamask/eth-block-tracker": true,
"@metamask/network-controller>@metamask/base-controller": true,
- "@metamask/network-controller>@metamask/controller-utils": true,
"@metamask/network-controller>@metamask/eth-json-rpc-infura": true,
"@metamask/network-controller>@metamask/eth-json-rpc-middleware": true,
"@metamask/network-controller>@metamask/eth-json-rpc-provider": true,
"@metamask/network-controller>@metamask/swappable-obj-proxy": true,
+ "@metamask/network-controller>@metamask/utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
- "@metamask/utils": true,
"browserify>assert": true,
"uuid": true
}
@@ -1948,39 +1849,6 @@
"immer": true
}
},
- "@metamask/network-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/network-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/network-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/network-controller>@metamask/eth-json-rpc-infura": {
"globals": {
"setTimeout": true
@@ -2017,16 +1885,31 @@
"@metamask/eth-json-rpc-middleware>safe-stable-stringify": true,
"@metamask/eth-sig-util": true,
"@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/json-rpc-engine": true,
+ "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": true,
"@metamask/rpc-errors": true,
- "@metamask/utils": true,
"pify": true
}
},
"@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/json-rpc-engine": {
"packages": {
+ "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": true,
"@metamask/rpc-errors": true,
- "@metamask/safe-event-emitter": true,
- "@metamask/utils": true
+ "@metamask/safe-event-emitter": true
+ }
+ },
+ "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true,
+ "superstruct": true
}
},
"@metamask/network-controller>@metamask/eth-json-rpc-provider": {
@@ -2037,6 +1920,21 @@
"uuid": true
}
},
+ "@metamask/network-controller>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/abi-utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/notification-controller": {
"packages": {
"@metamask/base-controller": true,
@@ -2049,6 +1947,148 @@
"crypto.getRandomValues": true
}
},
+ "@metamask/notification-services-controller": {
+ "globals": {
+ "Intl.NumberFormat": true,
+ "addEventListener": true,
+ "fetch": true,
+ "registration": true,
+ "removeEventListener": true
+ },
+ "packages": {
+ "@contentful/rich-text-html-renderer": true,
+ "@metamask/controller-utils": true,
+ "@metamask/notification-services-controller>@metamask/base-controller": true,
+ "@metamask/notification-services-controller>firebase": true,
+ "@metamask/profile-sync-controller": true,
+ "bignumber.js": true,
+ "loglevel": true,
+ "uuid": true
+ }
+ },
+ "@metamask/notification-services-controller>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
+ "packages": {
+ "immer": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase": {
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app": true,
+ "@metamask/notification-services-controller>firebase>@firebase/messaging": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app": {
+ "globals": {
+ "FinalizationRegistry": true,
+ "console.warn": true
+ },
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": true,
+ "@metamask/notification-services-controller>firebase>@firebase/util": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": {
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/util": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": {
+ "globals": {
+ "console": true
+ },
+ "packages": {
+ "@swc/helpers>tslib": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": {
+ "globals": {
+ "DOMException": true,
+ "IDBCursor": true,
+ "IDBDatabase": true,
+ "IDBIndex": true,
+ "IDBObjectStore": true,
+ "IDBRequest": true,
+ "IDBTransaction": true,
+ "indexedDB.deleteDatabase": true,
+ "indexedDB.open": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/installations": {
+ "globals": {
+ "BroadcastChannel": true,
+ "Headers": true,
+ "btoa": true,
+ "console.error": true,
+ "crypto": true,
+ "fetch": true,
+ "msCrypto": true,
+ "navigator.onLine": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": true,
+ "@metamask/notification-services-controller>firebase>@firebase/util": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/messaging": {
+ "globals": {
+ "Headers": true,
+ "Notification.maxActions": true,
+ "Notification.permission": true,
+ "Notification.requestPermission": true,
+ "PushSubscription.prototype.hasOwnProperty": true,
+ "ServiceWorkerRegistration": true,
+ "URL": true,
+ "addEventListener": true,
+ "atob": true,
+ "btoa": true,
+ "clients.matchAll": true,
+ "clients.openWindow": true,
+ "console.warn": true,
+ "document": true,
+ "fetch": true,
+ "indexedDB": true,
+ "location.href": true,
+ "location.origin": true,
+ "navigator": true,
+ "origin.replace": true,
+ "registration.showNotification": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": true,
+ "@metamask/notification-services-controller>firebase>@firebase/installations": true,
+ "@metamask/notification-services-controller>firebase>@firebase/util": true,
+ "@swc/helpers>tslib": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/util": {
+ "globals": {
+ "atob": true,
+ "browser": true,
+ "btoa": true,
+ "chrome": true,
+ "console": true,
+ "document": true,
+ "indexedDB": true,
+ "navigator": true,
+ "process": true,
+ "self": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "process": true
+ }
+ },
"@metamask/object-multiplex": {
"globals": {
"console.warn": true
@@ -2074,8 +2114,8 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/permission-controller>@metamask/base-controller": true,
- "@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/permission-controller>nanoid": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
@@ -2092,39 +2132,6 @@
"immer": true
}
},
- "@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/permission-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/permission-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -2138,18 +2145,25 @@
},
"@metamask/phishing-controller": {
"globals": {
+ "TextEncoder": true,
+ "URL": true,
"fetch": true
},
"packages": {
- "@metamask/base-controller": true,
+ "@ethereumjs/tx>ethereum-cryptography": true,
"@metamask/controller-utils": true,
- "@metamask/phishing-warning>eth-phishing-detect": true,
+ "@metamask/phishing-controller>@metamask/base-controller": true,
+ "@metamask/phishing-controller>fastest-levenshtein": true,
+ "@noble/hashes": true,
"punycode": true
}
},
- "@metamask/phishing-warning>eth-phishing-detect": {
+ "@metamask/phishing-controller>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
"packages": {
- "eslint>optionator>fast-levenshtein": true
+ "immer": true
}
},
"@metamask/post-message-stream": {
@@ -2416,27 +2430,57 @@
"console.info": true
},
"packages": {
- "@metamask/base-controller": true,
"@metamask/controller-utils": true,
"@metamask/logging-controller": true,
- "@metamask/rpc-errors": true,
+ "@metamask/signature-controller>@metamask/base-controller": true,
"@metamask/signature-controller>@metamask/message-manager": true,
"lodash": true,
"webpack>events": true
}
},
+ "@metamask/signature-controller>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
+ "packages": {
+ "immer": true
+ }
+ },
"@metamask/signature-controller>@metamask/message-manager": {
"packages": {
- "@metamask/base-controller": true,
"@metamask/controller-utils": true,
"@metamask/eth-sig-util": true,
"@metamask/message-manager>jsonschema": true,
- "@metamask/utils": true,
+ "@metamask/signature-controller>@metamask/message-manager>@metamask/base-controller": true,
+ "@metamask/signature-controller>@metamask/utils": true,
"browserify>buffer": true,
"uuid": true,
"webpack>events": true
}
},
+ "@metamask/signature-controller>@metamask/message-manager>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
+ "packages": {
+ "immer": true
+ }
+ },
+ "@metamask/signature-controller>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/abi-utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/smart-transactions-controller": {
"globals": {
"URLSearchParams": true,
@@ -2448,11 +2492,11 @@
},
"packages": {
"@ethersproject/bytes": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller>@metamask/polling-controller": true,
"@metamask/smart-transactions-controller>@ethereumjs/tx": true,
"@metamask/smart-transactions-controller>@ethereumjs/util": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller": true,
"@metamask/smart-transactions-controller>bignumber.js": true,
"browserify>buffer": true,
@@ -2509,52 +2553,6 @@
"immer": true
}
},
- "@metamask/smart-transactions-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@ethereumjs/util": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@ethereumjs/util": {
- "globals": {
- "console.warn": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/rlp": true,
- "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true,
- "@ethereumjs/tx>ethereum-cryptography": true,
- "browserify>buffer": true,
- "browserify>insert-module-globals>is-buffer": true,
- "webpack>events": true
- }
- },
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/smart-transactions-controller>@metamask/controllers>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -2572,6 +2570,7 @@
"@ethersproject/abi": true,
"@ethersproject/contracts": true,
"@ethersproject/providers": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller": true,
"@metamask/metamask-eth-abis": true,
@@ -2579,11 +2578,10 @@
"@metamask/network-controller": true,
"@metamask/rpc-errors": true,
"@metamask/smart-transactions-controller>@metamask/base-controller": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller>@ethereumjs/tx": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller>@ethereumjs/util": true,
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller>eth-method-registry": true,
- "@metamask/transaction-controller>@metamask/nonce-tracker": true,
"@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
@@ -2616,6 +2614,22 @@
"webpack>events": true
}
},
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker": {
+ "packages": {
+ "@ethersproject/providers": true,
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true,
+ "browserify>assert": true
+ }
+ },
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": {
+ "globals": {
+ "clearTimeout": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@swc/helpers>tslib": true
+ }
+ },
"@metamask/smart-transactions-controller>@metamask/transaction-controller>eth-method-registry": {
"packages": {
"@metamask/smart-transactions-controller>@metamask/transaction-controller>eth-method-registry>@metamask/ethjs-contract": true,
@@ -2773,32 +2787,14 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/base-controller": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
- "@metamask/snaps-controllers>@metamask/phishing-controller>@metamask/controller-utils": true,
"@metamask/snaps-controllers>@metamask/utils": true,
"@metamask/snaps-controllers>nanoid": true,
"deep-freeze-strict": true,
- "immer": true
- }
- },
- "@metamask/snaps-controllers>@metamask/phishing-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-controllers>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
+ "immer": true
}
},
"@metamask/snaps-controllers>@metamask/utils": {
@@ -2921,34 +2917,16 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
"@metamask/snaps-execution-environments>@metamask/snaps-utils>@metamask/base-controller": true,
- "@metamask/snaps-execution-environments>@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/snaps-execution-environments>@metamask/utils": true,
"@metamask/snaps-execution-environments>nanoid": true,
"deep-freeze-strict": true,
"immer": true
}
},
- "@metamask/snaps-execution-environments>@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-execution-environments>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/snaps-execution-environments>@metamask/utils": {
"globals": {
"TextDecoder": true,
@@ -2986,10 +2964,10 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
"@metamask/snaps-rpc-methods>@metamask/permission-controller>@metamask/base-controller": true,
- "@metamask/snaps-rpc-methods>@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/snaps-rpc-methods>@metamask/permission-controller>nanoid": true,
"@metamask/snaps-rpc-methods>@metamask/utils": true,
"deep-freeze-strict": true,
@@ -3004,24 +2982,6 @@
"immer": true
}
},
- "@metamask/snaps-rpc-methods>@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-rpc-methods>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/snaps-rpc-methods>@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -3139,34 +3099,16 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
"@metamask/snaps-utils>@metamask/base-controller": true,
- "@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/snaps-utils>@metamask/permission-controller>nanoid": true,
"@metamask/snaps-utils>@metamask/utils": true,
"deep-freeze-strict": true,
"immer": true
}
},
- "@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/snaps-utils>@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -3314,6 +3256,7 @@
"@ethersproject/abi": true,
"@ethersproject/contracts": true,
"@ethersproject/providers": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller": true,
"@metamask/metamask-eth-abis": true,
@@ -3321,9 +3264,8 @@
"@metamask/network-controller": true,
"@metamask/rpc-errors": true,
"@metamask/transaction-controller>@metamask/base-controller": true,
- "@metamask/transaction-controller>@metamask/controller-utils": true,
"@metamask/transaction-controller>@metamask/nonce-tracker": true,
- "@metamask/utils": true,
+ "@metamask/transaction-controller>@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eth-method-registry": true,
@@ -3341,25 +3283,23 @@
"immer": true
}
},
- "@metamask/transaction-controller>@metamask/controller-utils": {
+ "@metamask/transaction-controller>@metamask/nonce-tracker": {
+ "packages": {
+ "@ethersproject/providers": true,
+ "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true,
+ "browserify>assert": true
+ }
+ },
+ "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": {
"globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
+ "clearTimeout": true,
"setTimeout": true
},
"packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/transaction-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
+ "@swc/helpers>tslib": true
}
},
- "@metamask/transaction-controller>@metamask/controller-utils>@metamask/utils": {
+ "@metamask/transaction-controller>@metamask/utils": {
"globals": {
"TextDecoder": true,
"TextEncoder": true
@@ -3374,34 +3314,18 @@
"semver": true
}
},
- "@metamask/transaction-controller>@metamask/nonce-tracker": {
- "packages": {
- "@ethersproject/providers": true,
- "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true,
- "browserify>assert": true
- }
- },
- "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": {
- "globals": {
- "clearTimeout": true,
- "setTimeout": true
- },
- "packages": {
- "@swc/helpers>tslib": true
- }
- },
"@metamask/user-operation-controller": {
"globals": {
"fetch": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller": true,
"@metamask/gas-fee-controller>@metamask/polling-controller": true,
"@metamask/rpc-errors": true,
"@metamask/transaction-controller": true,
"@metamask/user-operation-controller>@metamask/base-controller": true,
- "@metamask/user-operation-controller>@metamask/controller-utils": true,
"@metamask/utils": true,
"bn.js": true,
"lodash": true,
@@ -3418,39 +3342,6 @@
"immer": true
}
},
- "@metamask/user-operation-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/user-operation-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/user-operation-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/utils": {
"globals": {
"TextDecoder": true,
@@ -3826,9 +3717,41 @@
"@trezor/connect-web>@trezor/connect>@trezor/protobuf": {
"packages": {
"@swc/helpers>tslib": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": true,
"@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true,
- "browserify>buffer": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs": true
+ "browserify>buffer": true
+ }
+ },
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": {
+ "globals": {
+ "process": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/base64": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/eventemitter": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/float": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/path": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/pool": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/utf8": true
+ }
+ },
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": {
+ "globals": {
+ "console.log": true
+ }
+ },
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": {
+ "globals": {
+ "XMLHttpRequest": true
+ },
+ "packages": {
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true
}
},
"@trezor/connect-web>@trezor/connect>@trezor/schema-utils": {
@@ -4376,16 +4299,6 @@
"koa>is-generator-function>has-tostringtag": true
}
},
- "eslint>optionator>fast-levenshtein": {
- "globals": {
- "Intl": true,
- "Levenshtein": "write",
- "console.log": true,
- "define": true,
- "importScripts": true,
- "postMessage": true
- }
- },
"eth-ens-namehash": {
"globals": {
"name": "write"
@@ -4776,153 +4689,6 @@
"setTimeout": true
}
},
- "firebase": {
- "packages": {
- "firebase>@firebase/app": true,
- "firebase>@firebase/messaging": true
- }
- },
- "firebase>@firebase/app": {
- "globals": {
- "FinalizationRegistry": true,
- "console.warn": true
- },
- "packages": {
- "firebase>@firebase/app>@firebase/component": true,
- "firebase>@firebase/app>@firebase/logger": true,
- "firebase>@firebase/app>idb": true,
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/app>@firebase/component": {
- "packages": {
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/app>@firebase/logger": {
- "globals": {
- "console": true
- },
- "packages": {
- "@swc/helpers>tslib": true
- }
- },
- "firebase>@firebase/app>idb": {
- "globals": {
- "DOMException": true,
- "IDBCursor": true,
- "IDBDatabase": true,
- "IDBIndex": true,
- "IDBObjectStore": true,
- "IDBRequest": true,
- "IDBTransaction": true,
- "indexedDB.deleteDatabase": true,
- "indexedDB.open": true
- }
- },
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs": {
- "globals": {
- "process": true,
- "setTimeout": true
- },
- "packages": {
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/aspromise": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/base64": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/codegen": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/eventemitter": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/fetch": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/float": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/inquire": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/path": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/pool": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/utf8": true
- }
- },
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/codegen": {
- "globals": {
- "console.log": true
- }
- },
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/fetch": {
- "globals": {
- "XMLHttpRequest": true
- },
- "packages": {
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/aspromise": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/inquire": true
- }
- },
- "firebase>@firebase/installations": {
- "globals": {
- "BroadcastChannel": true,
- "Headers": true,
- "btoa": true,
- "console.error": true,
- "crypto": true,
- "fetch": true,
- "msCrypto": true,
- "navigator.onLine": true,
- "setTimeout": true
- },
- "packages": {
- "firebase>@firebase/app": true,
- "firebase>@firebase/app>@firebase/component": true,
- "firebase>@firebase/app>idb": true,
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/messaging": {
- "globals": {
- "Headers": true,
- "Notification.maxActions": true,
- "Notification.permission": true,
- "Notification.requestPermission": true,
- "PushSubscription.prototype.hasOwnProperty": true,
- "ServiceWorkerRegistration": true,
- "URL": true,
- "addEventListener": true,
- "atob": true,
- "btoa": true,
- "clients.matchAll": true,
- "clients.openWindow": true,
- "console.warn": true,
- "document": true,
- "fetch": true,
- "indexedDB": true,
- "location.href": true,
- "location.origin": true,
- "navigator": true,
- "origin.replace": true,
- "registration.showNotification": true,
- "setTimeout": true
- },
- "packages": {
- "@swc/helpers>tslib": true,
- "firebase>@firebase/app": true,
- "firebase>@firebase/app>@firebase/component": true,
- "firebase>@firebase/app>idb": true,
- "firebase>@firebase/installations": true,
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/util": {
- "globals": {
- "atob": true,
- "browser": true,
- "btoa": true,
- "chrome": true,
- "console": true,
- "document": true,
- "indexedDB": true,
- "navigator": true,
- "process": true,
- "self": true,
- "setTimeout": true
- },
- "packages": {
- "process": true
- }
- },
"fuse.js": {
"globals": {
"console": true,
diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json
index 605c88c89ea1..cc0b0f53fd56 100644
--- a/lavamoat/browserify/flask/policy.json
+++ b/lavamoat/browserify/flask/policy.json
@@ -180,8 +180,8 @@
},
"packages": {
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": true,
- "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true,
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true
+ "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true,
+ "@noble/hashes": true
}
},
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": {
@@ -189,20 +189,14 @@
"TextEncoder": true
},
"packages": {
- "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true
- }
- },
- "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": {
- "globals": {
- "TextEncoder": true,
- "crypto": true
+ "@noble/hashes": true
}
},
"@ethereumjs/tx>ethereum-cryptography>@scure/bip32": {
"packages": {
"@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/curves": true,
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": true,
- "@metamask/utils>@scure/base": true
+ "@metamask/utils>@scure/base": true,
+ "@noble/hashes": true
}
},
"@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/curves": {
@@ -210,13 +204,7 @@
"TextEncoder": true
},
"packages": {
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": true
- }
- },
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": {
- "globals": {
- "TextEncoder": true,
- "crypto": true
+ "@noble/hashes": true
}
},
"@ethersproject/abi": {
@@ -922,12 +910,12 @@
"@ethersproject/providers": true,
"@metamask/abi-utils": true,
"@metamask/assets-controllers>@metamask/base-controller": true,
- "@metamask/assets-controllers>@metamask/controller-utils": true,
"@metamask/assets-controllers>@metamask/polling-controller": true,
"@metamask/assets-controllers>@metamask/utils": true,
"@metamask/assets-controllers>cockatiel": true,
"@metamask/assets-controllers>multiformats": true,
"@metamask/contract-metadata": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/metamask-eth-abis": true,
"@metamask/name-controller>async-mutex": true,
@@ -946,24 +934,6 @@
"immer": true
}
},
- "@metamask/assets-controllers>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/assets-controllers>@metamask/utils": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/assets-controllers>@metamask/polling-controller": {
"globals": {
"clearTimeout": true,
@@ -1045,15 +1015,30 @@
},
"packages": {
"@ethereumjs/tx>@ethereumjs/util": true,
+ "@metamask/controller-utils>@metamask/utils": true,
"@metamask/controller-utils>@spruceid/siwe-parser": true,
"@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true
}
},
+ "@metamask/controller-utils>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/abi-utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/controller-utils>@spruceid/siwe-parser": {
"globals": {
"console.error": true,
@@ -1087,9 +1072,9 @@
"@metamask/ens-controller": {
"packages": {
"@ethersproject/providers": true,
+ "@metamask/controller-utils": true,
"@metamask/ens-controller>@metamask/base-controller": true,
- "@metamask/ens-controller>@metamask/controller-utils": true,
- "@metamask/utils": true,
+ "@metamask/ens-controller>@metamask/utils": true,
"punycode": true
}
},
@@ -1101,25 +1086,7 @@
"immer": true
}
},
- "@metamask/ens-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ens-controller>@metamask/controller-utils>@metamask/utils": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/ens-controller>@metamask/controller-utils>@metamask/utils": {
+ "@metamask/ens-controller>@metamask/utils": {
"globals": {
"TextDecoder": true,
"TextEncoder": true
@@ -1550,46 +1517,13 @@
"setInterval": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
- "@metamask/gas-fee-controller>@metamask/controller-utils": true,
"@metamask/gas-fee-controller>@metamask/polling-controller": true,
"bn.js": true,
"uuid": true
}
},
- "@metamask/gas-fee-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/gas-fee-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/gas-fee-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/gas-fee-controller>@metamask/polling-controller": {
"globals": {
"clearTimeout": true,
@@ -1861,8 +1795,8 @@
"fetch": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/name-controller>@metamask/base-controller": true,
- "@metamask/name-controller>@metamask/controller-utils": true,
"@metamask/name-controller>async-mutex": true,
"@metamask/utils": true
}
@@ -1875,39 +1809,6 @@
"immer": true
}
},
- "@metamask/name-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/name-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/name-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/name-controller>async-mutex": {
"globals": {
"clearTimeout": true,
@@ -1925,17 +1826,17 @@
"setTimeout": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/eth-token-tracker>@metamask/eth-block-tracker": true,
"@metamask/network-controller>@metamask/base-controller": true,
- "@metamask/network-controller>@metamask/controller-utils": true,
"@metamask/network-controller>@metamask/eth-json-rpc-infura": true,
"@metamask/network-controller>@metamask/eth-json-rpc-middleware": true,
"@metamask/network-controller>@metamask/eth-json-rpc-provider": true,
"@metamask/network-controller>@metamask/swappable-obj-proxy": true,
+ "@metamask/network-controller>@metamask/utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
- "@metamask/utils": true,
"browserify>assert": true,
"uuid": true
}
@@ -1948,39 +1849,6 @@
"immer": true
}
},
- "@metamask/network-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/network-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/network-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/network-controller>@metamask/eth-json-rpc-infura": {
"globals": {
"setTimeout": true
@@ -2017,16 +1885,31 @@
"@metamask/eth-json-rpc-middleware>safe-stable-stringify": true,
"@metamask/eth-sig-util": true,
"@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/json-rpc-engine": true,
+ "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": true,
"@metamask/rpc-errors": true,
- "@metamask/utils": true,
"pify": true
}
},
"@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/json-rpc-engine": {
"packages": {
+ "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": true,
"@metamask/rpc-errors": true,
- "@metamask/safe-event-emitter": true,
- "@metamask/utils": true
+ "@metamask/safe-event-emitter": true
+ }
+ },
+ "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true,
+ "superstruct": true
}
},
"@metamask/network-controller>@metamask/eth-json-rpc-provider": {
@@ -2037,6 +1920,21 @@
"uuid": true
}
},
+ "@metamask/network-controller>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/abi-utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/notification-controller": {
"packages": {
"@metamask/base-controller": true,
@@ -2049,6 +1947,148 @@
"crypto.getRandomValues": true
}
},
+ "@metamask/notification-services-controller": {
+ "globals": {
+ "Intl.NumberFormat": true,
+ "addEventListener": true,
+ "fetch": true,
+ "registration": true,
+ "removeEventListener": true
+ },
+ "packages": {
+ "@contentful/rich-text-html-renderer": true,
+ "@metamask/controller-utils": true,
+ "@metamask/notification-services-controller>@metamask/base-controller": true,
+ "@metamask/notification-services-controller>firebase": true,
+ "@metamask/profile-sync-controller": true,
+ "bignumber.js": true,
+ "loglevel": true,
+ "uuid": true
+ }
+ },
+ "@metamask/notification-services-controller>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
+ "packages": {
+ "immer": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase": {
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app": true,
+ "@metamask/notification-services-controller>firebase>@firebase/messaging": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app": {
+ "globals": {
+ "FinalizationRegistry": true,
+ "console.warn": true
+ },
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": true,
+ "@metamask/notification-services-controller>firebase>@firebase/util": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": {
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/util": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": {
+ "globals": {
+ "console": true
+ },
+ "packages": {
+ "@swc/helpers>tslib": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": {
+ "globals": {
+ "DOMException": true,
+ "IDBCursor": true,
+ "IDBDatabase": true,
+ "IDBIndex": true,
+ "IDBObjectStore": true,
+ "IDBRequest": true,
+ "IDBTransaction": true,
+ "indexedDB.deleteDatabase": true,
+ "indexedDB.open": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/installations": {
+ "globals": {
+ "BroadcastChannel": true,
+ "Headers": true,
+ "btoa": true,
+ "console.error": true,
+ "crypto": true,
+ "fetch": true,
+ "msCrypto": true,
+ "navigator.onLine": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": true,
+ "@metamask/notification-services-controller>firebase>@firebase/util": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/messaging": {
+ "globals": {
+ "Headers": true,
+ "Notification.maxActions": true,
+ "Notification.permission": true,
+ "Notification.requestPermission": true,
+ "PushSubscription.prototype.hasOwnProperty": true,
+ "ServiceWorkerRegistration": true,
+ "URL": true,
+ "addEventListener": true,
+ "atob": true,
+ "btoa": true,
+ "clients.matchAll": true,
+ "clients.openWindow": true,
+ "console.warn": true,
+ "document": true,
+ "fetch": true,
+ "indexedDB": true,
+ "location.href": true,
+ "location.origin": true,
+ "navigator": true,
+ "origin.replace": true,
+ "registration.showNotification": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": true,
+ "@metamask/notification-services-controller>firebase>@firebase/installations": true,
+ "@metamask/notification-services-controller>firebase>@firebase/util": true,
+ "@swc/helpers>tslib": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/util": {
+ "globals": {
+ "atob": true,
+ "browser": true,
+ "btoa": true,
+ "chrome": true,
+ "console": true,
+ "document": true,
+ "indexedDB": true,
+ "navigator": true,
+ "process": true,
+ "self": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "process": true
+ }
+ },
"@metamask/object-multiplex": {
"globals": {
"console.warn": true
@@ -2074,8 +2114,8 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/permission-controller>@metamask/base-controller": true,
- "@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/permission-controller>nanoid": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
@@ -2092,39 +2132,6 @@
"immer": true
}
},
- "@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/permission-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/permission-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -2138,18 +2145,25 @@
},
"@metamask/phishing-controller": {
"globals": {
+ "TextEncoder": true,
+ "URL": true,
"fetch": true
},
"packages": {
- "@metamask/base-controller": true,
+ "@ethereumjs/tx>ethereum-cryptography": true,
"@metamask/controller-utils": true,
- "@metamask/phishing-warning>eth-phishing-detect": true,
+ "@metamask/phishing-controller>@metamask/base-controller": true,
+ "@metamask/phishing-controller>fastest-levenshtein": true,
+ "@noble/hashes": true,
"punycode": true
}
},
- "@metamask/phishing-warning>eth-phishing-detect": {
+ "@metamask/phishing-controller>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
"packages": {
- "eslint>optionator>fast-levenshtein": true
+ "immer": true
}
},
"@metamask/post-message-stream": {
@@ -2416,27 +2430,57 @@
"console.info": true
},
"packages": {
- "@metamask/base-controller": true,
"@metamask/controller-utils": true,
"@metamask/logging-controller": true,
- "@metamask/rpc-errors": true,
+ "@metamask/signature-controller>@metamask/base-controller": true,
"@metamask/signature-controller>@metamask/message-manager": true,
"lodash": true,
"webpack>events": true
}
},
+ "@metamask/signature-controller>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
+ "packages": {
+ "immer": true
+ }
+ },
"@metamask/signature-controller>@metamask/message-manager": {
"packages": {
- "@metamask/base-controller": true,
"@metamask/controller-utils": true,
"@metamask/eth-sig-util": true,
"@metamask/message-manager>jsonschema": true,
- "@metamask/utils": true,
+ "@metamask/signature-controller>@metamask/message-manager>@metamask/base-controller": true,
+ "@metamask/signature-controller>@metamask/utils": true,
"browserify>buffer": true,
"uuid": true,
"webpack>events": true
}
},
+ "@metamask/signature-controller>@metamask/message-manager>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
+ "packages": {
+ "immer": true
+ }
+ },
+ "@metamask/signature-controller>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/abi-utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/smart-transactions-controller": {
"globals": {
"URLSearchParams": true,
@@ -2448,11 +2492,11 @@
},
"packages": {
"@ethersproject/bytes": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller>@metamask/polling-controller": true,
"@metamask/smart-transactions-controller>@ethereumjs/tx": true,
"@metamask/smart-transactions-controller>@ethereumjs/util": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller": true,
"@metamask/smart-transactions-controller>bignumber.js": true,
"browserify>buffer": true,
@@ -2509,52 +2553,6 @@
"immer": true
}
},
- "@metamask/smart-transactions-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@ethereumjs/util": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@ethereumjs/util": {
- "globals": {
- "console.warn": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/rlp": true,
- "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true,
- "@ethereumjs/tx>ethereum-cryptography": true,
- "browserify>buffer": true,
- "browserify>insert-module-globals>is-buffer": true,
- "webpack>events": true
- }
- },
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/smart-transactions-controller>@metamask/controllers>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -2572,6 +2570,7 @@
"@ethersproject/abi": true,
"@ethersproject/contracts": true,
"@ethersproject/providers": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller": true,
"@metamask/metamask-eth-abis": true,
@@ -2579,11 +2578,10 @@
"@metamask/network-controller": true,
"@metamask/rpc-errors": true,
"@metamask/smart-transactions-controller>@metamask/base-controller": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller>@ethereumjs/tx": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller>@ethereumjs/util": true,
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller>eth-method-registry": true,
- "@metamask/transaction-controller>@metamask/nonce-tracker": true,
"@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
@@ -2616,6 +2614,22 @@
"webpack>events": true
}
},
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker": {
+ "packages": {
+ "@ethersproject/providers": true,
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true,
+ "browserify>assert": true
+ }
+ },
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": {
+ "globals": {
+ "clearTimeout": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@swc/helpers>tslib": true
+ }
+ },
"@metamask/smart-transactions-controller>@metamask/transaction-controller>eth-method-registry": {
"packages": {
"@metamask/smart-transactions-controller>@metamask/transaction-controller>eth-method-registry>@metamask/ethjs-contract": true,
@@ -2773,32 +2787,14 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/base-controller": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
- "@metamask/snaps-controllers>@metamask/phishing-controller>@metamask/controller-utils": true,
"@metamask/snaps-controllers>@metamask/utils": true,
"@metamask/snaps-controllers>nanoid": true,
"deep-freeze-strict": true,
- "immer": true
- }
- },
- "@metamask/snaps-controllers>@metamask/phishing-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-controllers>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
+ "immer": true
}
},
"@metamask/snaps-controllers>@metamask/utils": {
@@ -2921,34 +2917,16 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
"@metamask/snaps-execution-environments>@metamask/snaps-utils>@metamask/base-controller": true,
- "@metamask/snaps-execution-environments>@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/snaps-execution-environments>@metamask/utils": true,
"@metamask/snaps-execution-environments>nanoid": true,
"deep-freeze-strict": true,
"immer": true
}
},
- "@metamask/snaps-execution-environments>@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-execution-environments>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/snaps-execution-environments>@metamask/utils": {
"globals": {
"TextDecoder": true,
@@ -2986,10 +2964,10 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
"@metamask/snaps-rpc-methods>@metamask/permission-controller>@metamask/base-controller": true,
- "@metamask/snaps-rpc-methods>@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/snaps-rpc-methods>@metamask/permission-controller>nanoid": true,
"@metamask/snaps-rpc-methods>@metamask/utils": true,
"deep-freeze-strict": true,
@@ -3004,24 +2982,6 @@
"immer": true
}
},
- "@metamask/snaps-rpc-methods>@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-rpc-methods>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/snaps-rpc-methods>@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -3139,34 +3099,16 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
"@metamask/snaps-utils>@metamask/base-controller": true,
- "@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/snaps-utils>@metamask/permission-controller>nanoid": true,
"@metamask/snaps-utils>@metamask/utils": true,
"deep-freeze-strict": true,
"immer": true
}
},
- "@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/snaps-utils>@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -3314,6 +3256,7 @@
"@ethersproject/abi": true,
"@ethersproject/contracts": true,
"@ethersproject/providers": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller": true,
"@metamask/metamask-eth-abis": true,
@@ -3321,9 +3264,8 @@
"@metamask/network-controller": true,
"@metamask/rpc-errors": true,
"@metamask/transaction-controller>@metamask/base-controller": true,
- "@metamask/transaction-controller>@metamask/controller-utils": true,
"@metamask/transaction-controller>@metamask/nonce-tracker": true,
- "@metamask/utils": true,
+ "@metamask/transaction-controller>@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eth-method-registry": true,
@@ -3341,25 +3283,23 @@
"immer": true
}
},
- "@metamask/transaction-controller>@metamask/controller-utils": {
+ "@metamask/transaction-controller>@metamask/nonce-tracker": {
+ "packages": {
+ "@ethersproject/providers": true,
+ "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true,
+ "browserify>assert": true
+ }
+ },
+ "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": {
"globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
+ "clearTimeout": true,
"setTimeout": true
},
"packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/transaction-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
+ "@swc/helpers>tslib": true
}
},
- "@metamask/transaction-controller>@metamask/controller-utils>@metamask/utils": {
+ "@metamask/transaction-controller>@metamask/utils": {
"globals": {
"TextDecoder": true,
"TextEncoder": true
@@ -3374,34 +3314,18 @@
"semver": true
}
},
- "@metamask/transaction-controller>@metamask/nonce-tracker": {
- "packages": {
- "@ethersproject/providers": true,
- "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true,
- "browserify>assert": true
- }
- },
- "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": {
- "globals": {
- "clearTimeout": true,
- "setTimeout": true
- },
- "packages": {
- "@swc/helpers>tslib": true
- }
- },
"@metamask/user-operation-controller": {
"globals": {
"fetch": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller": true,
"@metamask/gas-fee-controller>@metamask/polling-controller": true,
"@metamask/rpc-errors": true,
"@metamask/transaction-controller": true,
"@metamask/user-operation-controller>@metamask/base-controller": true,
- "@metamask/user-operation-controller>@metamask/controller-utils": true,
"@metamask/utils": true,
"bn.js": true,
"lodash": true,
@@ -3418,39 +3342,6 @@
"immer": true
}
},
- "@metamask/user-operation-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/user-operation-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/user-operation-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/utils": {
"globals": {
"TextDecoder": true,
@@ -3826,9 +3717,41 @@
"@trezor/connect-web>@trezor/connect>@trezor/protobuf": {
"packages": {
"@swc/helpers>tslib": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": true,
"@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true,
- "browserify>buffer": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs": true
+ "browserify>buffer": true
+ }
+ },
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": {
+ "globals": {
+ "process": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/base64": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/eventemitter": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/float": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/path": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/pool": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/utf8": true
+ }
+ },
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": {
+ "globals": {
+ "console.log": true
+ }
+ },
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": {
+ "globals": {
+ "XMLHttpRequest": true
+ },
+ "packages": {
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true
}
},
"@trezor/connect-web>@trezor/connect>@trezor/schema-utils": {
@@ -4376,16 +4299,6 @@
"koa>is-generator-function>has-tostringtag": true
}
},
- "eslint>optionator>fast-levenshtein": {
- "globals": {
- "Intl": true,
- "Levenshtein": "write",
- "console.log": true,
- "define": true,
- "importScripts": true,
- "postMessage": true
- }
- },
"eth-ens-namehash": {
"globals": {
"name": "write"
@@ -4776,153 +4689,6 @@
"setTimeout": true
}
},
- "firebase": {
- "packages": {
- "firebase>@firebase/app": true,
- "firebase>@firebase/messaging": true
- }
- },
- "firebase>@firebase/app": {
- "globals": {
- "FinalizationRegistry": true,
- "console.warn": true
- },
- "packages": {
- "firebase>@firebase/app>@firebase/component": true,
- "firebase>@firebase/app>@firebase/logger": true,
- "firebase>@firebase/app>idb": true,
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/app>@firebase/component": {
- "packages": {
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/app>@firebase/logger": {
- "globals": {
- "console": true
- },
- "packages": {
- "@swc/helpers>tslib": true
- }
- },
- "firebase>@firebase/app>idb": {
- "globals": {
- "DOMException": true,
- "IDBCursor": true,
- "IDBDatabase": true,
- "IDBIndex": true,
- "IDBObjectStore": true,
- "IDBRequest": true,
- "IDBTransaction": true,
- "indexedDB.deleteDatabase": true,
- "indexedDB.open": true
- }
- },
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs": {
- "globals": {
- "process": true,
- "setTimeout": true
- },
- "packages": {
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/aspromise": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/base64": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/codegen": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/eventemitter": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/fetch": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/float": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/inquire": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/path": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/pool": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/utf8": true
- }
- },
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/codegen": {
- "globals": {
- "console.log": true
- }
- },
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/fetch": {
- "globals": {
- "XMLHttpRequest": true
- },
- "packages": {
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/aspromise": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/inquire": true
- }
- },
- "firebase>@firebase/installations": {
- "globals": {
- "BroadcastChannel": true,
- "Headers": true,
- "btoa": true,
- "console.error": true,
- "crypto": true,
- "fetch": true,
- "msCrypto": true,
- "navigator.onLine": true,
- "setTimeout": true
- },
- "packages": {
- "firebase>@firebase/app": true,
- "firebase>@firebase/app>@firebase/component": true,
- "firebase>@firebase/app>idb": true,
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/messaging": {
- "globals": {
- "Headers": true,
- "Notification.maxActions": true,
- "Notification.permission": true,
- "Notification.requestPermission": true,
- "PushSubscription.prototype.hasOwnProperty": true,
- "ServiceWorkerRegistration": true,
- "URL": true,
- "addEventListener": true,
- "atob": true,
- "btoa": true,
- "clients.matchAll": true,
- "clients.openWindow": true,
- "console.warn": true,
- "document": true,
- "fetch": true,
- "indexedDB": true,
- "location.href": true,
- "location.origin": true,
- "navigator": true,
- "origin.replace": true,
- "registration.showNotification": true,
- "setTimeout": true
- },
- "packages": {
- "@swc/helpers>tslib": true,
- "firebase>@firebase/app": true,
- "firebase>@firebase/app>@firebase/component": true,
- "firebase>@firebase/app>idb": true,
- "firebase>@firebase/installations": true,
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/util": {
- "globals": {
- "atob": true,
- "browser": true,
- "btoa": true,
- "chrome": true,
- "console": true,
- "document": true,
- "indexedDB": true,
- "navigator": true,
- "process": true,
- "self": true,
- "setTimeout": true
- },
- "packages": {
- "process": true
- }
- },
"fuse.js": {
"globals": {
"console": true,
diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json
index 605c88c89ea1..cc0b0f53fd56 100644
--- a/lavamoat/browserify/main/policy.json
+++ b/lavamoat/browserify/main/policy.json
@@ -180,8 +180,8 @@
},
"packages": {
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": true,
- "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true,
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true
+ "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true,
+ "@noble/hashes": true
}
},
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": {
@@ -189,20 +189,14 @@
"TextEncoder": true
},
"packages": {
- "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true
- }
- },
- "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": {
- "globals": {
- "TextEncoder": true,
- "crypto": true
+ "@noble/hashes": true
}
},
"@ethereumjs/tx>ethereum-cryptography>@scure/bip32": {
"packages": {
"@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/curves": true,
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": true,
- "@metamask/utils>@scure/base": true
+ "@metamask/utils>@scure/base": true,
+ "@noble/hashes": true
}
},
"@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/curves": {
@@ -210,13 +204,7 @@
"TextEncoder": true
},
"packages": {
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": true
- }
- },
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": {
- "globals": {
- "TextEncoder": true,
- "crypto": true
+ "@noble/hashes": true
}
},
"@ethersproject/abi": {
@@ -922,12 +910,12 @@
"@ethersproject/providers": true,
"@metamask/abi-utils": true,
"@metamask/assets-controllers>@metamask/base-controller": true,
- "@metamask/assets-controllers>@metamask/controller-utils": true,
"@metamask/assets-controllers>@metamask/polling-controller": true,
"@metamask/assets-controllers>@metamask/utils": true,
"@metamask/assets-controllers>cockatiel": true,
"@metamask/assets-controllers>multiformats": true,
"@metamask/contract-metadata": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/metamask-eth-abis": true,
"@metamask/name-controller>async-mutex": true,
@@ -946,24 +934,6 @@
"immer": true
}
},
- "@metamask/assets-controllers>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/assets-controllers>@metamask/utils": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/assets-controllers>@metamask/polling-controller": {
"globals": {
"clearTimeout": true,
@@ -1045,15 +1015,30 @@
},
"packages": {
"@ethereumjs/tx>@ethereumjs/util": true,
+ "@metamask/controller-utils>@metamask/utils": true,
"@metamask/controller-utils>@spruceid/siwe-parser": true,
"@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true
}
},
+ "@metamask/controller-utils>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/abi-utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/controller-utils>@spruceid/siwe-parser": {
"globals": {
"console.error": true,
@@ -1087,9 +1072,9 @@
"@metamask/ens-controller": {
"packages": {
"@ethersproject/providers": true,
+ "@metamask/controller-utils": true,
"@metamask/ens-controller>@metamask/base-controller": true,
- "@metamask/ens-controller>@metamask/controller-utils": true,
- "@metamask/utils": true,
+ "@metamask/ens-controller>@metamask/utils": true,
"punycode": true
}
},
@@ -1101,25 +1086,7 @@
"immer": true
}
},
- "@metamask/ens-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ens-controller>@metamask/controller-utils>@metamask/utils": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/ens-controller>@metamask/controller-utils>@metamask/utils": {
+ "@metamask/ens-controller>@metamask/utils": {
"globals": {
"TextDecoder": true,
"TextEncoder": true
@@ -1550,46 +1517,13 @@
"setInterval": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
- "@metamask/gas-fee-controller>@metamask/controller-utils": true,
"@metamask/gas-fee-controller>@metamask/polling-controller": true,
"bn.js": true,
"uuid": true
}
},
- "@metamask/gas-fee-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/gas-fee-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/gas-fee-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/gas-fee-controller>@metamask/polling-controller": {
"globals": {
"clearTimeout": true,
@@ -1861,8 +1795,8 @@
"fetch": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/name-controller>@metamask/base-controller": true,
- "@metamask/name-controller>@metamask/controller-utils": true,
"@metamask/name-controller>async-mutex": true,
"@metamask/utils": true
}
@@ -1875,39 +1809,6 @@
"immer": true
}
},
- "@metamask/name-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/name-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/name-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/name-controller>async-mutex": {
"globals": {
"clearTimeout": true,
@@ -1925,17 +1826,17 @@
"setTimeout": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/eth-token-tracker>@metamask/eth-block-tracker": true,
"@metamask/network-controller>@metamask/base-controller": true,
- "@metamask/network-controller>@metamask/controller-utils": true,
"@metamask/network-controller>@metamask/eth-json-rpc-infura": true,
"@metamask/network-controller>@metamask/eth-json-rpc-middleware": true,
"@metamask/network-controller>@metamask/eth-json-rpc-provider": true,
"@metamask/network-controller>@metamask/swappable-obj-proxy": true,
+ "@metamask/network-controller>@metamask/utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
- "@metamask/utils": true,
"browserify>assert": true,
"uuid": true
}
@@ -1948,39 +1849,6 @@
"immer": true
}
},
- "@metamask/network-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/network-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/network-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/network-controller>@metamask/eth-json-rpc-infura": {
"globals": {
"setTimeout": true
@@ -2017,16 +1885,31 @@
"@metamask/eth-json-rpc-middleware>safe-stable-stringify": true,
"@metamask/eth-sig-util": true,
"@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/json-rpc-engine": true,
+ "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": true,
"@metamask/rpc-errors": true,
- "@metamask/utils": true,
"pify": true
}
},
"@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/json-rpc-engine": {
"packages": {
+ "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": true,
"@metamask/rpc-errors": true,
- "@metamask/safe-event-emitter": true,
- "@metamask/utils": true
+ "@metamask/safe-event-emitter": true
+ }
+ },
+ "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true,
+ "superstruct": true
}
},
"@metamask/network-controller>@metamask/eth-json-rpc-provider": {
@@ -2037,6 +1920,21 @@
"uuid": true
}
},
+ "@metamask/network-controller>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/abi-utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/notification-controller": {
"packages": {
"@metamask/base-controller": true,
@@ -2049,6 +1947,148 @@
"crypto.getRandomValues": true
}
},
+ "@metamask/notification-services-controller": {
+ "globals": {
+ "Intl.NumberFormat": true,
+ "addEventListener": true,
+ "fetch": true,
+ "registration": true,
+ "removeEventListener": true
+ },
+ "packages": {
+ "@contentful/rich-text-html-renderer": true,
+ "@metamask/controller-utils": true,
+ "@metamask/notification-services-controller>@metamask/base-controller": true,
+ "@metamask/notification-services-controller>firebase": true,
+ "@metamask/profile-sync-controller": true,
+ "bignumber.js": true,
+ "loglevel": true,
+ "uuid": true
+ }
+ },
+ "@metamask/notification-services-controller>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
+ "packages": {
+ "immer": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase": {
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app": true,
+ "@metamask/notification-services-controller>firebase>@firebase/messaging": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app": {
+ "globals": {
+ "FinalizationRegistry": true,
+ "console.warn": true
+ },
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": true,
+ "@metamask/notification-services-controller>firebase>@firebase/util": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": {
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/util": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": {
+ "globals": {
+ "console": true
+ },
+ "packages": {
+ "@swc/helpers>tslib": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": {
+ "globals": {
+ "DOMException": true,
+ "IDBCursor": true,
+ "IDBDatabase": true,
+ "IDBIndex": true,
+ "IDBObjectStore": true,
+ "IDBRequest": true,
+ "IDBTransaction": true,
+ "indexedDB.deleteDatabase": true,
+ "indexedDB.open": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/installations": {
+ "globals": {
+ "BroadcastChannel": true,
+ "Headers": true,
+ "btoa": true,
+ "console.error": true,
+ "crypto": true,
+ "fetch": true,
+ "msCrypto": true,
+ "navigator.onLine": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": true,
+ "@metamask/notification-services-controller>firebase>@firebase/util": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/messaging": {
+ "globals": {
+ "Headers": true,
+ "Notification.maxActions": true,
+ "Notification.permission": true,
+ "Notification.requestPermission": true,
+ "PushSubscription.prototype.hasOwnProperty": true,
+ "ServiceWorkerRegistration": true,
+ "URL": true,
+ "addEventListener": true,
+ "atob": true,
+ "btoa": true,
+ "clients.matchAll": true,
+ "clients.openWindow": true,
+ "console.warn": true,
+ "document": true,
+ "fetch": true,
+ "indexedDB": true,
+ "location.href": true,
+ "location.origin": true,
+ "navigator": true,
+ "origin.replace": true,
+ "registration.showNotification": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": true,
+ "@metamask/notification-services-controller>firebase>@firebase/installations": true,
+ "@metamask/notification-services-controller>firebase>@firebase/util": true,
+ "@swc/helpers>tslib": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/util": {
+ "globals": {
+ "atob": true,
+ "browser": true,
+ "btoa": true,
+ "chrome": true,
+ "console": true,
+ "document": true,
+ "indexedDB": true,
+ "navigator": true,
+ "process": true,
+ "self": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "process": true
+ }
+ },
"@metamask/object-multiplex": {
"globals": {
"console.warn": true
@@ -2074,8 +2114,8 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/permission-controller>@metamask/base-controller": true,
- "@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/permission-controller>nanoid": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
@@ -2092,39 +2132,6 @@
"immer": true
}
},
- "@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/permission-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/permission-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -2138,18 +2145,25 @@
},
"@metamask/phishing-controller": {
"globals": {
+ "TextEncoder": true,
+ "URL": true,
"fetch": true
},
"packages": {
- "@metamask/base-controller": true,
+ "@ethereumjs/tx>ethereum-cryptography": true,
"@metamask/controller-utils": true,
- "@metamask/phishing-warning>eth-phishing-detect": true,
+ "@metamask/phishing-controller>@metamask/base-controller": true,
+ "@metamask/phishing-controller>fastest-levenshtein": true,
+ "@noble/hashes": true,
"punycode": true
}
},
- "@metamask/phishing-warning>eth-phishing-detect": {
+ "@metamask/phishing-controller>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
"packages": {
- "eslint>optionator>fast-levenshtein": true
+ "immer": true
}
},
"@metamask/post-message-stream": {
@@ -2416,27 +2430,57 @@
"console.info": true
},
"packages": {
- "@metamask/base-controller": true,
"@metamask/controller-utils": true,
"@metamask/logging-controller": true,
- "@metamask/rpc-errors": true,
+ "@metamask/signature-controller>@metamask/base-controller": true,
"@metamask/signature-controller>@metamask/message-manager": true,
"lodash": true,
"webpack>events": true
}
},
+ "@metamask/signature-controller>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
+ "packages": {
+ "immer": true
+ }
+ },
"@metamask/signature-controller>@metamask/message-manager": {
"packages": {
- "@metamask/base-controller": true,
"@metamask/controller-utils": true,
"@metamask/eth-sig-util": true,
"@metamask/message-manager>jsonschema": true,
- "@metamask/utils": true,
+ "@metamask/signature-controller>@metamask/message-manager>@metamask/base-controller": true,
+ "@metamask/signature-controller>@metamask/utils": true,
"browserify>buffer": true,
"uuid": true,
"webpack>events": true
}
},
+ "@metamask/signature-controller>@metamask/message-manager>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
+ "packages": {
+ "immer": true
+ }
+ },
+ "@metamask/signature-controller>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/abi-utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/smart-transactions-controller": {
"globals": {
"URLSearchParams": true,
@@ -2448,11 +2492,11 @@
},
"packages": {
"@ethersproject/bytes": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller>@metamask/polling-controller": true,
"@metamask/smart-transactions-controller>@ethereumjs/tx": true,
"@metamask/smart-transactions-controller>@ethereumjs/util": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller": true,
"@metamask/smart-transactions-controller>bignumber.js": true,
"browserify>buffer": true,
@@ -2509,52 +2553,6 @@
"immer": true
}
},
- "@metamask/smart-transactions-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@ethereumjs/util": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@ethereumjs/util": {
- "globals": {
- "console.warn": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/rlp": true,
- "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true,
- "@ethereumjs/tx>ethereum-cryptography": true,
- "browserify>buffer": true,
- "browserify>insert-module-globals>is-buffer": true,
- "webpack>events": true
- }
- },
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/smart-transactions-controller>@metamask/controllers>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -2572,6 +2570,7 @@
"@ethersproject/abi": true,
"@ethersproject/contracts": true,
"@ethersproject/providers": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller": true,
"@metamask/metamask-eth-abis": true,
@@ -2579,11 +2578,10 @@
"@metamask/network-controller": true,
"@metamask/rpc-errors": true,
"@metamask/smart-transactions-controller>@metamask/base-controller": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller>@ethereumjs/tx": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller>@ethereumjs/util": true,
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller>eth-method-registry": true,
- "@metamask/transaction-controller>@metamask/nonce-tracker": true,
"@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
@@ -2616,6 +2614,22 @@
"webpack>events": true
}
},
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker": {
+ "packages": {
+ "@ethersproject/providers": true,
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true,
+ "browserify>assert": true
+ }
+ },
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": {
+ "globals": {
+ "clearTimeout": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@swc/helpers>tslib": true
+ }
+ },
"@metamask/smart-transactions-controller>@metamask/transaction-controller>eth-method-registry": {
"packages": {
"@metamask/smart-transactions-controller>@metamask/transaction-controller>eth-method-registry>@metamask/ethjs-contract": true,
@@ -2773,32 +2787,14 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/base-controller": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
- "@metamask/snaps-controllers>@metamask/phishing-controller>@metamask/controller-utils": true,
"@metamask/snaps-controllers>@metamask/utils": true,
"@metamask/snaps-controllers>nanoid": true,
"deep-freeze-strict": true,
- "immer": true
- }
- },
- "@metamask/snaps-controllers>@metamask/phishing-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-controllers>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
+ "immer": true
}
},
"@metamask/snaps-controllers>@metamask/utils": {
@@ -2921,34 +2917,16 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
"@metamask/snaps-execution-environments>@metamask/snaps-utils>@metamask/base-controller": true,
- "@metamask/snaps-execution-environments>@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/snaps-execution-environments>@metamask/utils": true,
"@metamask/snaps-execution-environments>nanoid": true,
"deep-freeze-strict": true,
"immer": true
}
},
- "@metamask/snaps-execution-environments>@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-execution-environments>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/snaps-execution-environments>@metamask/utils": {
"globals": {
"TextDecoder": true,
@@ -2986,10 +2964,10 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
"@metamask/snaps-rpc-methods>@metamask/permission-controller>@metamask/base-controller": true,
- "@metamask/snaps-rpc-methods>@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/snaps-rpc-methods>@metamask/permission-controller>nanoid": true,
"@metamask/snaps-rpc-methods>@metamask/utils": true,
"deep-freeze-strict": true,
@@ -3004,24 +2982,6 @@
"immer": true
}
},
- "@metamask/snaps-rpc-methods>@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-rpc-methods>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/snaps-rpc-methods>@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -3139,34 +3099,16 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
"@metamask/snaps-utils>@metamask/base-controller": true,
- "@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/snaps-utils>@metamask/permission-controller>nanoid": true,
"@metamask/snaps-utils>@metamask/utils": true,
"deep-freeze-strict": true,
"immer": true
}
},
- "@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/snaps-utils>@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -3314,6 +3256,7 @@
"@ethersproject/abi": true,
"@ethersproject/contracts": true,
"@ethersproject/providers": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller": true,
"@metamask/metamask-eth-abis": true,
@@ -3321,9 +3264,8 @@
"@metamask/network-controller": true,
"@metamask/rpc-errors": true,
"@metamask/transaction-controller>@metamask/base-controller": true,
- "@metamask/transaction-controller>@metamask/controller-utils": true,
"@metamask/transaction-controller>@metamask/nonce-tracker": true,
- "@metamask/utils": true,
+ "@metamask/transaction-controller>@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eth-method-registry": true,
@@ -3341,25 +3283,23 @@
"immer": true
}
},
- "@metamask/transaction-controller>@metamask/controller-utils": {
+ "@metamask/transaction-controller>@metamask/nonce-tracker": {
+ "packages": {
+ "@ethersproject/providers": true,
+ "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true,
+ "browserify>assert": true
+ }
+ },
+ "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": {
"globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
+ "clearTimeout": true,
"setTimeout": true
},
"packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/transaction-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
+ "@swc/helpers>tslib": true
}
},
- "@metamask/transaction-controller>@metamask/controller-utils>@metamask/utils": {
+ "@metamask/transaction-controller>@metamask/utils": {
"globals": {
"TextDecoder": true,
"TextEncoder": true
@@ -3374,34 +3314,18 @@
"semver": true
}
},
- "@metamask/transaction-controller>@metamask/nonce-tracker": {
- "packages": {
- "@ethersproject/providers": true,
- "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true,
- "browserify>assert": true
- }
- },
- "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": {
- "globals": {
- "clearTimeout": true,
- "setTimeout": true
- },
- "packages": {
- "@swc/helpers>tslib": true
- }
- },
"@metamask/user-operation-controller": {
"globals": {
"fetch": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller": true,
"@metamask/gas-fee-controller>@metamask/polling-controller": true,
"@metamask/rpc-errors": true,
"@metamask/transaction-controller": true,
"@metamask/user-operation-controller>@metamask/base-controller": true,
- "@metamask/user-operation-controller>@metamask/controller-utils": true,
"@metamask/utils": true,
"bn.js": true,
"lodash": true,
@@ -3418,39 +3342,6 @@
"immer": true
}
},
- "@metamask/user-operation-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/user-operation-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/user-operation-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/utils": {
"globals": {
"TextDecoder": true,
@@ -3826,9 +3717,41 @@
"@trezor/connect-web>@trezor/connect>@trezor/protobuf": {
"packages": {
"@swc/helpers>tslib": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": true,
"@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true,
- "browserify>buffer": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs": true
+ "browserify>buffer": true
+ }
+ },
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": {
+ "globals": {
+ "process": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/base64": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/eventemitter": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/float": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/path": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/pool": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/utf8": true
+ }
+ },
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": {
+ "globals": {
+ "console.log": true
+ }
+ },
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": {
+ "globals": {
+ "XMLHttpRequest": true
+ },
+ "packages": {
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true
}
},
"@trezor/connect-web>@trezor/connect>@trezor/schema-utils": {
@@ -4376,16 +4299,6 @@
"koa>is-generator-function>has-tostringtag": true
}
},
- "eslint>optionator>fast-levenshtein": {
- "globals": {
- "Intl": true,
- "Levenshtein": "write",
- "console.log": true,
- "define": true,
- "importScripts": true,
- "postMessage": true
- }
- },
"eth-ens-namehash": {
"globals": {
"name": "write"
@@ -4776,153 +4689,6 @@
"setTimeout": true
}
},
- "firebase": {
- "packages": {
- "firebase>@firebase/app": true,
- "firebase>@firebase/messaging": true
- }
- },
- "firebase>@firebase/app": {
- "globals": {
- "FinalizationRegistry": true,
- "console.warn": true
- },
- "packages": {
- "firebase>@firebase/app>@firebase/component": true,
- "firebase>@firebase/app>@firebase/logger": true,
- "firebase>@firebase/app>idb": true,
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/app>@firebase/component": {
- "packages": {
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/app>@firebase/logger": {
- "globals": {
- "console": true
- },
- "packages": {
- "@swc/helpers>tslib": true
- }
- },
- "firebase>@firebase/app>idb": {
- "globals": {
- "DOMException": true,
- "IDBCursor": true,
- "IDBDatabase": true,
- "IDBIndex": true,
- "IDBObjectStore": true,
- "IDBRequest": true,
- "IDBTransaction": true,
- "indexedDB.deleteDatabase": true,
- "indexedDB.open": true
- }
- },
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs": {
- "globals": {
- "process": true,
- "setTimeout": true
- },
- "packages": {
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/aspromise": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/base64": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/codegen": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/eventemitter": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/fetch": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/float": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/inquire": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/path": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/pool": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/utf8": true
- }
- },
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/codegen": {
- "globals": {
- "console.log": true
- }
- },
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/fetch": {
- "globals": {
- "XMLHttpRequest": true
- },
- "packages": {
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/aspromise": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/inquire": true
- }
- },
- "firebase>@firebase/installations": {
- "globals": {
- "BroadcastChannel": true,
- "Headers": true,
- "btoa": true,
- "console.error": true,
- "crypto": true,
- "fetch": true,
- "msCrypto": true,
- "navigator.onLine": true,
- "setTimeout": true
- },
- "packages": {
- "firebase>@firebase/app": true,
- "firebase>@firebase/app>@firebase/component": true,
- "firebase>@firebase/app>idb": true,
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/messaging": {
- "globals": {
- "Headers": true,
- "Notification.maxActions": true,
- "Notification.permission": true,
- "Notification.requestPermission": true,
- "PushSubscription.prototype.hasOwnProperty": true,
- "ServiceWorkerRegistration": true,
- "URL": true,
- "addEventListener": true,
- "atob": true,
- "btoa": true,
- "clients.matchAll": true,
- "clients.openWindow": true,
- "console.warn": true,
- "document": true,
- "fetch": true,
- "indexedDB": true,
- "location.href": true,
- "location.origin": true,
- "navigator": true,
- "origin.replace": true,
- "registration.showNotification": true,
- "setTimeout": true
- },
- "packages": {
- "@swc/helpers>tslib": true,
- "firebase>@firebase/app": true,
- "firebase>@firebase/app>@firebase/component": true,
- "firebase>@firebase/app>idb": true,
- "firebase>@firebase/installations": true,
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/util": {
- "globals": {
- "atob": true,
- "browser": true,
- "btoa": true,
- "chrome": true,
- "console": true,
- "document": true,
- "indexedDB": true,
- "navigator": true,
- "process": true,
- "self": true,
- "setTimeout": true
- },
- "packages": {
- "process": true
- }
- },
"fuse.js": {
"globals": {
"console": true,
diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json
index 96ba8b467983..e74fd5eb14c1 100644
--- a/lavamoat/browserify/mmi/policy.json
+++ b/lavamoat/browserify/mmi/policy.json
@@ -180,8 +180,8 @@
},
"packages": {
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": true,
- "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true,
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true
+ "@ethereumjs/tx>ethereum-cryptography>@scure/bip32": true,
+ "@noble/hashes": true
}
},
"@ethereumjs/tx>ethereum-cryptography>@noble/curves": {
@@ -189,20 +189,14 @@
"TextEncoder": true
},
"packages": {
- "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": true
- }
- },
- "@ethereumjs/tx>ethereum-cryptography>@noble/hashes": {
- "globals": {
- "TextEncoder": true,
- "crypto": true
+ "@noble/hashes": true
}
},
"@ethereumjs/tx>ethereum-cryptography>@scure/bip32": {
"packages": {
"@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/curves": true,
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": true,
- "@metamask/utils>@scure/base": true
+ "@metamask/utils>@scure/base": true,
+ "@noble/hashes": true
}
},
"@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/curves": {
@@ -210,13 +204,7 @@
"TextEncoder": true
},
"packages": {
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": true
- }
- },
- "@ethereumjs/tx>ethereum-cryptography>@scure/bip32>@noble/hashes": {
- "globals": {
- "TextEncoder": true,
- "crypto": true
+ "@noble/hashes": true
}
},
"@ethersproject/abi": {
@@ -1014,12 +1002,12 @@
"@ethersproject/providers": true,
"@metamask/abi-utils": true,
"@metamask/assets-controllers>@metamask/base-controller": true,
- "@metamask/assets-controllers>@metamask/controller-utils": true,
"@metamask/assets-controllers>@metamask/polling-controller": true,
"@metamask/assets-controllers>@metamask/utils": true,
"@metamask/assets-controllers>cockatiel": true,
"@metamask/assets-controllers>multiformats": true,
"@metamask/contract-metadata": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/metamask-eth-abis": true,
"@metamask/name-controller>async-mutex": true,
@@ -1038,24 +1026,6 @@
"immer": true
}
},
- "@metamask/assets-controllers>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/assets-controllers>@metamask/utils": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/assets-controllers>@metamask/polling-controller": {
"globals": {
"clearTimeout": true,
@@ -1137,15 +1107,30 @@
},
"packages": {
"@ethereumjs/tx>@ethereumjs/util": true,
+ "@metamask/controller-utils>@metamask/utils": true,
"@metamask/controller-utils>@spruceid/siwe-parser": true,
"@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eslint>fast-deep-equal": true,
"eth-ens-namehash": true
}
},
+ "@metamask/controller-utils>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/abi-utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/controller-utils>@spruceid/siwe-parser": {
"globals": {
"console.error": true,
@@ -1179,9 +1164,9 @@
"@metamask/ens-controller": {
"packages": {
"@ethersproject/providers": true,
+ "@metamask/controller-utils": true,
"@metamask/ens-controller>@metamask/base-controller": true,
- "@metamask/ens-controller>@metamask/controller-utils": true,
- "@metamask/utils": true,
+ "@metamask/ens-controller>@metamask/utils": true,
"punycode": true
}
},
@@ -1193,25 +1178,7 @@
"immer": true
}
},
- "@metamask/ens-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ens-controller>@metamask/controller-utils>@metamask/utils": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/ens-controller>@metamask/controller-utils>@metamask/utils": {
+ "@metamask/ens-controller>@metamask/utils": {
"globals": {
"TextDecoder": true,
"TextEncoder": true
@@ -1642,46 +1609,13 @@
"setInterval": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
- "@metamask/gas-fee-controller>@metamask/controller-utils": true,
"@metamask/gas-fee-controller>@metamask/polling-controller": true,
"bn.js": true,
"uuid": true
}
},
- "@metamask/gas-fee-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/gas-fee-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/gas-fee-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/gas-fee-controller>@metamask/polling-controller": {
"globals": {
"clearTimeout": true,
@@ -1953,8 +1887,8 @@
"fetch": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/name-controller>@metamask/base-controller": true,
- "@metamask/name-controller>@metamask/controller-utils": true,
"@metamask/name-controller>async-mutex": true,
"@metamask/utils": true
}
@@ -1967,39 +1901,6 @@
"immer": true
}
},
- "@metamask/name-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/name-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/name-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/name-controller>async-mutex": {
"globals": {
"clearTimeout": true,
@@ -2017,17 +1918,17 @@
"setTimeout": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/eth-token-tracker>@metamask/eth-block-tracker": true,
"@metamask/network-controller>@metamask/base-controller": true,
- "@metamask/network-controller>@metamask/controller-utils": true,
"@metamask/network-controller>@metamask/eth-json-rpc-infura": true,
"@metamask/network-controller>@metamask/eth-json-rpc-middleware": true,
"@metamask/network-controller>@metamask/eth-json-rpc-provider": true,
"@metamask/network-controller>@metamask/swappable-obj-proxy": true,
+ "@metamask/network-controller>@metamask/utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
- "@metamask/utils": true,
"browserify>assert": true,
"uuid": true
}
@@ -2040,39 +1941,6 @@
"immer": true
}
},
- "@metamask/network-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/network-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/network-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/network-controller>@metamask/eth-json-rpc-infura": {
"globals": {
"setTimeout": true
@@ -2109,16 +1977,31 @@
"@metamask/eth-json-rpc-middleware>safe-stable-stringify": true,
"@metamask/eth-sig-util": true,
"@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/json-rpc-engine": true,
+ "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": true,
"@metamask/rpc-errors": true,
- "@metamask/utils": true,
"pify": true
}
},
"@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/json-rpc-engine": {
"packages": {
+ "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": true,
"@metamask/rpc-errors": true,
- "@metamask/safe-event-emitter": true,
- "@metamask/utils": true
+ "@metamask/safe-event-emitter": true
+ }
+ },
+ "@metamask/network-controller>@metamask/eth-json-rpc-middleware>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true,
+ "superstruct": true
}
},
"@metamask/network-controller>@metamask/eth-json-rpc-provider": {
@@ -2129,6 +2012,21 @@
"uuid": true
}
},
+ "@metamask/network-controller>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/abi-utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/notification-controller": {
"packages": {
"@metamask/base-controller": true,
@@ -2141,6 +2039,148 @@
"crypto.getRandomValues": true
}
},
+ "@metamask/notification-services-controller": {
+ "globals": {
+ "Intl.NumberFormat": true,
+ "addEventListener": true,
+ "fetch": true,
+ "registration": true,
+ "removeEventListener": true
+ },
+ "packages": {
+ "@contentful/rich-text-html-renderer": true,
+ "@metamask/controller-utils": true,
+ "@metamask/notification-services-controller>@metamask/base-controller": true,
+ "@metamask/notification-services-controller>firebase": true,
+ "@metamask/profile-sync-controller": true,
+ "bignumber.js": true,
+ "loglevel": true,
+ "uuid": true
+ }
+ },
+ "@metamask/notification-services-controller>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
+ "packages": {
+ "immer": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase": {
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app": true,
+ "@metamask/notification-services-controller>firebase>@firebase/messaging": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app": {
+ "globals": {
+ "FinalizationRegistry": true,
+ "console.warn": true
+ },
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": true,
+ "@metamask/notification-services-controller>firebase>@firebase/util": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": {
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/util": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/logger": {
+ "globals": {
+ "console": true
+ },
+ "packages": {
+ "@swc/helpers>tslib": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": {
+ "globals": {
+ "DOMException": true,
+ "IDBCursor": true,
+ "IDBDatabase": true,
+ "IDBIndex": true,
+ "IDBObjectStore": true,
+ "IDBRequest": true,
+ "IDBTransaction": true,
+ "indexedDB.deleteDatabase": true,
+ "indexedDB.open": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/installations": {
+ "globals": {
+ "BroadcastChannel": true,
+ "Headers": true,
+ "btoa": true,
+ "console.error": true,
+ "crypto": true,
+ "fetch": true,
+ "msCrypto": true,
+ "navigator.onLine": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": true,
+ "@metamask/notification-services-controller>firebase>@firebase/util": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/messaging": {
+ "globals": {
+ "Headers": true,
+ "Notification.maxActions": true,
+ "Notification.permission": true,
+ "Notification.requestPermission": true,
+ "PushSubscription.prototype.hasOwnProperty": true,
+ "ServiceWorkerRegistration": true,
+ "URL": true,
+ "addEventListener": true,
+ "atob": true,
+ "btoa": true,
+ "clients.matchAll": true,
+ "clients.openWindow": true,
+ "console.warn": true,
+ "document": true,
+ "fetch": true,
+ "indexedDB": true,
+ "location.href": true,
+ "location.origin": true,
+ "navigator": true,
+ "origin.replace": true,
+ "registration.showNotification": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@metamask/notification-services-controller>firebase>@firebase/app": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>@firebase/component": true,
+ "@metamask/notification-services-controller>firebase>@firebase/app>idb": true,
+ "@metamask/notification-services-controller>firebase>@firebase/installations": true,
+ "@metamask/notification-services-controller>firebase>@firebase/util": true,
+ "@swc/helpers>tslib": true
+ }
+ },
+ "@metamask/notification-services-controller>firebase>@firebase/util": {
+ "globals": {
+ "atob": true,
+ "browser": true,
+ "btoa": true,
+ "chrome": true,
+ "console": true,
+ "document": true,
+ "indexedDB": true,
+ "navigator": true,
+ "process": true,
+ "self": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "process": true
+ }
+ },
"@metamask/object-multiplex": {
"globals": {
"console.warn": true
@@ -2166,8 +2206,8 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/permission-controller>@metamask/base-controller": true,
- "@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/permission-controller>nanoid": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
@@ -2184,39 +2224,6 @@
"immer": true
}
},
- "@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/permission-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/permission-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -2230,18 +2237,25 @@
},
"@metamask/phishing-controller": {
"globals": {
+ "TextEncoder": true,
+ "URL": true,
"fetch": true
},
"packages": {
- "@metamask/base-controller": true,
+ "@ethereumjs/tx>ethereum-cryptography": true,
"@metamask/controller-utils": true,
- "@metamask/phishing-warning>eth-phishing-detect": true,
+ "@metamask/phishing-controller>@metamask/base-controller": true,
+ "@metamask/phishing-controller>fastest-levenshtein": true,
+ "@noble/hashes": true,
"punycode": true
}
},
- "@metamask/phishing-warning>eth-phishing-detect": {
+ "@metamask/phishing-controller>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
"packages": {
- "eslint>optionator>fast-levenshtein": true
+ "immer": true
}
},
"@metamask/post-message-stream": {
@@ -2508,27 +2522,57 @@
"console.info": true
},
"packages": {
- "@metamask/base-controller": true,
"@metamask/controller-utils": true,
"@metamask/logging-controller": true,
- "@metamask/rpc-errors": true,
+ "@metamask/signature-controller>@metamask/base-controller": true,
"@metamask/signature-controller>@metamask/message-manager": true,
"lodash": true,
"webpack>events": true
}
},
+ "@metamask/signature-controller>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
+ "packages": {
+ "immer": true
+ }
+ },
"@metamask/signature-controller>@metamask/message-manager": {
"packages": {
- "@metamask/base-controller": true,
"@metamask/controller-utils": true,
"@metamask/eth-sig-util": true,
"@metamask/message-manager>jsonschema": true,
- "@metamask/utils": true,
+ "@metamask/signature-controller>@metamask/message-manager>@metamask/base-controller": true,
+ "@metamask/signature-controller>@metamask/utils": true,
"browserify>buffer": true,
"uuid": true,
"webpack>events": true
}
},
+ "@metamask/signature-controller>@metamask/message-manager>@metamask/base-controller": {
+ "globals": {
+ "setTimeout": true
+ },
+ "packages": {
+ "immer": true
+ }
+ },
+ "@metamask/signature-controller>@metamask/utils": {
+ "globals": {
+ "TextDecoder": true,
+ "TextEncoder": true
+ },
+ "packages": {
+ "@metamask/abi-utils>@metamask/superstruct": true,
+ "@metamask/utils>@scure/base": true,
+ "@metamask/utils>pony-cause": true,
+ "@noble/hashes": true,
+ "browserify>buffer": true,
+ "nock>debug": true,
+ "semver": true
+ }
+ },
"@metamask/smart-transactions-controller": {
"globals": {
"URLSearchParams": true,
@@ -2540,11 +2584,11 @@
},
"packages": {
"@ethersproject/bytes": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller>@metamask/polling-controller": true,
"@metamask/smart-transactions-controller>@ethereumjs/tx": true,
"@metamask/smart-transactions-controller>@ethereumjs/util": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller": true,
"@metamask/smart-transactions-controller>bignumber.js": true,
"browserify>buffer": true,
@@ -2601,52 +2645,6 @@
"immer": true
}
},
- "@metamask/smart-transactions-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@ethereumjs/util": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@ethereumjs/util": {
- "globals": {
- "console.warn": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/rlp": true,
- "@ethereumjs/tx>@ethereumjs/util>micro-ftch": true,
- "@ethereumjs/tx>ethereum-cryptography": true,
- "browserify>buffer": true,
- "browserify>insert-module-globals>is-buffer": true,
- "webpack>events": true
- }
- },
- "@metamask/smart-transactions-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/smart-transactions-controller>@metamask/controllers>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -2664,6 +2662,7 @@
"@ethersproject/abi": true,
"@ethersproject/contracts": true,
"@ethersproject/providers": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller": true,
"@metamask/metamask-eth-abis": true,
@@ -2671,11 +2670,10 @@
"@metamask/network-controller": true,
"@metamask/rpc-errors": true,
"@metamask/smart-transactions-controller>@metamask/base-controller": true,
- "@metamask/smart-transactions-controller>@metamask/controller-utils": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller>@ethereumjs/tx": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller>@ethereumjs/util": true,
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker": true,
"@metamask/smart-transactions-controller>@metamask/transaction-controller>eth-method-registry": true,
- "@metamask/transaction-controller>@metamask/nonce-tracker": true,
"@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
@@ -2708,6 +2706,22 @@
"webpack>events": true
}
},
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker": {
+ "packages": {
+ "@ethersproject/providers": true,
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true,
+ "browserify>assert": true
+ }
+ },
+ "@metamask/smart-transactions-controller>@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": {
+ "globals": {
+ "clearTimeout": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@swc/helpers>tslib": true
+ }
+ },
"@metamask/smart-transactions-controller>@metamask/transaction-controller>eth-method-registry": {
"packages": {
"@metamask/smart-transactions-controller>@metamask/transaction-controller>eth-method-registry>@metamask/ethjs-contract": true,
@@ -2865,32 +2879,14 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/base-controller": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
- "@metamask/snaps-controllers>@metamask/phishing-controller>@metamask/controller-utils": true,
"@metamask/snaps-controllers>@metamask/utils": true,
"@metamask/snaps-controllers>nanoid": true,
"deep-freeze-strict": true,
- "immer": true
- }
- },
- "@metamask/snaps-controllers>@metamask/phishing-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-controllers>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
+ "immer": true
}
},
"@metamask/snaps-controllers>@metamask/utils": {
@@ -3013,34 +3009,16 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
"@metamask/snaps-execution-environments>@metamask/snaps-utils>@metamask/base-controller": true,
- "@metamask/snaps-execution-environments>@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/snaps-execution-environments>@metamask/utils": true,
"@metamask/snaps-execution-environments>nanoid": true,
"deep-freeze-strict": true,
"immer": true
}
},
- "@metamask/snaps-execution-environments>@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-execution-environments>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/snaps-execution-environments>@metamask/utils": {
"globals": {
"TextDecoder": true,
@@ -3078,10 +3056,10 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
"@metamask/snaps-rpc-methods>@metamask/permission-controller>@metamask/base-controller": true,
- "@metamask/snaps-rpc-methods>@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/snaps-rpc-methods>@metamask/permission-controller>nanoid": true,
"@metamask/snaps-rpc-methods>@metamask/utils": true,
"deep-freeze-strict": true,
@@ -3096,24 +3074,6 @@
"immer": true
}
},
- "@metamask/snaps-rpc-methods>@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-rpc-methods>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/snaps-rpc-methods>@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -3231,34 +3191,16 @@
"console.error": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/rpc-errors": true,
"@metamask/snaps-controllers>@metamask/json-rpc-engine": true,
"@metamask/snaps-utils>@metamask/base-controller": true,
- "@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": true,
"@metamask/snaps-utils>@metamask/permission-controller>nanoid": true,
"@metamask/snaps-utils>@metamask/utils": true,
"deep-freeze-strict": true,
"immer": true
}
},
- "@metamask/snaps-utils>@metamask/permission-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/snaps-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
"@metamask/snaps-utils>@metamask/permission-controller>nanoid": {
"globals": {
"crypto.getRandomValues": true
@@ -3406,6 +3348,7 @@
"@ethersproject/abi": true,
"@ethersproject/contracts": true,
"@ethersproject/providers": true,
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller": true,
"@metamask/metamask-eth-abis": true,
@@ -3413,9 +3356,8 @@
"@metamask/network-controller": true,
"@metamask/rpc-errors": true,
"@metamask/transaction-controller>@metamask/base-controller": true,
- "@metamask/transaction-controller>@metamask/controller-utils": true,
"@metamask/transaction-controller>@metamask/nonce-tracker": true,
- "@metamask/utils": true,
+ "@metamask/transaction-controller>@metamask/utils": true,
"bn.js": true,
"browserify>buffer": true,
"eth-method-registry": true,
@@ -3433,25 +3375,23 @@
"immer": true
}
},
- "@metamask/transaction-controller>@metamask/controller-utils": {
+ "@metamask/transaction-controller>@metamask/nonce-tracker": {
+ "packages": {
+ "@ethersproject/providers": true,
+ "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true,
+ "browserify>assert": true
+ }
+ },
+ "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": {
"globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
+ "clearTimeout": true,
"setTimeout": true
},
"packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/transaction-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
+ "@swc/helpers>tslib": true
}
},
- "@metamask/transaction-controller>@metamask/controller-utils>@metamask/utils": {
+ "@metamask/transaction-controller>@metamask/utils": {
"globals": {
"TextDecoder": true,
"TextEncoder": true
@@ -3466,34 +3406,18 @@
"semver": true
}
},
- "@metamask/transaction-controller>@metamask/nonce-tracker": {
- "packages": {
- "@ethersproject/providers": true,
- "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": true,
- "browserify>assert": true
- }
- },
- "@metamask/transaction-controller>@metamask/nonce-tracker>async-mutex": {
- "globals": {
- "clearTimeout": true,
- "setTimeout": true
- },
- "packages": {
- "@swc/helpers>tslib": true
- }
- },
"@metamask/user-operation-controller": {
"globals": {
"fetch": true
},
"packages": {
+ "@metamask/controller-utils": true,
"@metamask/eth-query": true,
"@metamask/gas-fee-controller": true,
"@metamask/gas-fee-controller>@metamask/polling-controller": true,
"@metamask/rpc-errors": true,
"@metamask/transaction-controller": true,
"@metamask/user-operation-controller>@metamask/base-controller": true,
- "@metamask/user-operation-controller>@metamask/controller-utils": true,
"@metamask/utils": true,
"bn.js": true,
"lodash": true,
@@ -3510,39 +3434,6 @@
"immer": true
}
},
- "@metamask/user-operation-controller>@metamask/controller-utils": {
- "globals": {
- "URL": true,
- "console.error": true,
- "fetch": true,
- "setTimeout": true
- },
- "packages": {
- "@ethereumjs/tx>@ethereumjs/util": true,
- "@metamask/controller-utils>@spruceid/siwe-parser": true,
- "@metamask/ethjs>@metamask/ethjs-unit": true,
- "@metamask/user-operation-controller>@metamask/controller-utils>@metamask/utils": true,
- "bn.js": true,
- "browserify>buffer": true,
- "eslint>fast-deep-equal": true,
- "eth-ens-namehash": true
- }
- },
- "@metamask/user-operation-controller>@metamask/controller-utils>@metamask/utils": {
- "globals": {
- "TextDecoder": true,
- "TextEncoder": true
- },
- "packages": {
- "@metamask/abi-utils>@metamask/superstruct": true,
- "@metamask/utils>@scure/base": true,
- "@metamask/utils>pony-cause": true,
- "@noble/hashes": true,
- "browserify>buffer": true,
- "nock>debug": true,
- "semver": true
- }
- },
"@metamask/utils": {
"globals": {
"TextDecoder": true,
@@ -3918,9 +3809,41 @@
"@trezor/connect-web>@trezor/connect>@trezor/protobuf": {
"packages": {
"@swc/helpers>tslib": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": true,
"@trezor/connect-web>@trezor/connect>@trezor/schema-utils": true,
- "browserify>buffer": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs": true
+ "browserify>buffer": true
+ }
+ },
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs": {
+ "globals": {
+ "process": true,
+ "setTimeout": true
+ },
+ "packages": {
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/base64": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/eventemitter": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/float": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/path": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/pool": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/utf8": true
+ }
+ },
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/codegen": {
+ "globals": {
+ "console.log": true
+ }
+ },
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/fetch": {
+ "globals": {
+ "XMLHttpRequest": true
+ },
+ "packages": {
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/aspromise": true,
+ "@trezor/connect-web>@trezor/connect>@trezor/protobuf>protobufjs>@protobufjs/inquire": true
}
},
"@trezor/connect-web>@trezor/connect>@trezor/schema-utils": {
@@ -4468,16 +4391,6 @@
"koa>is-generator-function>has-tostringtag": true
}
},
- "eslint>optionator>fast-levenshtein": {
- "globals": {
- "Intl": true,
- "Levenshtein": "write",
- "console.log": true,
- "define": true,
- "importScripts": true,
- "postMessage": true
- }
- },
"eth-ens-namehash": {
"globals": {
"name": "write"
@@ -4868,153 +4781,6 @@
"setTimeout": true
}
},
- "firebase": {
- "packages": {
- "firebase>@firebase/app": true,
- "firebase>@firebase/messaging": true
- }
- },
- "firebase>@firebase/app": {
- "globals": {
- "FinalizationRegistry": true,
- "console.warn": true
- },
- "packages": {
- "firebase>@firebase/app>@firebase/component": true,
- "firebase>@firebase/app>@firebase/logger": true,
- "firebase>@firebase/app>idb": true,
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/app>@firebase/component": {
- "packages": {
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/app>@firebase/logger": {
- "globals": {
- "console": true
- },
- "packages": {
- "@swc/helpers>tslib": true
- }
- },
- "firebase>@firebase/app>idb": {
- "globals": {
- "DOMException": true,
- "IDBCursor": true,
- "IDBDatabase": true,
- "IDBIndex": true,
- "IDBObjectStore": true,
- "IDBRequest": true,
- "IDBTransaction": true,
- "indexedDB.deleteDatabase": true,
- "indexedDB.open": true
- }
- },
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs": {
- "globals": {
- "process": true,
- "setTimeout": true
- },
- "packages": {
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/aspromise": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/base64": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/codegen": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/eventemitter": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/fetch": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/float": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/inquire": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/path": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/pool": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/utf8": true
- }
- },
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/codegen": {
- "globals": {
- "console.log": true
- }
- },
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/fetch": {
- "globals": {
- "XMLHttpRequest": true
- },
- "packages": {
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/aspromise": true,
- "firebase>@firebase/firestore>@grpc/proto-loader>protobufjs>@protobufjs/inquire": true
- }
- },
- "firebase>@firebase/installations": {
- "globals": {
- "BroadcastChannel": true,
- "Headers": true,
- "btoa": true,
- "console.error": true,
- "crypto": true,
- "fetch": true,
- "msCrypto": true,
- "navigator.onLine": true,
- "setTimeout": true
- },
- "packages": {
- "firebase>@firebase/app": true,
- "firebase>@firebase/app>@firebase/component": true,
- "firebase>@firebase/app>idb": true,
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/messaging": {
- "globals": {
- "Headers": true,
- "Notification.maxActions": true,
- "Notification.permission": true,
- "Notification.requestPermission": true,
- "PushSubscription.prototype.hasOwnProperty": true,
- "ServiceWorkerRegistration": true,
- "URL": true,
- "addEventListener": true,
- "atob": true,
- "btoa": true,
- "clients.matchAll": true,
- "clients.openWindow": true,
- "console.warn": true,
- "document": true,
- "fetch": true,
- "indexedDB": true,
- "location.href": true,
- "location.origin": true,
- "navigator": true,
- "origin.replace": true,
- "registration.showNotification": true,
- "setTimeout": true
- },
- "packages": {
- "@swc/helpers>tslib": true,
- "firebase>@firebase/app": true,
- "firebase>@firebase/app>@firebase/component": true,
- "firebase>@firebase/app>idb": true,
- "firebase>@firebase/installations": true,
- "firebase>@firebase/util": true
- }
- },
- "firebase>@firebase/util": {
- "globals": {
- "atob": true,
- "browser": true,
- "btoa": true,
- "chrome": true,
- "console": true,
- "document": true,
- "indexedDB": true,
- "navigator": true,
- "process": true,
- "self": true,
- "setTimeout": true
- },
- "packages": {
- "process": true
- }
- },
"fuse.js": {
"globals": {
"console": true,
From ea1784b5312c5385c86984b023c88a7994edbcf5 Mon Sep 17 00:00:00 2001
From: Dan J Miller
Date: Wed, 25 Sep 2024 17:55:16 -0230
Subject: [PATCH 04/41] Lint fix
---
app/scripts/lib/ppom/ppom-middleware.test.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/app/scripts/lib/ppom/ppom-middleware.test.ts b/app/scripts/lib/ppom/ppom-middleware.test.ts
index c16f6579cf9e..4adfeb3b8a6c 100644
--- a/app/scripts/lib/ppom/ppom-middleware.test.ts
+++ b/app/scripts/lib/ppom/ppom-middleware.test.ts
@@ -1,5 +1,4 @@
import { type Hex, JsonRpcResponseStruct } from '@metamask/utils';
-import * as ControllerUtils from '@metamask/controller-utils';
import { CHAIN_IDS } from '../../../../shared/constants/network';
import {
From 94ddd17938bc207a29dae3f5ac54e53f3e92f547 Mon Sep 17 00:00:00 2001
From: Dan J Miller
Date: Wed, 25 Sep 2024 20:39:31 -0230
Subject: [PATCH 05/41] Remove unused dependency
---
package.json | 1 -
yarn.lock | 3 +--
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/package.json b/package.json
index d568e1433305..307ad60c06ea 100644
--- a/package.json
+++ b/package.json
@@ -270,7 +270,6 @@
"dependencies": {
"@babel/runtime": "patch:@babel/runtime@npm%3A7.24.0#~/.yarn/patches/@babel-runtime-npm-7.24.0-7eb1dd11a2.patch",
"@blockaid/ppom_release": "^1.5.3",
- "@contentful/rich-text-html-renderer": "^16.3.5",
"@ensdomains/content-hash": "^2.5.7",
"@ethereumjs/tx": "^4.1.1",
"@ethersproject/abi": "^5.6.4",
diff --git a/yarn.lock b/yarn.lock
index 31ede7105993..f9e5b6420ed7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1759,7 +1759,7 @@ __metadata:
languageName: node
linkType: hard
-"@contentful/rich-text-html-renderer@npm:^16.3.5, @contentful/rich-text-html-renderer@npm:^16.5.2":
+"@contentful/rich-text-html-renderer@npm:^16.5.2":
version: 16.6.10
resolution: "@contentful/rich-text-html-renderer@npm:16.6.10"
dependencies:
@@ -25919,7 +25919,6 @@ __metadata:
"@babel/register": "npm:^7.22.15"
"@babel/runtime": "patch:@babel/runtime@npm%3A7.24.0#~/.yarn/patches/@babel-runtime-npm-7.24.0-7eb1dd11a2.patch"
"@blockaid/ppom_release": "npm:^1.5.3"
- "@contentful/rich-text-html-renderer": "npm:^16.3.5"
"@ensdomains/content-hash": "npm:^2.5.7"
"@ethereumjs/tx": "npm:^4.1.1"
"@ethersproject/abi": "npm:^5.6.4"
From e90736ac7c6b1c551cf5181bde9f18c24a59758d Mon Sep 17 00:00:00 2001
From: MetaMask Bot
Date: Wed, 25 Sep 2024 23:42:24 +0000
Subject: [PATCH 06/41] Update LavaMoat policies
---
lavamoat/browserify/beta/policy.json | 12 ++++++------
lavamoat/browserify/flask/policy.json | 12 ++++++------
lavamoat/browserify/main/policy.json | 12 ++++++------
lavamoat/browserify/mmi/policy.json | 12 ++++++------
4 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json
index cc0b0f53fd56..8558b0b01b56 100644
--- a/lavamoat/browserify/beta/policy.json
+++ b/lavamoat/browserify/beta/policy.json
@@ -5,11 +5,6 @@
"regeneratorRuntime": "write"
}
},
- "@contentful/rich-text-html-renderer": {
- "globals": {
- "SuppressedError": true
- }
- },
"@ensdomains/content-hash": {
"globals": {
"console.warn": true
@@ -1956,8 +1951,8 @@
"removeEventListener": true
},
"packages": {
- "@contentful/rich-text-html-renderer": true,
"@metamask/controller-utils": true,
+ "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": true,
"@metamask/notification-services-controller>@metamask/base-controller": true,
"@metamask/notification-services-controller>firebase": true,
"@metamask/profile-sync-controller": true,
@@ -1966,6 +1961,11 @@
"uuid": true
}
},
+ "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": {
+ "globals": {
+ "SuppressedError": true
+ }
+ },
"@metamask/notification-services-controller>@metamask/base-controller": {
"globals": {
"setTimeout": true
diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json
index cc0b0f53fd56..8558b0b01b56 100644
--- a/lavamoat/browserify/flask/policy.json
+++ b/lavamoat/browserify/flask/policy.json
@@ -5,11 +5,6 @@
"regeneratorRuntime": "write"
}
},
- "@contentful/rich-text-html-renderer": {
- "globals": {
- "SuppressedError": true
- }
- },
"@ensdomains/content-hash": {
"globals": {
"console.warn": true
@@ -1956,8 +1951,8 @@
"removeEventListener": true
},
"packages": {
- "@contentful/rich-text-html-renderer": true,
"@metamask/controller-utils": true,
+ "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": true,
"@metamask/notification-services-controller>@metamask/base-controller": true,
"@metamask/notification-services-controller>firebase": true,
"@metamask/profile-sync-controller": true,
@@ -1966,6 +1961,11 @@
"uuid": true
}
},
+ "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": {
+ "globals": {
+ "SuppressedError": true
+ }
+ },
"@metamask/notification-services-controller>@metamask/base-controller": {
"globals": {
"setTimeout": true
diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json
index cc0b0f53fd56..8558b0b01b56 100644
--- a/lavamoat/browserify/main/policy.json
+++ b/lavamoat/browserify/main/policy.json
@@ -5,11 +5,6 @@
"regeneratorRuntime": "write"
}
},
- "@contentful/rich-text-html-renderer": {
- "globals": {
- "SuppressedError": true
- }
- },
"@ensdomains/content-hash": {
"globals": {
"console.warn": true
@@ -1956,8 +1951,8 @@
"removeEventListener": true
},
"packages": {
- "@contentful/rich-text-html-renderer": true,
"@metamask/controller-utils": true,
+ "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": true,
"@metamask/notification-services-controller>@metamask/base-controller": true,
"@metamask/notification-services-controller>firebase": true,
"@metamask/profile-sync-controller": true,
@@ -1966,6 +1961,11 @@
"uuid": true
}
},
+ "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": {
+ "globals": {
+ "SuppressedError": true
+ }
+ },
"@metamask/notification-services-controller>@metamask/base-controller": {
"globals": {
"setTimeout": true
diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json
index e74fd5eb14c1..2021f5491abf 100644
--- a/lavamoat/browserify/mmi/policy.json
+++ b/lavamoat/browserify/mmi/policy.json
@@ -5,11 +5,6 @@
"regeneratorRuntime": "write"
}
},
- "@contentful/rich-text-html-renderer": {
- "globals": {
- "SuppressedError": true
- }
- },
"@ensdomains/content-hash": {
"globals": {
"console.warn": true
@@ -2048,8 +2043,8 @@
"removeEventListener": true
},
"packages": {
- "@contentful/rich-text-html-renderer": true,
"@metamask/controller-utils": true,
+ "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": true,
"@metamask/notification-services-controller>@metamask/base-controller": true,
"@metamask/notification-services-controller>firebase": true,
"@metamask/profile-sync-controller": true,
@@ -2058,6 +2053,11 @@
"uuid": true
}
},
+ "@metamask/notification-services-controller>@contentful/rich-text-html-renderer": {
+ "globals": {
+ "SuppressedError": true
+ }
+ },
"@metamask/notification-services-controller>@metamask/base-controller": {
"globals": {
"setTimeout": true
From aee1f551a55a3346efbd6669377ca4e744ca6360 Mon Sep 17 00:00:00 2001
From: Dan J Miller
Date: Thu, 26 Sep 2024 14:07:46 -0230
Subject: [PATCH 07/41] Fix storybook tests
---
.storybook/main.js | 3 +++
ui/__mocks__/ethereumjs-util.js | 6 ++++++
2 files changed, 9 insertions(+)
create mode 100644 ui/__mocks__/ethereumjs-util.js
diff --git a/.storybook/main.js b/.storybook/main.js
index 554f6d955ee0..7f38a53a733f 100644
--- a/.storybook/main.js
+++ b/.storybook/main.js
@@ -48,6 +48,9 @@ module.exports = {
config.resolve.alias['../../../../../../store/actions'] = require.resolve(
'../ui/__mocks__/actions.js',
);
+ config.resolve.alias['@ethereumjs/util'] = require.resolve(
+ '../ui/__mocks__/ethereumjs-util.js',
+ );
config.resolve.fallback = {
child_process: false,
constants: false,
diff --git a/ui/__mocks__/ethereumjs-util.js b/ui/__mocks__/ethereumjs-util.js
new file mode 100644
index 000000000000..d7af4a81162c
--- /dev/null
+++ b/ui/__mocks__/ethereumjs-util.js
@@ -0,0 +1,6 @@
+// eslint-disable-next-line import/no-extraneous-dependencies, node/no-extraneous-require
+const util = require('ethereumjs-util');
+
+module.exports = {
+ ...util,
+};
From acc47b30a2dc5d88aa4f57c8b0fffcbc053cbd54 Mon Sep 17 00:00:00 2001
From: Dan J Miller
Date: Thu, 26 Sep 2024 16:42:02 -0230
Subject: [PATCH 08/41] Get changelog lint passing
---
CHANGELOG.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7b4057f46bd1..e774b557d549 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [12.4.0]
-### Uncategorized
+### Fixed
- fix: flaky test `Test Snap Interactive UI test interactive ui elements` ([#26792](https://github.com/MetaMask/metamask-extension/pull/26792))
- feat: Update Polygon from `MATIC` to `POL` ([#26671](https://github.com/MetaMask/metamask-extension/pull/26671))
- feat: implement client side malicious network request detection ([#25839](https://github.com/MetaMask/metamask-extension/pull/25839))
From c414b28d3ab5b7a5a12805732e1c005dc1c1ab54 Mon Sep 17 00:00:00 2001
From: Kate Johnson <91970214+k-g-j@users.noreply.github.com>
Date: Wed, 2 Oct 2024 13:52:00 -0400
Subject: [PATCH 09/41] Cherry-pick ab37660 (PR ##27543) to V12.4.0 (#27577)
This PR cherry-picks the commit
[ab37660](https://github.com/MetaMask/metamask-extension/commit/ab376602c74d5e77c4edaf4a1540db4712625062)
(https://github.com/MetaMask/metamask-extension/pull/27543) into the
release v12.4.0
---
app/scripts/controllers/preferences.js | 2 +
.../lib/snap-keyring/account-watcher-snap.ts | 2 +
app/scripts/metamask-controller.js | 2 +
app/scripts/snaps/preinstalled-snaps.ts | 4 +-
shared/constants/metametrics.ts | 2 +
.../create-watch-account.spec.ts | 0
.../account-list-menu/account-list-menu.tsx | 47 ++++++++++---------
.../experimental-tab.component.tsx | 8 +++-
8 files changed, 42 insertions(+), 25 deletions(-)
rename test/e2e/{accounts => flask}/create-watch-account.spec.ts (100%)
diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js
index 677761cd2ef5..1db839386ed1 100644
--- a/app/scripts/controllers/preferences.js
+++ b/app/scripts/controllers/preferences.js
@@ -291,6 +291,7 @@ export default class PreferencesController {
}
///: END:ONLY_INCLUDE_IF
+ ///: BEGIN:ONLY_INCLUDE_IF(build-flask)
/**
* Setter for the `watchEthereumAccountEnabled` property.
*
@@ -302,6 +303,7 @@ export default class PreferencesController {
watchEthereumAccountEnabled,
});
}
+ ///: END:ONLY_INCLUDE_IF
/**
* Setter for the `bitcoinSupportEnabled` property.
diff --git a/app/scripts/lib/snap-keyring/account-watcher-snap.ts b/app/scripts/lib/snap-keyring/account-watcher-snap.ts
index 3775dcd28405..48ace4e595af 100644
--- a/app/scripts/lib/snap-keyring/account-watcher-snap.ts
+++ b/app/scripts/lib/snap-keyring/account-watcher-snap.ts
@@ -1,3 +1,4 @@
+// BEGIN:ONLY_INCLUDE_IF(build-flask)
import { SnapId } from '@metamask/snaps-sdk';
import AccountWatcherSnap from '@metamask/account-watcher/dist/preinstalled-snap.json';
@@ -6,3 +7,4 @@ export const ACCOUNT_WATCHER_SNAP_ID: SnapId =
export const ACCOUNT_WATCHER_NAME: string =
AccountWatcherSnap.manifest.proposedName;
+// END:ONLY_INCLUDE_IF
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 1e8f6303dbc6..78c9329b012e 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -3155,10 +3155,12 @@ export default class MetamaskController extends EventEmitter {
preferencesController,
),
///: END:ONLY_INCLUDE_IF
+ ///: BEGIN:ONLY_INCLUDE_IF(build-flask)
setWatchEthereumAccountEnabled:
preferencesController.setWatchEthereumAccountEnabled.bind(
preferencesController,
),
+ ///: END:ONLY_INCLUDE_IF
setBitcoinSupportEnabled:
preferencesController.setBitcoinSupportEnabled.bind(
preferencesController,
diff --git a/app/scripts/snaps/preinstalled-snaps.ts b/app/scripts/snaps/preinstalled-snaps.ts
index b30945e76477..f8bdeaf49a9c 100644
--- a/app/scripts/snaps/preinstalled-snaps.ts
+++ b/app/scripts/snaps/preinstalled-snaps.ts
@@ -1,15 +1,15 @@
import type { PreinstalledSnap } from '@metamask/snaps-controllers';
import MessageSigningSnap from '@metamask/message-signing-snap/dist/preinstalled-snap.json';
-import AccountWatcherSnap from '@metamask/account-watcher/dist/preinstalled-snap.json';
///: BEGIN:ONLY_INCLUDE_IF(build-flask)
+import AccountWatcherSnap from '@metamask/account-watcher/dist/preinstalled-snap.json';
import BitcoinWalletSnap from '@metamask/bitcoin-wallet-snap/dist/preinstalled-snap.json';
///: END:ONLY_INCLUDE_IF
// The casts here are less than ideal but we expect the SnapController to validate the inputs.
const PREINSTALLED_SNAPS = Object.freeze([
MessageSigningSnap as PreinstalledSnap,
- AccountWatcherSnap as PreinstalledSnap,
///: BEGIN:ONLY_INCLUDE_IF(build-flask)
+ AccountWatcherSnap as PreinstalledSnap,
BitcoinWalletSnap as unknown as PreinstalledSnap,
///: END:ONLY_INCLUDE_IF
]);
diff --git a/shared/constants/metametrics.ts b/shared/constants/metametrics.ts
index bea343ea7c41..b6799a1ad936 100644
--- a/shared/constants/metametrics.ts
+++ b/shared/constants/metametrics.ts
@@ -627,7 +627,9 @@ export enum MetaMetricsEventName {
WalletSetupCanceled = 'Wallet Setup Canceled',
WalletSetupFailed = 'Wallet Setup Failed',
WalletCreated = 'Wallet Created',
+ // BEGIN:ONLY_INCLUDE_IF(build-flask)
WatchEthereumAccountsToggled = 'Watch Ethereum Accounts Toggled',
+ // END:ONLY_INCLUDE_IF
///: BEGIN:ONLY_INCLUDE_IF(build-mmi)
DeeplinkClicked = 'Deeplink Clicked',
ConnectCustodialAccountClicked = 'Connect Custodial Account Clicked',
diff --git a/test/e2e/accounts/create-watch-account.spec.ts b/test/e2e/flask/create-watch-account.spec.ts
similarity index 100%
rename from test/e2e/accounts/create-watch-account.spec.ts
rename to test/e2e/flask/create-watch-account.spec.ts
diff --git a/ui/components/multichain/account-list-menu/account-list-menu.tsx b/ui/components/multichain/account-list-menu/account-list-menu.tsx
index b0440d0d09bb..ce87e6e0e34e 100644
--- a/ui/components/multichain/account-list-menu/account-list-menu.tsx
+++ b/ui/components/multichain/account-list-menu/account-list-menu.tsx
@@ -57,6 +57,7 @@ import {
getIsAddSnapAccountEnabled,
///: END:ONLY_INCLUDE_IF
///: BEGIN:ONLY_INCLUDE_IF(build-flask)
+ getIsWatchEthereumAccountEnabled,
getIsBitcoinSupportEnabled,
getIsBitcoinTestnetSupportEnabled,
///: END:ONLY_INCLUDE_IF
@@ -64,7 +65,6 @@ import {
getOriginOfCurrentTab,
getSelectedInternalAccount,
getUpdatedAndSortedAccounts,
- getIsWatchEthereumAccountEnabled,
} from '../../../selectors';
import { setSelectedAccount } from '../../../store/actions';
import {
@@ -82,6 +82,10 @@ import { getEnvironmentType } from '../../../../app/scripts/lib/util';
import { ENVIRONMENT_TYPE_POPUP } from '../../../../shared/constants/app';
import { getAccountLabel } from '../../../helpers/utils/accounts';
///: BEGIN:ONLY_INCLUDE_IF(build-flask)
+import {
+ ACCOUNT_WATCHER_NAME,
+ ACCOUNT_WATCHER_SNAP_ID,
+} from '../../../../app/scripts/lib/snap-keyring/account-watcher-snap';
import {
hasCreatedBtcMainnetAccount,
hasCreatedBtcTestnetAccount,
@@ -93,10 +97,6 @@ import {
AccountConnections,
MergedInternalAccount,
} from '../../../selectors/selectors.types';
-import {
- ACCOUNT_WATCHER_NAME,
- ACCOUNT_WATCHER_SNAP_ID,
-} from '../../../../app/scripts/lib/snap-keyring/account-watcher-snap';
import { HiddenAccountList } from './hidden-account-list';
const ACTION_MODES = {
@@ -106,9 +106,9 @@ const ACTION_MODES = {
MENU: 'menu',
// Displays the add account form controls
ADD: 'add',
+ ///: BEGIN:ONLY_INCLUDE_IF(build-flask)
// Displays the add account form controls (for watch-only account)
ADD_WATCH_ONLY: 'add-watch-only',
- ///: BEGIN:ONLY_INCLUDE_IF(build-flask)
// Displays the add account form controls (for bitcoin account)
ADD_BITCOIN: 'add-bitcoin',
// Same but for testnet
@@ -132,9 +132,9 @@ export const getActionTitle = (
switch (actionMode) {
case ACTION_MODES.ADD:
case ACTION_MODES.MENU:
- case ACTION_MODES.ADD_WATCH_ONLY:
return t('addAccount');
///: BEGIN:ONLY_INCLUDE_IF(build-flask)
+ case ACTION_MODES.ADD_WATCH_ONLY:
case ACTION_MODES.ADD_BITCOIN:
return t('addAccount');
case ACTION_MODES.ADD_BITCOIN_TESTNET:
@@ -225,6 +225,7 @@ export const AccountListMenu = ({
///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps)
const addSnapAccountEnabled = useSelector(getIsAddSnapAccountEnabled);
///: END:ONLY_INCLUDE_IF
+ ///: BEGIN:ONLY_INCLUDE_IF(build-flask)
const isAddWatchEthereumAccountEnabled = useSelector(
getIsWatchEthereumAccountEnabled,
);
@@ -242,7 +243,7 @@ export const AccountListMenu = ({
onClose();
history.push(`/snaps/view/${encodeURIComponent(ACCOUNT_WATCHER_SNAP_ID)}`);
}, [trackEvent, onClose, history]);
- ///: BEGIN:ONLY_INCLUDE_IF(build-flask)
+
const bitcoinSupportEnabled = useSelector(getIsBitcoinSupportEnabled);
const bitcoinTestnetSupportEnabled = useSelector(
getIsBitcoinTestnetSupportEnabled,
@@ -544,19 +545,23 @@ export const AccountListMenu = ({
///: END:ONLY_INCLUDE_IF
}
- {isAddWatchEthereumAccountEnabled && (
-
-
- {t('addEthereumWatchOnlyAccount')}
-
-
- )}
+ {
+ ///: BEGIN:ONLY_INCLUDE_IF(build-flask)
+ isAddWatchEthereumAccountEnabled && (
+
+
+ {t('addEthereumWatchOnlyAccount')}
+
+
+ )
+ ///: END:ONLY_INCLUDE_IF
+ }
) : null}
{actionMode === ACTION_MODES.LIST ? (
diff --git a/ui/pages/settings/experimental-tab/experimental-tab.component.tsx b/ui/pages/settings/experimental-tab/experimental-tab.component.tsx
index b888ac31efbe..c59cd6ead481 100644
--- a/ui/pages/settings/experimental-tab/experimental-tab.component.tsx
+++ b/ui/pages/settings/experimental-tab/experimental-tab.component.tsx
@@ -263,6 +263,7 @@ export default class ExperimentalTab extends PureComponent
});
}
+ ///: BEGIN:ONLY_INCLUDE_IF(build-flask)
renderWatchAccountToggle() {
const { t, trackEvent } = this.context;
const { watchAccountEnabled, setWatchAccountEnabled } = this.props;
@@ -297,7 +298,6 @@ export default class ExperimentalTab extends PureComponent
});
}
- ///: BEGIN:ONLY_INCLUDE_IF(build-flask)
// We're only setting the code fences here since
// we should remove it for the feature release
renderBitcoinSupport() {
@@ -385,7 +385,11 @@ export default class ExperimentalTab extends PureComponent
this.renderKeyringSnapsToggle()
///: END:ONLY_INCLUDE_IF
}
- {this.renderWatchAccountToggle()}
+ {
+ ///: BEGIN:ONLY_INCLUDE_IF(build-flask)
+ this.renderWatchAccountToggle()
+ ///: END:ONLY_INCLUDE_IF
+ }
{
///: BEGIN:ONLY_INCLUDE_IF(build-flask)
// We're only setting the code fences here since
From f072921beb0d88f0ad9e95693e531ff15f166420 Mon Sep 17 00:00:00 2001
From: Vinicius Stevam <45455812+vinistevam@users.noreply.github.com>
Date: Thu, 3 Oct 2024 16:37:41 +0100
Subject: [PATCH 10/41] fix: cherry pick incomplete transactions on startup
(#27537)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
This PR cherry-picks
https://github.com/MetaMask/metamask-extension/pull/26963
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27537?quickstart=1)
## **Related issues**
Fixes: https://github.com/MetaMask/metamask-extension/issues/27486
## **Manual testing steps**
1. Started a tx
2. Disable the wallet from the chrome://extensions site
3. Enable it again
4. Try to Reject the tx
5. Tx unapproved disappears
## **Screenshots/Recordings**
[clean-unapproved-tx.webm](https://github.com/user-attachments/assets/87661d40-7eb9-4ff4-8c97-596be14dc85d)
### **Before**
### **After**
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---------
Co-authored-by: Matthew Walsh
Co-authored-by: MetaMask Bot
---
.storybook/main.js | 1 +
app/scripts/metamask-controller.js | 8 +-
package.json | 2 +-
test/e2e/page-objects/flows/transaction.ts | 40 ++++++++++
.../pages/confirmations/legacy/navigation.ts | 57 +++++++++++++
test/e2e/page-objects/pages/test-dapp.ts | 37 +++++++++
.../contract-interaction-redesign.spec.ts | 17 ++--
.../tests/transaction/edit-gas-fee.spec.js | 5 +-
.../transaction/navigate-transactions.spec.js | 79 ++++++++-----------
test/e2e/tests/transaction/send-edit.spec.js | 1 +
yarn.lock | 18 ++---
11 files changed, 199 insertions(+), 66 deletions(-)
create mode 100644 test/e2e/page-objects/flows/transaction.ts
create mode 100644 test/e2e/page-objects/pages/confirmations/legacy/navigation.ts
create mode 100644 test/e2e/page-objects/pages/test-dapp.ts
diff --git a/.storybook/main.js b/.storybook/main.js
index 7f38a53a733f..d63d924aa2e2 100644
--- a/.storybook/main.js
+++ b/.storybook/main.js
@@ -48,6 +48,7 @@ module.exports = {
config.resolve.alias['../../../../../../store/actions'] = require.resolve(
'../ui/__mocks__/actions.js',
);
+ // Import within controller-utils crashes storybook.
config.resolve.alias['@ethereumjs/util'] = require.resolve(
'../ui/__mocks__/ethereumjs-util.js',
);
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 78c9329b012e..7925a9f4118f 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -4845,11 +4845,11 @@ export default class MetamaskController extends EventEmitter {
* by creating a new transaction.
*
* @param {number} originalTxId - the id of the txMeta that you want to
- * attempt to cancel
+ * attempt to cancel
* @param {import(
* './controllers/transactions'
* ).CustomGasSettings} [customGasSettings] - overrides to use for gas params
- * instead of allowing this method to generate them
+ * instead of allowing this method to generate them
* @param options
* @returns {object} MetaMask state
*/
@@ -4868,11 +4868,11 @@ export default class MetamaskController extends EventEmitter {
* by creating a new transaction.
*
* @param {number} originalTxId - the id of the txMeta that you want to
- * attempt to speed up
+ * attempt to speed up
* @param {import(
* './controllers/transactions'
* ).CustomGasSettings} [customGasSettings] - overrides to use for gas params
- * instead of allowing this method to generate them
+ * instead of allowing this method to generate them
* @param options
* @returns {object} MetaMask state
*/
diff --git a/package.json b/package.json
index 307ad60c06ea..d8fece95d0c0 100644
--- a/package.json
+++ b/package.json
@@ -356,7 +356,7 @@
"@metamask/snaps-rpc-methods": "^11.0.0",
"@metamask/snaps-sdk": "6.3.0",
"@metamask/snaps-utils": "^8.0.1",
- "@metamask/transaction-controller": "^35.2.0",
+ "@metamask/transaction-controller": "^37.0.0",
"@metamask/user-operation-controller": "^13.0.0",
"@metamask/utils": "^8.2.1",
"@ngraveio/bc-ur": "^1.1.12",
diff --git a/test/e2e/page-objects/flows/transaction.ts b/test/e2e/page-objects/flows/transaction.ts
new file mode 100644
index 000000000000..e2fdbd652034
--- /dev/null
+++ b/test/e2e/page-objects/flows/transaction.ts
@@ -0,0 +1,40 @@
+import { TransactionParams } from '@metamask/transaction-controller';
+import { DEFAULT_FIXTURE_ACCOUNT } from '../../constants';
+import { Driver } from '../../webdriver/driver';
+import HomePage from '../pages/homepage';
+import SendTokenPage from '../pages/send/send-token-page';
+import TestDapp from '../pages/test-dapp';
+
+export const createInternalTransaction = async (driver: Driver) => {
+ // Firefox has incorrect balance if send flow started too quickly.
+ await driver.delay(1000);
+
+ const homePage = new HomePage(driver);
+ await homePage.startSendFlow();
+
+ const sendToPage = new SendTokenPage(driver);
+ await sendToPage.check_pageIsLoaded();
+ await sendToPage.fillRecipient('0x2f318C334780961FB129D2a6c30D0763d9a5C970');
+ await sendToPage.fillAmount('1');
+ await sendToPage.goToNextScreen();
+};
+
+export const createDappTransaction = async (
+ driver: Driver,
+ override?: Partial,
+) => {
+ const testDapp = new TestDapp(driver);
+
+ await testDapp.request('eth_sendTransaction', [
+ {
+ data: '0x',
+ from: DEFAULT_FIXTURE_ACCOUNT,
+ maxFeePerGas: '0x0',
+ maxPriorityFeePerGas: '0x0',
+ to: '0x2f318C334780961FB129D2a6c30D0763d9a5C970',
+ value: '0x38d7ea4c68000',
+ type: '0x2',
+ ...override,
+ },
+ ]);
+};
diff --git a/test/e2e/page-objects/pages/confirmations/legacy/navigation.ts b/test/e2e/page-objects/pages/confirmations/legacy/navigation.ts
new file mode 100644
index 000000000000..ab04f85a4a2e
--- /dev/null
+++ b/test/e2e/page-objects/pages/confirmations/legacy/navigation.ts
@@ -0,0 +1,57 @@
+import { Driver } from '../../../../webdriver/driver';
+
+class ConfirmationNavigation {
+ private driver: Driver;
+
+ private nextPageButton: string;
+
+ private previousPageButton: string;
+
+ private firstPageButton: string;
+
+ private lastPageButton: string;
+
+ private navigationTitle: string;
+
+ constructor(driver: Driver) {
+ this.driver = driver;
+ this.nextPageButton = '[data-testid="next-page"]';
+ this.previousPageButton = '[data-testid="previous-page"]';
+ this.firstPageButton = '[data-testid="first-page"]';
+ this.lastPageButton = '[data-testid="last-page"]';
+ this.navigationTitle = '.confirm-page-container-navigation';
+ }
+
+ async clickNextPage(): Promise {
+ await this.driver.clickElement(this.nextPageButton);
+ }
+
+ async clickPreviousPage(): Promise {
+ await this.driver.clickElement(this.previousPageButton);
+ }
+
+ async clickFirstPage(): Promise {
+ await this.driver.clickElement(this.firstPageButton);
+ }
+
+ async clickLastPage(): Promise {
+ await this.driver.clickElement(this.lastPageButton);
+ }
+
+ async check_pageNumbers(
+ currentPage: number,
+ totalPages: number,
+ ): Promise {
+ try {
+ await this.driver.findElement({
+ css: this.navigationTitle,
+ text: `${currentPage} of ${totalPages}`,
+ });
+ } catch (e) {
+ console.log('Timeout while waiting for navigation page numbers', e);
+ throw e;
+ }
+ }
+}
+
+export default ConfirmationNavigation;
diff --git a/test/e2e/page-objects/pages/test-dapp.ts b/test/e2e/page-objects/pages/test-dapp.ts
new file mode 100644
index 000000000000..8c2fe513ca10
--- /dev/null
+++ b/test/e2e/page-objects/pages/test-dapp.ts
@@ -0,0 +1,37 @@
+import { Driver } from '../../webdriver/driver';
+
+const DAPP_HOST_ADDRESS = '127.0.0.1:8080';
+const DAPP_URL = `http://${DAPP_HOST_ADDRESS}`;
+
+class TestDapp {
+ private driver: Driver;
+
+ constructor(driver: Driver) {
+ this.driver = driver;
+ }
+
+ async open({
+ contractAddress,
+ url = DAPP_URL,
+ }: {
+ contractAddress?: string;
+ url?: string;
+ }) {
+ const dappUrl = contractAddress
+ ? `${url}/?contract=${contractAddress}`
+ : url;
+
+ return await this.driver.openNewPage(dappUrl);
+ }
+
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ async request(method: string, params: any[]) {
+ await this.open({
+ url: `${DAPP_URL}/request?method=${method}¶ms=${JSON.stringify(
+ params,
+ )}`,
+ });
+ }
+}
+
+export default TestDapp;
diff --git a/test/e2e/tests/confirmations/transactions/contract-interaction-redesign.spec.ts b/test/e2e/tests/confirmations/transactions/contract-interaction-redesign.spec.ts
index fc6ca9e2ff4e..2a815a025d18 100644
--- a/test/e2e/tests/confirmations/transactions/contract-interaction-redesign.spec.ts
+++ b/test/e2e/tests/confirmations/transactions/contract-interaction-redesign.spec.ts
@@ -1,9 +1,10 @@
/* eslint-disable @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */
import { Mockttp } from 'mockttp';
-import { createDappTransaction, unlockWallet } from '../../../helpers';
+import { openDapp, unlockWallet } from '../../../helpers';
+import { createDappTransaction } from '../../../page-objects/flows/transaction';
+import GanacheContractAddressRegistry from '../../../seeder/ganache-contract-address-registry';
import { Driver } from '../../../webdriver/driver';
import { MockedEndpoint } from '../../../mock-e2e';
-import { DEFAULT_FIXTURE_ACCOUNT } from '../../../constants';
import {
assertAdvancedGasDetails,
confirmDepositTransaction,
@@ -106,10 +107,16 @@ describe('Confirmation Redesign Contract Interaction Component', function () {
title: this.test?.fullTitle(),
testSpecificMock: mockOptimismOracle,
},
- async ({ driver }: TestSuiteArguments) => {
+ async ({ driver, contractRegistry }: TestSuiteArguments) => {
await unlockWallet(driver);
await createLayer2Transaction(driver);
+ const contractAddress = await (
+ contractRegistry as GanacheContractAddressRegistry
+ ).getContractAddress(smartContract);
+
+ await openDapp(driver, contractAddress);
+
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await toggleAdvancedDetails(driver);
@@ -281,11 +288,7 @@ describe('Confirmation Redesign Contract Interaction Component', function () {
async function createLayer2Transaction(driver: Driver) {
await createDappTransaction(driver, {
data: '0x1234',
- from: DEFAULT_FIXTURE_ACCOUNT,
to: '0x581c3C1A2A4EBDE2A0Df29B5cf4c116E42945947',
- gas: '0x31f10',
- maxFeePerGas: '0x3b014b3',
- maxPriorityFeePerGas: '0x3b014b3',
});
}
diff --git a/test/e2e/tests/transaction/edit-gas-fee.spec.js b/test/e2e/tests/transaction/edit-gas-fee.spec.js
index 07944e0e973c..85ae4da3a31f 100644
--- a/test/e2e/tests/transaction/edit-gas-fee.spec.js
+++ b/test/e2e/tests/transaction/edit-gas-fee.spec.js
@@ -1,11 +1,14 @@
const { strict: assert } = require('assert');
+const {
+ createInternalTransaction,
+} = require('../../page-objects/flows/transaction');
+
const {
withFixtures,
openDapp,
unlockWallet,
generateGanacheOptions,
WINDOW_TITLES,
- createInternalTransaction,
} = require('../../helpers');
const FixtureBuilder = require('../../fixture-builder');
diff --git a/test/e2e/tests/transaction/navigate-transactions.spec.js b/test/e2e/tests/transaction/navigate-transactions.spec.js
index 151e22ba55b9..45c27d11e76e 100644
--- a/test/e2e/tests/transaction/navigate-transactions.spec.js
+++ b/test/e2e/tests/transaction/navigate-transactions.spec.js
@@ -1,3 +1,11 @@
+const {
+ createDappTransaction,
+} = require('../../page-objects/flows/transaction');
+
+const {
+ default: ConfirmationNavigation,
+} = require('../../page-objects/pages/confirmations/legacy/navigation');
+
const {
withFixtures,
openDapp,
@@ -5,7 +13,6 @@ const {
unlockWallet,
generateGanacheOptions,
WINDOW_TITLES,
- createDappTransactionTypeTwo,
} = require('../../helpers');
const FixtureBuilder = require('../../fixture-builder');
@@ -27,26 +34,28 @@ describe('Navigate transactions', function () {
await unlockWallet(driver);
await createMultipleTransactions(driver, TRANSACTION_COUNT);
- await clickNextPage(driver);
- await expectPageNumber(driver, 2, 4);
+ const navigation = new ConfirmationNavigation(driver);
+
+ await navigation.clickNextPage();
+ await navigation.check_pageNumbers(2, 4);
- await clickNextPage(driver);
- await expectPageNumber(driver, 3, 4);
+ await navigation.clickNextPage();
+ await navigation.check_pageNumbers(3, 4);
- await clickNextPage(driver);
- await expectPageNumber(driver, 4, 4);
+ await navigation.clickNextPage();
+ await navigation.check_pageNumbers(4, 4);
- await clickFirstPage(driver);
- await expectPageNumber(driver, 1, 4);
+ await navigation.clickFirstPage();
+ await navigation.check_pageNumbers(1, 4);
- await clickLastPage(driver);
- await expectPageNumber(driver, 4, 4);
+ await navigation.clickLastPage();
+ await navigation.check_pageNumbers(4, 4);
- await clickPreviousPage(driver);
- await expectPageNumber(driver, 3, 4);
+ await navigation.clickPreviousPage();
+ await navigation.check_pageNumbers(3, 4);
- await clickPreviousPage(driver);
- await expectPageNumber(driver, 2, 4);
+ await navigation.clickPreviousPage();
+ await navigation.check_pageNumbers(2, 4);
},
);
});
@@ -66,8 +75,10 @@ describe('Navigate transactions', function () {
await unlockWallet(driver);
await createMultipleTransactions(driver, TRANSACTION_COUNT);
- await clickNextPage(driver);
- await expectPageNumber(driver, 2, 4);
+ const navigation = new ConfirmationNavigation(driver);
+
+ await navigation.clickNextPage();
+ await navigation.check_pageNumbers(2, 4);
await driver.switchToWindowWithTitle(
WINDOW_TITLES.ExtensionInFullScreenView,
@@ -77,7 +88,7 @@ describe('Navigate transactions', function () {
await driver.clickElement({ text: 'Send', tag: 'button' });
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await expectPageNumber(driver, 2, 5);
+ await navigation.check_pageNumbers(2, 5);
},
);
});
@@ -100,7 +111,8 @@ describe('Navigate transactions', function () {
// reject transaction
await driver.clickElement({ text: 'Reject', tag: 'button' });
- await expectPageNumber(driver, 1, 3);
+ const navigation = new ConfirmationNavigation(driver);
+ await navigation.check_pageNumbers(1, 3);
},
);
});
@@ -123,7 +135,8 @@ describe('Navigate transactions', function () {
// confirm transaction
await driver.clickElement({ text: 'Confirm', tag: 'button' });
- await expectPageNumber(driver, 1, 3);
+ const navigation = new ConfirmationNavigation(driver);
+ await navigation.check_pageNumbers(1, 3);
},
);
});
@@ -146,6 +159,7 @@ describe('Navigate transactions', function () {
// reject transactions
await driver.clickElement({ text: 'Reject 4', tag: 'a' });
await driver.clickElement({ text: 'Reject all', tag: 'button' });
+
await driver.switchToWindowWithTitle(
WINDOW_TITLES.ExtensionInFullScreenView,
);
@@ -157,7 +171,7 @@ describe('Navigate transactions', function () {
async function createMultipleTransactions(driver, count) {
for (let i = 0; i < count; i++) {
- await createDappTransactionTypeTwo(driver);
+ await createDappTransaction(driver);
}
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
@@ -168,26 +182,3 @@ async function createMultipleTransactions(driver, count) {
text: '0.001',
});
}
-
-async function clickFirstPage(driver) {
- await driver.clickElement('[data-testid="first-page"]');
-}
-
-async function clickLastPage(driver) {
- await driver.clickElement('[data-testid="last-page"]');
-}
-
-async function clickNextPage(driver) {
- await driver.clickElement('[data-testid="next-page"]');
-}
-
-async function clickPreviousPage(driver) {
- await driver.clickElement('[data-testid="previous-page"]');
-}
-
-async function expectPageNumber(driver, current, total) {
- await driver.findElement({
- css: '.confirm-page-container-navigation',
- text: `${current} of ${total}`,
- });
-}
diff --git a/test/e2e/tests/transaction/send-edit.spec.js b/test/e2e/tests/transaction/send-edit.spec.js
index 6e372ad2d64a..6fffe1d6b300 100644
--- a/test/e2e/tests/transaction/send-edit.spec.js
+++ b/test/e2e/tests/transaction/send-edit.spec.js
@@ -1,4 +1,5 @@
const { strict: assert } = require('assert');
+
const {
defaultGanacheOptions,
withFixtures,
diff --git a/yarn.lock b/yarn.lock
index f9e5b6420ed7..cc4f7fd6149d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6600,9 +6600,9 @@ __metadata:
languageName: node
linkType: hard
-"@metamask/transaction-controller@npm:^35.2.0":
- version: 35.2.0
- resolution: "@metamask/transaction-controller@npm:35.2.0"
+"@metamask/transaction-controller@npm:^37.0.0":
+ version: 37.0.0
+ resolution: "@metamask/transaction-controller@npm:37.0.0"
dependencies:
"@ethereumjs/common": "npm:^3.2.0"
"@ethereumjs/tx": "npm:^4.2.0"
@@ -6610,8 +6610,8 @@ __metadata:
"@ethersproject/abi": "npm:^5.7.0"
"@ethersproject/contracts": "npm:^5.7.0"
"@ethersproject/providers": "npm:^5.7.0"
- "@metamask/base-controller": "npm:^6.0.3"
- "@metamask/controller-utils": "npm:^11.0.2"
+ "@metamask/base-controller": "npm:^7.0.1"
+ "@metamask/controller-utils": "npm:^11.3.0"
"@metamask/eth-query": "npm:^4.0.0"
"@metamask/metamask-eth-abis": "npm:^3.1.1"
"@metamask/nonce-tracker": "npm:^6.0.0"
@@ -6627,9 +6627,9 @@ __metadata:
"@babel/runtime": ^7.23.9
"@metamask/accounts-controller": ^18.0.0
"@metamask/approval-controller": ^7.0.0
- "@metamask/gas-fee-controller": ^19.0.0
- "@metamask/network-controller": ^20.0.0
- checksum: 10/93af57d96860e4363b53ac1365742d77ca82689faf9ececca84309e15298a43a92e76a7ea3871b52b2a1785ff96e003db23e921ad6b4a4b65eddaa12d5edf570
+ "@metamask/gas-fee-controller": ^20.0.0
+ "@metamask/network-controller": ^21.0.0
+ checksum: 10/b4608260cb86ad1a867926b983a21050a2be899f17af909ad2403b5148eada348b0fbb3f7ecef9ebc7cf8d28c040ce4d6f5009709328cda00fab61e10fa94de6
languageName: node
linkType: hard
@@ -26023,7 +26023,7 @@ __metadata:
"@metamask/snaps-utils": "npm:^8.0.1"
"@metamask/test-bundler": "npm:^1.0.0"
"@metamask/test-dapp": "npm:^8.4.0"
- "@metamask/transaction-controller": "npm:^35.2.0"
+ "@metamask/transaction-controller": "npm:^37.0.0"
"@metamask/user-operation-controller": "npm:^13.0.0"
"@metamask/utils": "npm:^8.2.1"
"@ngraveio/bc-ur": "npm:^1.1.12"
From 9a18f1ce30ea478ed18793b37671c4f5e13d7125 Mon Sep 17 00:00:00 2001
From: Matthew Walsh
Date: Fri, 4 Oct 2024 17:11:46 +0100
Subject: [PATCH 11/41] fix (cherry-pick): disable transaction data decode if
deployment (#27586) (#27633)
---
.../hooks/useDecodedTransactionData.test.ts | 14 +++++++++
.../info/hooks/useDecodedTransactionData.ts | 5 ++--
.../confirm/info/hooks/useFourByte.test.ts | 29 +++++++++++++++++--
.../confirm/info/hooks/useFourByte.ts | 19 ++++++++++--
.../transaction-data.test.tsx | 1 +
5 files changed, 61 insertions(+), 7 deletions(-)
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.test.ts
index c070e1ae0635..d211e97d80bb 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.test.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.test.ts
@@ -65,6 +65,20 @@ describe('useDecodedTransactionData', () => {
},
);
+ it('returns undefined if no transaction to', async () => {
+ const result = await runHook({
+ currentConfirmation: {
+ chainId: CHAIN_ID_MOCK,
+ txParams: {
+ data: TRANSACTION_DATA_UNISWAP,
+ to: undefined,
+ } as TransactionParams,
+ },
+ });
+
+ expect(result).toStrictEqual({ pending: false, value: undefined });
+ });
+
it('returns the decoded data', async () => {
decodeTransactionDataMock.mockResolvedValue(TRANSACTION_DECODE_SOURCIFY);
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.ts b/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.ts
index 23c8c7af3f61..e77b704abc69 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useDecodedTransactionData.ts
@@ -20,9 +20,10 @@ export function useDecodedTransactionData(): AsyncResult<
const chainId = currentConfirmation?.chainId as Hex;
const contractAddress = currentConfirmation?.txParams?.to as Hex;
const transactionData = currentConfirmation?.txParams?.data as Hex;
+ const transactionTo = currentConfirmation?.txParams?.to as Hex;
return useAsyncResult(async () => {
- if (!hasTransactionData(transactionData)) {
+ if (!hasTransactionData(transactionData) || !transactionTo) {
return undefined;
}
@@ -31,5 +32,5 @@ export function useDecodedTransactionData(): AsyncResult<
chainId,
contractAddress,
});
- }, [transactionData, chainId, contractAddress]);
+ }, [transactionData, transactionTo, chainId, contractAddress]);
}
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts
index 5d4a023c82bb..9f1a848a96cd 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.test.ts
@@ -34,7 +34,7 @@ describe('useFourByte', () => {
expect(result.current.params).toEqual([]);
});
- it('returns empty object if resolution is turned off', () => {
+ it('returns null if resolution disabled', () => {
const currentConfirmation = genUnapprovedContractInteractionConfirmation({
address: CONTRACT_INTERACTION_SENDER_ADDRESS,
txData: depositHexData,
@@ -57,7 +57,7 @@ describe('useFourByte', () => {
expect(result.current).toBeNull();
});
- it("returns undefined if it's not known even if resolution is enabled", () => {
+ it('returns null if not known even if resolution enabled', () => {
const currentConfirmation = genUnapprovedContractInteractionConfirmation({
address: CONTRACT_INTERACTION_SENDER_ADDRESS,
txData: depositHexData,
@@ -77,4 +77,29 @@ describe('useFourByte', () => {
expect(result.current).toBeNull();
});
+
+ it('returns null if no transaction to', () => {
+ const currentConfirmation = genUnapprovedContractInteractionConfirmation({
+ address: CONTRACT_INTERACTION_SENDER_ADDRESS,
+ txData: depositHexData,
+ }) as TransactionMeta;
+
+ currentConfirmation.txParams.to = undefined;
+
+ const { result } = renderHookWithProvider(
+ () => useFourByte(currentConfirmation),
+ {
+ ...mockState,
+ metamask: {
+ ...mockState.metamask,
+ use4ByteResolution: true,
+ knownMethodData: {
+ [depositHexData]: { name: 'Deposit', params: [] },
+ },
+ },
+ },
+ );
+
+ expect(result.current).toBeNull();
+ });
});
diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.ts b/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.ts
index 7e2b81b443bd..7fece13fb417 100644
--- a/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.ts
+++ b/ui/pages/confirmations/components/confirm/info/hooks/useFourByte.ts
@@ -1,28 +1,41 @@
import { TransactionMeta } from '@metamask/transaction-controller';
import { useDispatch, useSelector } from 'react-redux';
import { useEffect } from 'react';
+import { Hex } from '@metamask/utils';
import {
getKnownMethodData,
use4ByteResolutionSelector,
} from '../../../../../../selectors';
import { getContractMethodData } from '../../../../../../store/actions';
+import { hasTransactionData } from '../../../../../../../shared/modules/transaction.utils';
export const useFourByte = (currentConfirmation: TransactionMeta) => {
const dispatch = useDispatch();
const isFourByteEnabled = useSelector(use4ByteResolutionSelector);
- const transactionData = currentConfirmation?.txParams?.data;
+ const transactionTo = currentConfirmation?.txParams?.to;
+ const transactionData = currentConfirmation?.txParams?.data as
+ | Hex
+ | undefined;
useEffect(() => {
- if (!isFourByteEnabled || !transactionData) {
+ if (
+ !isFourByteEnabled ||
+ !hasTransactionData(transactionData) ||
+ !transactionTo
+ ) {
return;
}
dispatch(getContractMethodData(transactionData));
- }, [isFourByteEnabled, transactionData, dispatch]);
+ }, [isFourByteEnabled, transactionData, transactionTo, dispatch]);
const methodData = useSelector((state) =>
getKnownMethodData(state, transactionData),
);
+ if (!transactionTo) {
+ return null;
+ }
+
return methodData;
};
diff --git a/ui/pages/confirmations/components/confirm/info/shared/transaction-data/transaction-data.test.tsx b/ui/pages/confirmations/components/confirm/info/shared/transaction-data/transaction-data.test.tsx
index 704d16eae7f8..667c2402410e 100644
--- a/ui/pages/confirmations/components/confirm/info/shared/transaction-data/transaction-data.test.tsx
+++ b/ui/pages/confirmations/components/confirm/info/shared/transaction-data/transaction-data.test.tsx
@@ -24,6 +24,7 @@ async function renderTransactionData(transactionData: string) {
confirm: {
currentConfirmation: {
txParams: {
+ to: '0x1234',
data: transactionData,
},
},
From fabf62dd4dbc26bb892f5e164732d1a2d273c271 Mon Sep 17 00:00:00 2001
From: Vinicius Stevam <45455812+vinistevam@users.noreply.github.com>
Date: Fri, 4 Oct 2024 17:22:03 +0100
Subject: [PATCH 12/41] fix (cherry-pick): add amount row for contract
deployment (#27594) (#27627)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
This PR cherry-picks
https://github.com/MetaMask/metamask-extension/pull/27594 for Version
12.4.0.
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27627?quickstart=1)
## **Related issues**
Fixes: https://github.com/MetaMask/metamask-extension/issues/27525
## **Manual testing steps**
1. Go to this page...
2.
3.
## **Screenshots/Recordings**
### **Before**
### **After**
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
.../confirmations/contract-interaction.ts | 288 +++++++++---------
.../approve-details.stories.tsx | 4 +-
.../confirm/info/approve/approve.stories.tsx | 4 +-
.../confirm/info/approve/approve.test.tsx | 4 +-
.../transaction-details.test.tsx | 24 ++
.../transaction-details.tsx | 31 ++
6 files changed, 204 insertions(+), 151 deletions(-)
diff --git a/test/data/confirmations/contract-interaction.ts b/test/data/confirmations/contract-interaction.ts
index 935a95f849db..a35ebcc74a3b 100644
--- a/test/data/confirmations/contract-interaction.ts
+++ b/test/data/confirmations/contract-interaction.ts
@@ -1,9 +1,14 @@
import {
+ SimulationData,
+ TransactionMeta,
TransactionStatus,
TransactionType,
} from '@metamask/transaction-controller';
import { Hex } from '@metamask/utils';
-import { Confirmation } from '../../../ui/pages/confirmations/types/confirm';
+import {
+ Confirmation,
+ SignatureRequestType,
+} from '../../../ui/pages/confirmations/types/confirm';
export const PAYMASTER_AND_DATA =
'0x9d6ac51b972544251fcc0f2902e633e3f9bd3f2900000000000000000000000000000000000000000000000000000000666bfd410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003498a76eb88b702e5e52b00fbc16a36baf89ebe3e0dd23170949cffc0a623011383cced660ff67930308c22e5aa746a2d586629ddbd87046a146225bf80e9d6f1b';
@@ -16,158 +21,151 @@ export const DEPOSIT_METHOD_DATA = '0xd0e30db0';
export const genUnapprovedContractInteractionConfirmation = ({
address = CONTRACT_INTERACTION_SENDER_ADDRESS,
txData = DEPOSIT_METHOD_DATA,
+ simulationData,
}: {
address?: Hex;
txData?: Hex;
-} = {}): Confirmation => ({
- actionId: String(400855682),
- chainId: '0xaa36a7',
- dappSuggestedGasFees: {
- gas: '0xab77',
- },
- defaultGasEstimates: {
- estimateType: 'medium',
- gas: '0xab77',
- maxFeePerGas: '0xaa350353',
- maxPriorityFeePerGas: '0x59682f00',
- },
- gasFeeEstimatesLoaded: true,
- history: [
- {
- actionId: String(400855682),
- chainId: '0xaa36a7',
- dappSuggestedGasFees: {
- gas: '0xab77',
- },
- defaultGasEstimates: {
- estimateType: 'medium',
- gas: '0xab77',
- maxFeePerGas: '0xaa350353',
- maxPriorityFeePerGas: '0x59682f00',
- },
- id: '1d7c08c0-fe54-11ee-9243-91b1e533746a',
- origin: 'https://metamask.github.io',
- securityAlertResponse: {
- reason: 'loading',
- result_type: 'validation_in_progress',
- },
- sendFlowHistory: [],
- status: TransactionStatus.unapproved,
- time: 1713534772044,
- txParams: {
- data: txData,
- from: address,
- gas: '0xab77',
- maxFeePerGas: '0xaa350353',
- maxPriorityFeePerGas: '0x59682f00',
- to: '0x88aa6343307ec9a652ccddda3646e62b2f1a5125',
- value: '0x3782dace9d900000',
- },
- type: TransactionType.contractInteraction,
- userEditedGasLimit: false,
- userFeeLevel: 'medium',
- verifiedOnBlockchain: false,
+ simulationData?: SimulationData;
+} = {}): Confirmation => {
+ const confirmation: Confirmation = {
+ actionId: String(400855682),
+ chainId: '0xaa36a7',
+ dappSuggestedGasFees: {
+ gas: '0xab77',
},
- [
+ defaultGasEstimates: {
+ estimateType: 'medium',
+ gas: '0xab77',
+ maxFeePerGas: '0xaa350353',
+ maxPriorityFeePerGas: '0x59682f00',
+ },
+ gasFeeEstimatesLoaded: true,
+ history: [
{
- note: 'TransactionController#updateSimulationData - Update simulation data',
- op: 'add',
- path: '/simulationData',
- timestamp: 1713534772417,
- value: {
- nativeBalanceChange: {
- difference: '0x3782dace9d900000',
- isDecrease: true,
- newBalance: '0xcc0ea4fb7ffa87d',
- previousBalance: '0x4443c51e558fa87d',
- },
- tokenBalanceChanges: [],
+ actionId: String(400855682),
+ chainId: '0xaa36a7',
+ dappSuggestedGasFees: {
+ gas: '0xab77',
},
+ defaultGasEstimates: {
+ estimateType: 'medium',
+ gas: '0xab77',
+ maxFeePerGas: '0xaa350353',
+ maxPriorityFeePerGas: '0x59682f00',
+ },
+ id: '1d7c08c0-fe54-11ee-9243-91b1e533746a',
+ origin: 'https://metamask.github.io',
+ securityAlertResponse: {
+ reason: 'loading',
+ result_type: 'validation_in_progress',
+ },
+ sendFlowHistory: [],
+ status: TransactionStatus.unapproved,
+ time: 1713534772044,
+ txParams: {
+ data: txData,
+ from: address,
+ gas: '0xab77',
+ maxFeePerGas: '0xaa350353',
+ maxPriorityFeePerGas: '0x59682f00',
+ to: '0x88aa6343307ec9a652ccddda3646e62b2f1a5125',
+ value: '0x3782dace9d900000',
+ },
+ type: TransactionType.contractInteraction,
+ userEditedGasLimit: false,
+ userFeeLevel: 'medium',
+ verifiedOnBlockchain: false,
},
- {
- op: 'add',
- path: '/gasFeeEstimatesLoaded',
- value: true,
- },
+ [
+ {
+ note: 'TransactionController#updateSimulationData - Update simulation data',
+ op: 'add',
+ path: '/simulationData',
+ timestamp: 1713534772417,
+ value: {
+ nativeBalanceChange: {
+ difference: '0x3782dace9d900000',
+ isDecrease: true,
+ newBalance: '0xcc0ea4fb7ffa87d',
+ previousBalance: '0x4443c51e558fa87d',
+ },
+ tokenBalanceChanges: [],
+ },
+ },
+ {
+ op: 'add',
+ path: '/gasFeeEstimatesLoaded',
+ value: true,
+ },
+ ],
+ [
+ {
+ note: 'TransactionController:updatesecurityAlertResponse - securityAlertResponse updated',
+ op: 'replace',
+ path: '/securityAlertResponse/result_type',
+ timestamp: 1713534773213,
+ value: 'Benign',
+ },
+ {
+ op: 'replace',
+ path: '/securityAlertResponse/reason',
+ value: '',
+ },
+ {
+ op: 'add',
+ path: '/securityAlertResponse/description',
+ value: '',
+ },
+ {
+ op: 'add',
+ path: '/securityAlertResponse/features',
+ value: [],
+ },
+ {
+ op: 'add',
+ path: '/securityAlertResponse/block',
+ value: 5732063,
+ },
+ ],
],
- [
- {
- note: 'TransactionController:updatesecurityAlertResponse - securityAlertResponse updated',
- op: 'replace',
- path: '/securityAlertResponse/result_type',
- timestamp: 1713534773213,
- value: 'Benign',
- },
- {
- op: 'replace',
- path: '/securityAlertResponse/reason',
- value: '',
- },
- {
- op: 'add',
- path: '/securityAlertResponse/description',
- value: '',
- },
- {
- op: 'add',
- path: '/securityAlertResponse/features',
- value: [],
- },
- {
- op: 'add',
- path: '/securityAlertResponse/block',
- value: 5732063,
+ id: '1d7c08c0-fe54-11ee-9243-91b1e533746a',
+ origin: 'https://metamask.github.io',
+ securityAlertResponse: {
+ features: [],
+ reason: '',
+ result_type: 'Benign',
+ },
+ sendFlowHistory: [],
+ simulationData: {
+ nativeBalanceChange: {
+ difference: '0x3782dace9d900000',
+ isDecrease: true,
+ newBalance: '0xcc0ea4fb7ffa87d',
+ previousBalance: '0x4443c51e558fa87d',
},
- ],
- ],
- id: '1d7c08c0-fe54-11ee-9243-91b1e533746a',
- origin: 'https://metamask.github.io',
- securityAlertResponse: {
- features: [],
- reason: '',
- result_type: 'Benign',
- },
- sendFlowHistory: [],
- simulationData: {
- nativeBalanceChange: {
- difference: '0x3782dace9d900000',
- isDecrease: true,
- newBalance: '0xcc0ea4fb7ffa87d',
- previousBalance: '0x4443c51e558fa87d',
+ tokenBalanceChanges: [],
+ },
+ status: TransactionStatus.unapproved,
+ time: 1713534772044,
+ txParams: {
+ data: txData,
+ from: address,
+ gas: '0xab77',
+ maxFeePerGas: '0xaa350353',
+ maxPriorityFeePerGas: '0x59682f00',
+ to: '0x88aa6343307ec9a652ccddda3646e62b2f1a5125',
+ value: '0x3782dace9d900000',
},
- tokenBalanceChanges: [],
- },
- status: TransactionStatus.unapproved,
- time: 1713534772044,
- txParams: {
- data: txData,
- from: address,
- gas: '0xab77',
- maxFeePerGas: '0xaa350353',
- maxPriorityFeePerGas: '0x59682f00',
- to: '0x88aa6343307ec9a652ccddda3646e62b2f1a5125',
- value: '0x3782dace9d900000',
- },
- type: TransactionType.contractInteraction,
- userEditedGasLimit: false,
- userFeeLevel: 'medium',
- verifiedOnBlockchain: false,
-});
+ type: TransactionType.contractInteraction,
+ userEditedGasLimit: false,
+ userFeeLevel: 'medium',
+ verifiedOnBlockchain: false,
+ } as SignatureRequestType;
-export const genUnapprovedApproveConfirmation = ({
- address = CONTRACT_INTERACTION_SENDER_ADDRESS,
-}: {
- address?: Hex;
-} = {}) => ({
- ...genUnapprovedContractInteractionConfirmation(),
- txParams: {
- from: address,
- data: '0x095ea7b30000000000000000000000002e0d7e8c45221fca00d74a3609a0f7097035d09b0000000000000000000000000000000000000000000000000000000000000001',
- gas: '0x16a92',
- to: '0x076146c765189d51be3160a2140cf80bfc73ad68',
- value: '0x0',
- maxFeePerGas: '0x5b06b0c0d',
- maxPriorityFeePerGas: '0x59682f00',
- },
- type: TransactionType.tokenMethodApprove,
-});
+ // Overwrite simulation data if provided
+ if (simulationData) {
+ (confirmation as TransactionMeta).simulationData = simulationData;
+ }
+
+ return confirmation;
+};
diff --git a/ui/pages/confirmations/components/confirm/info/approve/approve-details/approve-details.stories.tsx b/ui/pages/confirmations/components/confirm/info/approve/approve-details/approve-details.stories.tsx
index 965207360d3c..40523e396330 100644
--- a/ui/pages/confirmations/components/confirm/info/approve/approve-details/approve-details.stories.tsx
+++ b/ui/pages/confirmations/components/confirm/info/approve/approve-details/approve-details.stories.tsx
@@ -3,7 +3,7 @@ import React from 'react';
import { Provider } from 'react-redux';
import {
DEPOSIT_METHOD_DATA,
- genUnapprovedApproveConfirmation,
+ genUnapprovedContractInteractionConfirmation,
} from '../../../../../../../../test/data/confirmations/contract-interaction';
import mockState from '../../../../../../../../test/data/mock-state.json';
import configureStore from '../../../../../../../store/store';
@@ -22,7 +22,7 @@ const store = configureStore({
},
},
confirm: {
- currentConfirmation: genUnapprovedApproveConfirmation(),
+ currentConfirmation: genUnapprovedContractInteractionConfirmation(),
},
});
diff --git a/ui/pages/confirmations/components/confirm/info/approve/approve.stories.tsx b/ui/pages/confirmations/components/confirm/info/approve/approve.stories.tsx
index ba46eb6c8f47..74a622e7b2af 100644
--- a/ui/pages/confirmations/components/confirm/info/approve/approve.stories.tsx
+++ b/ui/pages/confirmations/components/confirm/info/approve/approve.stories.tsx
@@ -1,7 +1,7 @@
import { Meta } from '@storybook/react';
import React from 'react';
import { Provider } from 'react-redux';
-import { genUnapprovedApproveConfirmation } from '../../../../../../../test/data/confirmations/contract-interaction';
+import { genUnapprovedContractInteractionConfirmation } from '../../../../../../../test/data/confirmations/contract-interaction';
import mockState from '../../../../../../../test/data/mock-state.json';
import configureStore from '../../../../../../store/store';
import ApproveInfo from './approve';
@@ -12,7 +12,7 @@ const store = configureStore({
...mockState.metamask,
},
confirm: {
- currentConfirmation: genUnapprovedApproveConfirmation(),
+ currentConfirmation: genUnapprovedContractInteractionConfirmation(),
},
});
diff --git a/ui/pages/confirmations/components/confirm/info/approve/approve.test.tsx b/ui/pages/confirmations/components/confirm/info/approve/approve.test.tsx
index 2886e59690c5..2eda7bf50c79 100644
--- a/ui/pages/confirmations/components/confirm/info/approve/approve.test.tsx
+++ b/ui/pages/confirmations/components/confirm/info/approve/approve.test.tsx
@@ -2,7 +2,7 @@ import { waitFor } from '@testing-library/react';
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
-import { genUnapprovedApproveConfirmation } from '../../../../../../../test/data/confirmations/contract-interaction';
+import { genUnapprovedContractInteractionConfirmation } from '../../../../../../../test/data/confirmations/contract-interaction';
import mockState from '../../../../../../../test/data/mock-state.json';
import { renderWithProvider } from '../../../../../../../test/lib/render-helpers';
import ApproveInfo from './approve';
@@ -31,7 +31,7 @@ describe(' ', () => {
const state = {
...mockState,
confirm: {
- currentConfirmation: genUnapprovedApproveConfirmation(),
+ currentConfirmation: genUnapprovedContractInteractionConfirmation(),
},
};
const mockStore = configureMockStore(middleware)(state);
diff --git a/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.test.tsx b/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.test.tsx
index 4fd01437aad4..2dad785b1805 100644
--- a/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.test.tsx
+++ b/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.test.tsx
@@ -1,9 +1,11 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
+import { SimulationErrorCode } from '@metamask/transaction-controller';
import { genUnapprovedContractInteractionConfirmation } from '../../../../../../../../test/data/confirmations/contract-interaction';
import mockState from '../../../../../../../../test/data/mock-state.json';
import { renderWithProvider } from '../../../../../../../../test/lib/render-helpers';
+import { renderWithConfirmContextProvider } from '../../../../../../../../test/lib/confirmations/render-helpers';
import { TransactionDetails } from './transaction-details';
jest.mock(
@@ -36,4 +38,26 @@ describe(' ', () => {
const { container } = renderWithProvider( , mockStore);
expect(container).toMatchSnapshot();
});
+
+ it('renders component for transaction details with amount', () => {
+ const simulationDataMock = {
+ error: { code: SimulationErrorCode.Disabled },
+ tokenBalanceChanges: [],
+ };
+ const contractInteraction = genUnapprovedContractInteractionConfirmation({
+ simulationData: simulationDataMock,
+ });
+ const state = {
+ ...mockState,
+ confirm: {
+ currentConfirmation: contractInteraction,
+ },
+ };
+ const mockStore = configureMockStore(middleware)(state);
+ const { getByTestId } = renderWithConfirmContextProvider(
+ ,
+ mockStore,
+ );
+ expect(getByTestId('transaction-details-amount-row')).toBeInTheDocument();
+ });
});
diff --git a/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.tsx b/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.tsx
index def2549fbd63..aca636bf035d 100644
--- a/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.tsx
+++ b/ui/pages/confirmations/components/confirm/info/shared/transaction-details/transaction-details.tsx
@@ -16,6 +16,10 @@ import { selectPaymasterAddress } from '../../../../../../../selectors/account-a
import { currentConfirmationSelector } from '../../../../../selectors';
import { selectConfirmationAdvancedDetailsOpen } from '../../../../../selectors/preferences';
import { useFourByte } from '../../hooks/useFourByte';
+import { ConfirmInfoRowCurrency } from '../../../../../../../components/app/confirm/info/row/currency';
+import { PRIMARY } from '../../../../../../../helpers/constants/common';
+import { useUserPreferencedCurrency } from '../../../../../../../hooks/useUserPreferencedCurrency';
+import { HEX_ZERO } from '../constants';
export const OriginRow = () => {
const t = useI18nContext();
@@ -92,6 +96,32 @@ export const MethodDataRow = () => {
);
};
+const AmountRow = () => {
+ const t = useI18nContext();
+ const currentConfirmation = useSelector(
+ currentConfirmationSelector,
+ ) as TransactionMeta;
+ const { currency } = useUserPreferencedCurrency(PRIMARY);
+
+ const value = currentConfirmation?.txParams?.value;
+ const simulationData = currentConfirmation?.simulationData;
+
+ if (!value || value === HEX_ZERO || !simulationData?.error) {
+ return null;
+ }
+
+ return (
+
+
+
+
+
+ );
+};
+
const PaymasterRow = () => {
const t = useI18nContext();
@@ -136,6 +166,7 @@ export const TransactionDetails = () => {
{showAdvancedDetails && }
+
>
);
From c8f966c5e2da15c449daf8387eeeff3541a9ab8e Mon Sep 17 00:00:00 2001
From: Mark Stacey
Date: Tue, 8 Oct 2024 13:19:42 -0230
Subject: [PATCH 13/41] chore: Temporarily ignore advisory (#27676)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
The advisory https://github.com/advisories/GHSA-593m-55hh-j8gv has been
temporarily ignored, just for v12.4.x. This is resolved by a dependency
update in v12.5.0, but the update included too many functional changes,
so we deemed it too risky to backport in this release.
The impact is expected to be negligable due to our use of LavaMoat and
SES lockdown.
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27676?quickstart=1)
## **Related issues**
The audit advisory was resolved here on `develop`:
https://github.com/MetaMask/metamask-extension/pull/27620
And it was back ported to v12.5.0 here:
https://github.com/MetaMask/metamask-extension/pull/27673
## **Manual testing steps**
N/A
## **Screenshots/Recordings**
N/A
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
.yarnrc.yml | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/.yarnrc.yml b/.yarnrc.yml
index 252333917781..7176c6152327 100644
--- a/.yarnrc.yml
+++ b/.yarnrc.yml
@@ -43,6 +43,12 @@ npmAuditIgnoreAdvisories:
# not appear to be used.
- 1092461
+ # Issue: Sentry SDK Prototype Pollution gadget in JavaScript SDKs
+ # URL: https://github.com/advisories/GHSA-593m-55hh-j8gv
+ # Not easily fixed in this version, will be fixed in v12.5.0
+ # Minimally effects the extension due to usage of LavaMoat + SES lockdown.
+ - 1099839
+
# Temp fix for https://github.com/MetaMask/metamask-extension/pull/16920 for the sake of 11.7.1 hotfix
# This will be removed in this ticket https://github.com/MetaMask/metamask-extension/issues/22299
- 'ts-custom-error (deprecation)'
From 9446efa3d72f59f5305d65bf34fb741092bd0e78 Mon Sep 17 00:00:00 2001
From: Jyoti Puri
Date: Tue, 8 Oct 2024 21:38:10 +0530
Subject: [PATCH 14/41] fix: issue with default nonce value being wrong when
switching networks between transactions (#27634)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
Nonce in state should be reset correctly when switching between
different networks.
The issue is already fixed in develop by PR:
https://github.com/MetaMask/metamask-extension/pull/27297
## **Related issues**
Fixes: https://github.com/MetaMask/metamask-extension/issues/27657
## **Manual testing steps**
1. Connect to Arbitrum
2. Submit transaction with the high nonce
3. Observe it fails with Internal JSON RPC error
4. Switch to BNB Chain
5. Start a transaction
6. Transaction is created with correct nonce
## **Screenshots/Recordings**
NA
## **Pre-merge author checklist**
- [X] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [X] I've completed the PR template to the best of my ability
- [X] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [X] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
.../components/confirm/footer/footer.test.tsx | 26 ++++++++++++++++++-
.../components/confirm/footer/footer.tsx | 8 ++++++
.../confirm-transaction-base.component.js | 22 +++++++++++-----
.../confirm-transaction-base.container.js | 2 ++
4 files changed, 51 insertions(+), 7 deletions(-)
diff --git a/ui/pages/confirmations/components/confirm/footer/footer.test.tsx b/ui/pages/confirmations/components/confirm/footer/footer.test.tsx
index 5fb6b7e5ac76..4122f82028e4 100644
--- a/ui/pages/confirmations/components/confirm/footer/footer.test.tsx
+++ b/ui/pages/confirmations/components/confirm/footer/footer.test.tsx
@@ -88,11 +88,23 @@ describe('ConfirmFooter', () => {
// TODO: Replace `any` with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.mockImplementation(() => ({} as any));
+ const updateCustomNonceSpy = jest
+ .spyOn(Actions, 'updateCustomNonce')
+ // TODO: Replace `any` with type
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ .mockImplementation(() => ({} as any));
+ const setNextNonceSpy = jest
+ .spyOn(Actions, 'setNextNonce')
+ // TODO: Replace `any` with type
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ .mockImplementation(() => ({} as any));
fireEvent.click(cancelButton);
expect(rejectSpy).toHaveBeenCalled();
+ expect(updateCustomNonceSpy).toHaveBeenCalledWith('');
+ expect(setNextNonceSpy).toHaveBeenCalledWith('');
});
- it('invoke action resolvePendingApproval when submit button is clicked', () => {
+ it('invoke required actions when submit button is clicked', () => {
const { getAllByRole } = render();
const submitButton = getAllByRole('button')[1];
const resolveSpy = jest
@@ -100,8 +112,20 @@ describe('ConfirmFooter', () => {
// TODO: Replace `any` with type
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.mockImplementation(() => ({} as any));
+ const updateCustomNonceSpy = jest
+ .spyOn(Actions, 'updateCustomNonce')
+ // TODO: Replace `any` with type
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ .mockImplementation(() => ({} as any));
+ const setNextNonceSpy = jest
+ .spyOn(Actions, 'setNextNonce')
+ // TODO: Replace `any` with type
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ .mockImplementation(() => ({} as any));
fireEvent.click(submitButton);
expect(resolveSpy).toHaveBeenCalled();
+ expect(updateCustomNonceSpy).toHaveBeenCalledWith('');
+ expect(setNextNonceSpy).toHaveBeenCalledWith('');
});
it('displays a danger "Confirm" button there are danger alerts', async () => {
diff --git a/ui/pages/confirmations/components/confirm/footer/footer.tsx b/ui/pages/confirmations/components/confirm/footer/footer.tsx
index 6c70277b7ba5..e0d61f66f421 100644
--- a/ui/pages/confirmations/components/confirm/footer/footer.tsx
+++ b/ui/pages/confirmations/components/confirm/footer/footer.tsx
@@ -22,7 +22,11 @@ import useAlerts from '../../../../../hooks/useAlerts';
import {
rejectPendingApproval,
resolvePendingApproval,
+ setNextNonce,
+ ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask)
updateAndApproveTx,
+ ///: END:ONLY_INCLUDE_IF
+ updateCustomNonce,
} from '../../../../../store/actions';
import { confirmSelector } from '../../../selectors';
import { REDESIGN_DEV_TRANSACTION_TYPES } from '../../../utils';
@@ -156,6 +160,8 @@ const Footer = () => {
dispatch(
rejectPendingApproval(currentConfirmation.id, serializeError(error)),
);
+ dispatch(updateCustomNonce(''));
+ dispatch(setNextNonce(''));
},
[currentConfirmation],
);
@@ -186,6 +192,8 @@ const Footer = () => {
mmiOnSignCallback();
///: END:ONLY_INCLUDE_IF
}
+ dispatch(updateCustomNonce(''));
+ dispatch(setNextNonce(''));
}, [currentConfirmation, customNonceValue]);
const onFooterCancel = useCallback(() => {
diff --git a/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.component.js b/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.component.js
index 5330a3685d47..f344a9392455 100644
--- a/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.component.js
+++ b/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.component.js
@@ -134,6 +134,7 @@ export default class ConfirmTransactionBase extends Component {
image: PropTypes.string,
type: PropTypes.string,
getNextNonce: PropTypes.func,
+ setNextNonce: PropTypes.func,
nextNonce: PropTypes.number,
tryReverseResolveAddress: PropTypes.func.isRequired,
hideSenderToRecipient: PropTypes.bool,
@@ -696,12 +697,14 @@ export default class ConfirmTransactionBase extends Component {
history,
mostRecentOverviewPage,
updateCustomNonce,
+ setNextNonce,
} = this.props;
this._removeBeforeUnload();
- updateCustomNonce('');
await cancelTransaction(txData);
history.push(mostRecentOverviewPage);
+ updateCustomNonce('');
+ setNextNonce('');
}
handleSubmit() {
@@ -723,6 +726,7 @@ export default class ConfirmTransactionBase extends Component {
history,
mostRecentOverviewPage,
updateCustomNonce,
+ setNextNonce,
methodData,
maxFeePerGas,
customTokenAmount,
@@ -786,6 +790,9 @@ export default class ConfirmTransactionBase extends Component {
sendTransaction(txData, false, loadingIndicatorMessage)
.then(() => {
+ updateCustomNonce('');
+ setNextNonce('');
+
if (!this._isMounted) {
return;
}
@@ -796,11 +803,12 @@ export default class ConfirmTransactionBase extends Component {
},
() => {
history.push(mostRecentOverviewPage);
- updateCustomNonce('');
},
);
})
.catch((error) => {
+ updateCustomNonce('');
+ setNextNonce('');
if (!this._isMounted) {
return;
}
@@ -808,7 +816,6 @@ export default class ConfirmTransactionBase extends Component {
submitting: false,
submitError: error.message,
});
- updateCustomNonce('');
});
},
);
@@ -822,6 +829,7 @@ export default class ConfirmTransactionBase extends Component {
history,
mostRecentOverviewPage,
updateCustomNonce,
+ setNextNonce,
unapprovedTxCount,
accountType,
isNotification,
@@ -894,6 +902,8 @@ export default class ConfirmTransactionBase extends Component {
sendTransaction(txData)
.then(() => {
+ updateCustomNonce('');
+ setNextNonce('');
if (txData.custodyStatus) {
showCustodianDeepLink({
fromAddress,
@@ -912,7 +922,6 @@ export default class ConfirmTransactionBase extends Component {
}
this.setState({ submitting: false }, () => {
history.push(mostRecentOverviewPage);
- updateCustomNonce('');
});
},
});
@@ -926,12 +935,14 @@ export default class ConfirmTransactionBase extends Component {
},
() => {
history.push(mostRecentOverviewPage);
- updateCustomNonce('');
},
);
}
})
.catch((error) => {
+ updateCustomNonce('');
+ setNextNonce('');
+
if (!this._isMounted) {
return;
}
@@ -943,7 +954,6 @@ export default class ConfirmTransactionBase extends Component {
submitError: error.message,
});
setWaitForConfirmDeepLinkDialog(true);
- updateCustomNonce('');
});
},
);
diff --git a/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.container.js b/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.container.js
index cc3de6095f2d..0efa6fe9c58b 100644
--- a/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.container.js
+++ b/ui/pages/confirmations/confirm-transaction-base/confirm-transaction-base.container.js
@@ -29,6 +29,7 @@ import {
updateEditableParams,
setSwapsFeatureFlags,
fetchSmartTransactionsLiveness,
+ setNextNonce,
} from '../../../store/actions';
import { isBalanceSufficient } from '../send/send.utils';
import { shortenAddress, valuesFor } from '../../../helpers/utils/util';
@@ -429,6 +430,7 @@ export const mapDispatchToProps = (dispatch) => {
dispatch(fetchSmartTransactionsLiveness());
},
getNextNonce: () => dispatch(getNextNonce()),
+ setNextNonce: (val) => dispatch(setNextNonce(val)),
setDefaultHomeActiveTabName: (tabName) =>
dispatch(setDefaultHomeActiveTabName(tabName)),
updateTransactionGasFees: (gasFees) => {
From dfbead63996feb56a06dfdf35900cace6a316691 Mon Sep 17 00:00:00 2001
From: chloeYue <105063779+chloeYue@users.noreply.github.com>
Date: Tue, 8 Oct 2024 21:35:52 +0200
Subject: [PATCH 15/41] chore: Fix changelog for v12.4.0 (#27558)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
Fix changelog for v12.4.0
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27558?quickstart=1)
## **Related issues**
Fixes:
## **Manual testing steps**
1. Go to this page...
2.
3.
## **Screenshots/Recordings**
### **Before**
### **After**
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---------
Co-authored-by: Dan J Miller
---
CHANGELOG.md | 487 +++------------------------------------------------
1 file changed, 24 insertions(+), 463 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b8808ffa836a..c5fbcff7a94f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,108 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [12.4.0]
+### Added
+- Added a receive button to the home screen, allowing users to easily get their address or QR-code for receiving cryptocurrency ([#26148](https://github.com/MetaMask/metamask-extension/pull/26148))
+- Added smart transactions functionality for hardware wallet users ([#26251](https://github.com/MetaMask/metamask-extension/pull/26251))
+- Added new custom UI components for Snaps developers ([#26675](https://github.com/MetaMask/metamask-extension/pull/26675))
+- Add support for footers to Snap home pages ([#26463](https://github.com/MetaMask/metamask-extension/pull/26463))
+- [FLASK] Added Account Watcher as a preinstalled snap and added it to the menu list ([#26402](https://github.com/MetaMask/metamask-extension/pull/26402))
+- [FLASK] Added footers to Snap home pages ([#26463](https://github.com/MetaMask/metamask-extension/pull/26463))
+- Added icons for IoTeX network ([#26723](https://github.com/MetaMask/metamask-extension/pull/26723))
+- Added NEAR icon for chainId 397 and 398 ([#26459](https://github.com/MetaMask/metamask-extension/pull/26459))
+
+
+### Changed
+- Redesign contract deployment transaction screen ([#26382](https://github.com/MetaMask/metamask-extension/pull/26382))
+- Improve performance, reliability and coverage of the phishing detection feature ([#25839](https://github.com/MetaMask/metamask-extension/pull/25839))
+- Updated Moonbeam and Moonriver network and token logos ([#26677](https://github.com/MetaMask/metamask-extension/pull/26677))
+- Updated UI for add network notification window ([#25777](https://github.com/MetaMask/metamask-extension/pull/25777))
+- Update visual styling of token lists ([#26300](https://github.com/MetaMask/metamask-extension/pull/26300))
+- Update spacing on Snap home page ([#26462](https://github.com/MetaMask/metamask-extension/pull/26462))
+- [FLASK] Integrated Snaps into the redesigned confirmation pages ([#26435](https://github.com/MetaMask/metamask-extension/pull/26435))
+
### Fixed
-- fix: flaky test `Test Snap Interactive UI test interactive ui elements` ([#26792](https://github.com/MetaMask/metamask-extension/pull/26792))
-- feat: Update Polygon from `MATIC` to `POL` ([#26671](https://github.com/MetaMask/metamask-extension/pull/26671))
-- feat: implement client side malicious network request detection ([#25839](https://github.com/MetaMask/metamask-extension/pull/25839))
-- fix: Improve migration 121.1 state validation ([#26773](https://github.com/MetaMask/metamask-extension/pull/26773))
-- chore: Bump Snaps dependencies ([#26675](https://github.com/MetaMask/metamask-extension/pull/26675))
-- refactor: extract Send-specific functionality out of AssetPicker ([#26558](https://github.com/MetaMask/metamask-extension/pull/26558))
-- fix: rename migration 126 to 121.1 ([#26742](https://github.com/MetaMask/metamask-extension/pull/26742))
-- chore: Bump `storybook`, `@storybook/*` to `^7.6.20`, `storybook-dark-mode` from `^3.0.3` to `^4.0.2` ([#26703](https://github.com/MetaMask/metamask-extension/pull/26703))
-- fix: Sentry app state null data to show null as value. ([#26522](https://github.com/MetaMask/metamask-extension/pull/26522))
-- chore: Master sync ([#26737](https://github.com/MetaMask/metamask-extension/pull/26737))
-- fix: Stop using a hardcoded Snap ID for notifications ([#26739](https://github.com/MetaMask/metamask-extension/pull/26739))
-- chore: MMI Fixes passing the state to route using history.push ([#26722](https://github.com/MetaMask/metamask-extension/pull/26722))
-- Merge origin/develop into master-sync
-- test: Add integration test for insufficient gas ([#26711](https://github.com/MetaMask/metamask-extension/pull/26711))
-- test: [Snaps E2E] Add changes to fix flakiness in Snaps UI Images test ([#26725](https://github.com/MetaMask/metamask-extension/pull/26725))
-- test: Add integration test for gas estimate failed alert ([#26681](https://github.com/MetaMask/metamask-extension/pull/26681))
-- fix: flaky test `Click bridge button @no-mmi loads portfolio tab from asset overview when flag is turned off` ([#26654](https://github.com/MetaMask/metamask-extension/pull/26654))
-- fix: flaky test `Navigation Signature - Different signature types initiates and queues multiple signatures and confirms` ([#26707](https://github.com/MetaMask/metamask-extension/pull/26707))
-- feat: adding context to get current confirmation in re-designed confirmation pages PR-1 ([#26587](https://github.com/MetaMask/metamask-extension/pull/26587))
-- fix: `wallet_addEthereumChain` does not attach a `result` under certain conditions ([#26726](https://github.com/MetaMask/metamask-extension/pull/26726))
-- fix: Add IOTX icon ([#26723](https://github.com/MetaMask/metamask-extension/pull/26723))
-- test: Add integration tests for network busy alert ([#26679](https://github.com/MetaMask/metamask-extension/pull/26679))
-- feat: Temporarily hide Approve redesigned pages ([#26676](https://github.com/MetaMask/metamask-extension/pull/26676))
-- perf: use an interstitial page to load `popup.html`; load scripts using `defer`ed script tags ([#26555](https://github.com/MetaMask/metamask-extension/pull/26555))
-- feat: Add metrics to track where signature rejection occurred ([#26469](https://github.com/MetaMask/metamask-extension/pull/26469))
-- chore: update @metamask/bitcoin-wallet-snap to 0.5.0 ([#26701](https://github.com/MetaMask/metamask-extension/pull/26701))
-- fix: adding missing token images ([#26708](https://github.com/MetaMask/metamask-extension/pull/26708))
-- feat: Added Edit networks screen modal ([#26097](https://github.com/MetaMask/metamask-extension/pull/26097))
-- perf: add trace for UI startup ([#26636](https://github.com/MetaMask/metamask-extension/pull/26636))
-- fix: Address design review on contract interaction and deployment red… ([#26659](https://github.com/MetaMask/metamask-extension/pull/26659))
-- test: [Snaps E2E] Add test cases for signature confirmations redesign to signature insights snaps test ([#26691](https://github.com/MetaMask/metamask-extension/pull/26691))
-- feat: updated ui for adding chain id screen ([#25777](https://github.com/MetaMask/metamask-extension/pull/25777))
-- fix: update moonbeam and moonriver network and token logos ([#26677](https://github.com/MetaMask/metamask-extension/pull/26677))
-- chore: MMI adds back the current Tx confirmation view to MMI ([#26539](https://github.com/MetaMask/metamask-extension/pull/26539))
-- fix(snaps): Use ApprovalType instead DIALOG_APPROVAL_TYPES in confirmation page ([#26655](https://github.com/MetaMask/metamask-extension/pull/26655))
-- fix: catch error for getTokenStandardAndDetails ([#26269](https://github.com/MetaMask/metamask-extension/pull/26269))
-- chore: Master sync ([#26641](https://github.com/MetaMask/metamask-extension/pull/26641))
-- chore: update gitignore ([#26642](https://github.com/MetaMask/metamask-extension/pull/26642))
-- fix: flaky test `Phishing Detection should navigate the user to PhishFort to dispute a Phishfort Block` ([#26651](https://github.com/MetaMask/metamask-extension/pull/26651))
-- fix: flaky tests `Sentry errors before initialization, after opting into metrics @no-mmi should capture UI application state`... ([#26648](https://github.com/MetaMask/metamask-extension/pull/26648))
-- fix: flaky test `Vault Decryptor Page is able to decrypt the vault us..` due to empty file load ([#26612](https://github.com/MetaMask/metamask-extension/pull/26612))
-- Merge branch 'develop' into master-sync
-- fix: flaky test `Increase Token Allowance increases token spending ca..` ([#26640](https://github.com/MetaMask/metamask-extension/pull/26640))
-- chore: bump smart transactions controller ([#26644](https://github.com/MetaMask/metamask-extension/pull/26644))
-- chore: Polish multichain token list styles ([#26300](https://github.com/MetaMask/metamask-extension/pull/26300))
-- Merge origin/develop into master-sync
-- feat: upgrade network controller to v20 ([#26150](https://github.com/MetaMask/metamask-extension/pull/26150))
-- docs: Add publish a release to Sentry flow steps ([#26605](https://github.com/MetaMask/metamask-extension/pull/26605))
-- chore: set bridge network allowlists from feature flags ([#26147](https://github.com/MetaMask/metamask-extension/pull/26147))
-- chore: anonymize send analytic properties #26627 ([#26628](https://github.com/MetaMask/metamask-extension/pull/26628))
-- chore: add user IDs to send page analytics ([#26600](https://github.com/MetaMask/metamask-extension/pull/26600))
-- fix: bump accounts controller and migration to fix undefined selectedAccount ([#26573](https://github.com/MetaMask/metamask-extension/pull/26573))
-- feat: Integrate Snaps into the redesigned confirmations ([#26435](https://github.com/MetaMask/metamask-extension/pull/26435))
-- refactor: Replace usages of the deprecated `setProviderType` ([#22619](https://github.com/MetaMask/metamask-extension/pull/22619))
-- refactor: Use generic helper function to initiate signatures ([#26584](https://github.com/MetaMask/metamask-extension/pull/26584))
-- test: [Snaps E2E] Update snaps dialog test to include Custom dialog type ([#26598](https://github.com/MetaMask/metamask-extension/pull/26598))
-- feat: new receive flow ([#26148](https://github.com/MetaMask/metamask-extension/pull/26148))
-- fix: remove speed up and cancel controller validation ([#26492](https://github.com/MetaMask/metamask-extension/pull/26492))
-- fix: flaky test `Test Snap Name Lookup tests name-lookup functionalit...` ([#26583](https://github.com/MetaMask/metamask-extension/pull/26583))
-- feat: Add contract deployment redesigned transaction screen ([#26382](https://github.com/MetaMask/metamask-extension/pull/26382))
-- feat: add transaction performance metrics ([#26332](https://github.com/MetaMask/metamask-extension/pull/26332))
-- test: add tests for insufficient funds alert ([#26512](https://github.com/MetaMask/metamask-extension/pull/26512))
-- feat: account watcher e2e ([#26524](https://github.com/MetaMask/metamask-extension/pull/26524))
-- feat: update add team label workflow ([#26548](https://github.com/MetaMask/metamask-extension/pull/26548))
-- feat: Add approval static simulation ([#26514](https://github.com/MetaMask/metamask-extension/pull/26514))
-- fix: Snapshot unit tests ([#26585](https://github.com/MetaMask/metamask-extension/pull/26585))
-- chore: Rename `permittedChains` permission to `endowment:permitted-chains` ([#26534](https://github.com/MetaMask/metamask-extension/pull/26534))
-- feat: Redesign Approve confirmation ([#26464](https://github.com/MetaMask/metamask-extension/pull/26464))
-- feat: Enable hardware wallets for smart transactions, sign a transaction only once ([#26251](https://github.com/MetaMask/metamask-extension/pull/26251))
-- fix: Allowlist Snap UI card component ([#26565](https://github.com/MetaMask/metamask-extension/pull/26565))
-- fix(deps): Bump `@metamask/eth-json-rpc-middleware` to `^14.0.0`, `@metamask/transaction-controller` to `^35.1.1` ([#26143](https://github.com/MetaMask/metamask-extension/pull/26143))
-- fix: adding warning for origin on redesigned pages ([#26306](https://github.com/MetaMask/metamask-extension/pull/26306))
-- fix: track `swapAndSend` transaction type ([#26535](https://github.com/MetaMask/metamask-extension/pull/26535))
-- feat: added AccountWatcher as preinstalled snap and added to menu list ([#26402](https://github.com/MetaMask/metamask-extension/pull/26402))
-- fix: stick add team label version to commit hash ([#26540](https://github.com/MetaMask/metamask-extension/pull/26540))
-- fix: correct duplicate notifications event tracking in global menu ([#26525](https://github.com/MetaMask/metamask-extension/pull/26525))
-- feat: migrate protect intrinsics test to e2e ([#26197](https://github.com/MetaMask/metamask-extension/pull/26197))
-- fix: NetworkChangeToast width in wide screen mode ([#26532](https://github.com/MetaMask/metamask-extension/pull/26532))
-- fix: missing deadline in swaps stx status screen ([#25779](https://github.com/MetaMask/metamask-extension/pull/25779))
-- fix: Snap Address component UI/UX (Snaps custom UI) ([#26477](https://github.com/MetaMask/metamask-extension/pull/26477))
-- feat(snaps): Removed Snaps name-lookup permission code fences ([#26393](https://github.com/MetaMask/metamask-extension/pull/26393))
-- docs: Include MV2 build commands in README ([#26486](https://github.com/MetaMask/metamask-extension/pull/26486))
-- test: add `driver.clickElementAndWaitForWindowToClose` helper method ([#26449](https://github.com/MetaMask/metamask-extension/pull/26449))
-- chore: Integrate SnapInsightsController ([#26411](https://github.com/MetaMask/metamask-extension/pull/26411))
-- feat: Update @blockaid/ppom_release to release 1.5.2 ([#26494](https://github.com/MetaMask/metamask-extension/pull/26494))
-- chore: Master sync ([#26497](https://github.com/MetaMask/metamask-extension/pull/26497))
-- Merge origin/develop into master-sync
-- feat(notifications): use shared libraries NotificationServicesController ([#26480](https://github.com/MetaMask/metamask-extension/pull/26480))
-- perf: add parallel fetching for the network fee dropdown ([#26489](https://github.com/MetaMask/metamask-extension/pull/26489))
-- chore: remove token and nft detection modals ([#26403](https://github.com/MetaMask/metamask-extension/pull/26403))
-- chore: Add Near Icon ([#26459](https://github.com/MetaMask/metamask-extension/pull/26459))
-- fix: Restore `responsive` e2e driver option ([#25932](https://github.com/MetaMask/metamask-extension/pull/25932))
-- chore: downgrade prettier-eslint to match prettier version ([#26145](https://github.com/MetaMask/metamask-extension/pull/26145))
-- test: Add manual scenario for upgrade testing ([#26317](https://github.com/MetaMask/metamask-extension/pull/26317))
-- build(chore): switch to `defer` since it guarantees execution order once chunked ([#26425](https://github.com/MetaMask/metamask-extension/pull/26425))
-- fix: Update send transactions with custom nonce.csv ([#26451](https://github.com/MetaMask/metamask-extension/pull/26451))
-- fix: `rpcIdentifierUtility` client side grouping before emitting CustomRPC event ([#26266](https://github.com/MetaMask/metamask-extension/pull/26266))
-- feat(notifications): use notification services push controller ([#26448](https://github.com/MetaMask/metamask-extension/pull/26448))
-- feat: Add footers to Snap home pages ([#26463](https://github.com/MetaMask/metamask-extension/pull/26463))
-- fix: Remove double padding on Snap home page ([#26462](https://github.com/MetaMask/metamask-extension/pull/26462))
-- chore(webpack): update `html-bundler-webpack-plugin` from `v3.6.5` to `v3.17.3` ([#26371](https://github.com/MetaMask/metamask-extension/pull/26371))
+- Fixed network change toast width in wide screen mode ([#26532](https://github.com/MetaMask/metamask-extension/pull/26532))
+- Fixed missing deadline in swaps smart transaction status screen ([#25779](https://github.com/MetaMask/metamask-extension/pull/25779))
+- Improved Snap Address component UI/UX; stop using petnames in custom Snaps UIs ([#26477](https://github.com/MetaMask/metamask-extension/pull/26477))
+- Fixed bug that could prevent the Import NFT modal from closing after importing some tokens ([#26269](https://github.com/MetaMask/metamask-extension/pull/26269))
## [12.3.1]
### Fixed
@@ -152,368 +75,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Improved the AccountListMenu to hide the back button by default, showing it only when needed ([#27152](https://github.com/MetaMask/metamask-extension/pull/27152))
### Fixed
-- Merge branch 'Version-v12.2.0' into Version-v12.3.0
-- Merge remote-tracking branch 'origin/master' into Version-v12.2.0
-- CherryPick: "fix: issue where `wallet_addEtherumChain` was incorrectly enforcing inclusion of a blockExplorerUrls property which is not required (#26938)" ([#26938](https://github.com/MetaMask/metamask-extension/pull/26938))
-- fix: update notifications events (#26807) ([#26807](https://github.com/MetaMask/metamask-extension/pull/26807))
-- Update v12.2.0 with changes from v12.1.2 ([#26895](https://github.com/MetaMask/metamask-extension/pull/26895))
-- Merge remote-tracking branch 'origin/master' into sync-v12.1.2
-- perf(cherry-pick): use an interstitial page to load `popup.html`; load scripts using `defer`ed script tags (#26555) ([#26555](https://github.com/MetaMask/metamask-extension/pull/26555))
-- v12.2.0 sync v12.1.1 ([#26842](https://github.com/MetaMask/metamask-extension/pull/26842))
-- Merge branch 'Version-v12.2.0' into v12.2.0-sync-v12.1.1
-- ci: Prevent E2E timeouts on release changes (#26846) [cherry-pick] ([#26846](https://github.com/MetaMask/metamask-extension/pull/26846))
-- Fix type error
-- Fix changelog merge conflicts
-- Update LavaMoat policies
-- Run yarn dedupe
-- Update LavaMoat policies
-- Merge branch 'Version-v12.2.0' into v12.2.0-sync-v12.1.1
-- chore: MMI adds cherry pick for PR 25967 ([#26736](https://github.com/MetaMask/metamask-extension/pull/26736))
-- Merge remote-tracking branch 'origin/Version-v12.2.0' into v12.2.0-sync-v12.1.1
-- Merge remote-tracking branch 'origin/master' into v12.2.0-sync-v12.1.1
-- fix(cherry-pick): remove BTC accounts from send flow (#26271) ([#26271](https://github.com/MetaMask/metamask-extension/pull/26271))
-- feat(cherry-pick): support creation of Bitcoin testnet accounts (#25772) ([#25772](https://github.com/MetaMask/metamask-extension/pull/25772))
-- fix(cherry-pick): remove btc account from permission connect lists (#25980) ([#25980](https://github.com/MetaMask/metamask-extension/pull/25980))
-- fix(cherry-pick): remove submitRequest from dapp permission (#26319) ([#26319](https://github.com/MetaMask/metamask-extension/pull/26319))
-- chore: update @metamask/bitcoin-wallet-snap to 0.5.0 ([#26701](https://github.com/MetaMask/metamask-extension/pull/26701))
-- chore: update @metamask/bitcoin-wallet-snap to 0.4.0 ([#26229](https://github.com/MetaMask/metamask-extension/pull/26229))
-- chore: update @metamask/bitcoin-wallet-snap to 0.3.0 ([#26168](https://github.com/MetaMask/metamask-extension/pull/26168))
-- chore: update Bitcoin Snap to version 0.2.5 ([#26058](https://github.com/MetaMask/metamask-extension/pull/26058))
-- fix(multichain): use accounts{Added,Removed} to fetch/clear balances ([#25884](https://github.com/MetaMask/metamask-extension/pull/25884))
-- feat: add BTC support survey link ([#25875](https://github.com/MetaMask/metamask-extension/pull/25875))
-- Cherrypick flaky test fix 12.2.0 ([#26747](https://github.com/MetaMask/metamask-extension/pull/26747))
-- chore: cherry pick remove token and nft detection modals (#26403) ([#26403](https://github.com/MetaMask/metamask-extension/pull/26403))
-- Synchronize v12.2.0 RC with v12.1.0 ([#26729](https://github.com/MetaMask/metamask-extension/pull/26729))
-- Merge remote-tracking branch 'origin/master' into v12.2.0-sync-master
-- v12.2.0 sync with v12.1.0 ([#26695](https://github.com/MetaMask/metamask-extension/pull/26695))
-- Fix Sentry state merge conflict error
-- fix cherry-pick test: UX: Multichain: Add E2E for signaling network change from Netwo… ([#26704](https://github.com/MetaMask/metamask-extension/pull/26704))
-- test: Removed step from e2e tests ([#25910](https://github.com/MetaMask/metamask-extension/pull/25910))
-- Update LavaMoat policies
-- Resolve changelog conflicts
-- DResolve audit advisory
-- Merge remote-tracking branch 'origin/Version-v12.1.0' into v12.2.0-sync-with-v12.1.0
-- Patch fix for initial connections in preinstalled Snaps ([#26602](https://github.com/MetaMask/metamask-extension/pull/26602))
-- add version in changelog/package.json files ([#25766](https://github.com/MetaMask/metamask-extension/pull/25766))
-- chore: Master sync ([#26395](https://github.com/MetaMask/metamask-extension/pull/26395))
-- chore: Bump Snaps packages ([#26086](https://github.com/MetaMask/metamask-extension/pull/26086))
-- fix: Improve AccountListMenu/Item performance ([#26379](https://github.com/MetaMask/metamask-extension/pull/26379))
-- fix: Codespaces `corepack enable` ([#25161](https://github.com/MetaMask/metamask-extension/pull/25161))
-- fix: display toast message if user quickly sends transaction on different networks ([#26114](https://github.com/MetaMask/metamask-extension/pull/26114))
-- fix: problem with origins in the Snaps permission UI ([#26422](https://github.com/MetaMask/metamask-extension/pull/26422))
-- feat: Add abstraction for Snaps permissions ([#25175](https://github.com/MetaMask/metamask-extension/pull/25175))
-- test: add transaction contract interaction integration tests ([#26272](https://github.com/MetaMask/metamask-extension/pull/26272))
-- fix: timeout and "Rerun failed tests" ([#26239](https://github.com/MetaMask/metamask-extension/pull/26239))
-- chore: migrate BridgeController to BaseController v2 ([#26109](https://github.com/MetaMask/metamask-extension/pull/26109))
-- feat: Enable why did you render ([#26339](https://github.com/MetaMask/metamask-extension/pull/26339))
-- fix: Delete invalid `SelectedNetworkController` state ([#26428](https://github.com/MetaMask/metamask-extension/pull/26428))
-- test: ensure bridge button handles clicks according to feature flags ([#25812](https://github.com/MetaMask/metamask-extension/pull/25812))
-- build(webpack): polyfill `setImmediate` ([#26398](https://github.com/MetaMask/metamask-extension/pull/26398))
-- feat: feature-flagged cross-chain swaps route [METABRIDGE-867] ([#25811](https://github.com/MetaMask/metamask-extension/pull/25811))
-- chore: Remove i18n translations from Developer Options Settings Page ([#26380](https://github.com/MetaMask/metamask-extension/pull/26380))
-- fix: Do not break application if no token details are found using getTokenStandardAndDetails ([#26324](https://github.com/MetaMask/metamask-extension/pull/26324))
-- fix: Flaky contract interaction test ([#26420](https://github.com/MetaMask/metamask-extension/pull/26420))
-- fix: Enter key on Create Account checkbox should not trigger show/hide ([#26394](https://github.com/MetaMask/metamask-extension/pull/26394))
-- fix: notifications use better events ([#26410](https://github.com/MetaMask/metamask-extension/pull/26410))
-- fix: Restore snaps-controllers version following patch ([#26412](https://github.com/MetaMask/metamask-extension/pull/26412))
-- fix: Improve hex copy button ([#26384](https://github.com/MetaMask/metamask-extension/pull/26384))
-- refactor: use core profile syncing controllers. ([#26370](https://github.com/MetaMask/metamask-extension/pull/26370))
-- test: snap account contract interaction ([#26234](https://github.com/MetaMask/metamask-extension/pull/26234))
-- feat: updated SSK version in e2e and added test for creating multiple… ([#26378](https://github.com/MetaMask/metamask-extension/pull/26378))
-- Merge origin/develop into master-sync
-- chore: MMI move duck and selector to TS ([#26125](https://github.com/MetaMask/metamask-extension/pull/26125))
-- refactor(notifications): use contentful package as dev dependency ([#26381](https://github.com/MetaMask/metamask-extension/pull/26381))
-- fix: remove submitRequest from dapp permission ([#26319](https://github.com/MetaMask/metamask-extension/pull/26319))
-- feat: Add integration test for blockaid on contract interaction ([#26366](https://github.com/MetaMask/metamask-extension/pull/26366))
-- refactor: add performance tracing infrastructure ([#26044](https://github.com/MetaMask/metamask-extension/pull/26044))
-- refactor: replace deprecated mixins with Text component in slippage-buttons ([#25638](https://github.com/MetaMask/metamask-extension/pull/25638))
-- refactor: replace deprecated mixins with text component in loading-swaps-quotes ([#25553](https://github.com/MetaMask/metamask-extension/pull/25553))
-- feat: Add metrics for alerts (transactions redesign) ([#26121](https://github.com/MetaMask/metamask-extension/pull/26121))
-- fix(25350): fix flakey token importing e2e test ([#26351](https://github.com/MetaMask/metamask-extension/pull/26351))
-- fix: enable Save button on Add Contact page for address input ([#26155](https://github.com/MetaMask/metamask-extension/pull/26155))
-- test: Add test for migration 120.2 and fix docs ([#26333](https://github.com/MetaMask/metamask-extension/pull/26333))
-- chore: normalize separator in `content` on the `viewport` `meta` tag ([#26268](https://github.com/MetaMask/metamask-extension/pull/26268))
-- fix: Stop logging pipeline stream errors in the service worker if they match 'Premature close' ([#26336](https://github.com/MetaMask/metamask-extension/pull/26336))
-- build: add alternative build process to enable faster developer builds ([#22506](https://github.com/MetaMask/metamask-extension/pull/22506))
-- fix: issue where `setNetworkClientIdForDomain` was called without checking whether the origin was eligible for setting its own network ([#26323](https://github.com/MetaMask/metamask-extension/pull/26323))
-- fix: get permit and order signatures token decimals ([#26292](https://github.com/MetaMask/metamask-extension/pull/26292))
-- feat: Update Redesign Signature Permit to show ellipsis at max 15 digits ([#26227](https://github.com/MetaMask/metamask-extension/pull/26227))
-- fix: remove the ability to send to btc accounts in send page ([#26271](https://github.com/MetaMask/metamask-extension/pull/26271))
-- fix: Adding migration 125 to remove Deprecated TxController Key from state ([#26267](https://github.com/MetaMask/metamask-extension/pull/26267))
-- fix: Revert "fix: remove submitRequest from dapp permission" ([#26293](https://github.com/MetaMask/metamask-extension/pull/26293))
-- refactor: convert `icon-factory.js` to typescript ([#23823](https://github.com/MetaMask/metamask-extension/pull/23823))
-- fix(26065): remove persisted state mostRecentRetrievedState after initialization if no errors ([#26206](https://github.com/MetaMask/metamask-extension/pull/26206))
-- refactor: ENABLE_MV3 flag cleanup ([#26059](https://github.com/MetaMask/metamask-extension/pull/26059))
-- test: fix flaky test Import flow @no-mmi Import wallet using Secret Recovery Phrase ([#26275](https://github.com/MetaMask/metamask-extension/pull/26275))
-- chore: Fully remove `eth_sign` ([#24756](https://github.com/MetaMask/metamask-extension/pull/24756))
-- fix: remove submitRequest from dapp permission ([#26276](https://github.com/MetaMask/metamask-extension/pull/26276))
-- chore: Update `actions/cache` from v3 to v4 ([#26020](https://github.com/MetaMask/metamask-extension/pull/26020))
-- feat: QR-based add NGRAVE ZERO Hardware ([#25080](https://github.com/MetaMask/metamask-extension/pull/25080))
-- fix: Fix GitHub release description ([#26247](https://github.com/MetaMask/metamask-extension/pull/26247))
-- feat(btc): use new snap account flow for Bitcoin accounts ([#26183](https://github.com/MetaMask/metamask-extension/pull/26183))
-- refactor: replace deprecated mixins with text component in transaction-confirmed ([#25551](https://github.com/MetaMask/metamask-extension/pull/25551))
-- fix: improve warning in add network modal ([#26250](https://github.com/MetaMask/metamask-extension/pull/26250))
-- fix: Fix `create_release_pull_request` OOM error ([#26249](https://github.com/MetaMask/metamask-extension/pull/26249))
-- chore: Create a story for TokenCurrencyDisplay component ([#26172](https://github.com/MetaMask/metamask-extension/pull/26172))
-- chore: refactoring onboarding to remove deprecated components ([#26207](https://github.com/MetaMask/metamask-extension/pull/26207))
-- fix: Fix CircleCI `create_release_pull_request` job ([#26246](https://github.com/MetaMask/metamask-extension/pull/26246))
-- fix: flaky test `Import flow @no-mmi Import Account using json file` ([#26240](https://github.com/MetaMask/metamask-extension/pull/26240))
-- fix: sentry sessions ([#26192](https://github.com/MetaMask/metamask-extension/pull/26192))
-- test: [Page Object Model] rename process to flow ([#26228](https://github.com/MetaMask/metamask-extension/pull/26228))
-- test: header integration test for contract interaction ([#25981](https://github.com/MetaMask/metamask-extension/pull/25981))
-- chore: Pass along hashed `rpcUrl` during `CustomNetworkAdded` event ([#26203](https://github.com/MetaMask/metamask-extension/pull/26203))
-- chore: Create a story for PageContainerHeader component ([#26031](https://github.com/MetaMask/metamask-extension/pull/26031))
-- chore: Create a story for GasTiming component ([#25557](https://github.com/MetaMask/metamask-extension/pull/25557))
-- New Crowdin translations by Github Action ([#26230](https://github.com/MetaMask/metamask-extension/pull/26230))
-- chore: update @metamask/bitcoin-wallet-snap to 0.4.0 ([#26229](https://github.com/MetaMask/metamask-extension/pull/26229))
-- fix: flaky test `Sentry errors before initialization, after opting into metrics @no-mmi should send error events in background` ([#26216](https://github.com/MetaMask/metamask-extension/pull/26216))
-- chore: Create a story for NftCollectionImage component ([#26069](https://github.com/MetaMask/metamask-extension/pull/26069))
-- fix: update icons ([#26180](https://github.com/MetaMask/metamask-extension/pull/26180))
-- refactor: replace Typography with Text component in restore-vault.js ([#25636](https://github.com/MetaMask/metamask-extension/pull/25636))
-- chore: Create a story for convert-token-to-nft-modal component ([#25561](https://github.com/MetaMask/metamask-extension/pull/25561))
-- refactor: replace deprecated mixins with Text component in qr-code-view ([#25637](https://github.com/MetaMask/metamask-extension/pull/25637))
-- test: Add manual scenario for network polling scenario ([#26195](https://github.com/MetaMask/metamask-extension/pull/26195))
-- feat: Add experimental settings toggle for transactions redesign ([#26010](https://github.com/MetaMask/metamask-extension/pull/26010))
-- feat: Support Permit variants: PermitSingle, PermitBatch, PermitTransferFrom, PermitBatchTransferFrom, TradeOrder, Seaport ([#26107](https://github.com/MetaMask/metamask-extension/pull/26107))
-- feat: updated dapp permission screen ([#25703](https://github.com/MetaMask/metamask-extension/pull/25703))
-- fix: improve performance in large signature request confirmations ([#26209](https://github.com/MetaMask/metamask-extension/pull/26209))
-- refactor: remove password manager mention ([#25985](https://github.com/MetaMask/metamask-extension/pull/25985))
-- New Crowdin translations by Github Action ([#25939](https://github.com/MetaMask/metamask-extension/pull/25939))
-- chore: remove opera manifest files as they are not used ([#26200](https://github.com/MetaMask/metamask-extension/pull/26200))
-- fix(deps): bump fast-xml-parser from 4.3.4 to 4.4.1. ([#26202](https://github.com/MetaMask/metamask-extension/pull/26202))
-- test: [Snaps E2E] remove unnecessary steps from snaps UI Images test ([#25640](https://github.com/MetaMask/metamask-extension/pull/25640))
-- fix: truncate long tokenId ([#26179](https://github.com/MetaMask/metamask-extension/pull/26179))
-- chore: Add en_GB locale ([#26196](https://github.com/MetaMask/metamask-extension/pull/26196))
-- chore: upgrade to Sentry 8 ([#25999](https://github.com/MetaMask/metamask-extension/pull/25999))
-- refactor: add unlock checks for notification related controllers ([#26189](https://github.com/MetaMask/metamask-extension/pull/26189))
-- fix: interpret multipart errors correctly and allow ignore ([#26113](https://github.com/MetaMask/metamask-extension/pull/26113))
-- feat: migrate global unit tests from Mocha to Jest ([#26104](https://github.com/MetaMask/metamask-extension/pull/26104))
-- fix: node being setup twice ([#26052](https://github.com/MetaMask/metamask-extension/pull/26052))
-- fix: setupControllerConnection outstream end event listener ([#26141](https://github.com/MetaMask/metamask-extension/pull/26141))
-- fix: Address performance issues with 'Portfolio Dashboard' loading in test environment ([#26182](https://github.com/MetaMask/metamask-extension/pull/26182))
-- chore: migrating interactive-replacement-token-page to ts ([#26115](https://github.com/MetaMask/metamask-extension/pull/26115))
-- feat: (cherry-pick)(Version v12.2.0) Migration #122 set redesignedConfirmationsEnabled to true ([#26139](https://github.com/MetaMask/metamask-extension/pull/26139))
-- chore: update @metamask/bitcoin-wallet-snap to 0.3.0 ([#26168](https://github.com/MetaMask/metamask-extension/pull/26168))
-- test: fix potential api-spec test race condition when adding to task queue ([#26171](https://github.com/MetaMask/metamask-extension/pull/26171))
-- fix(user-preference-currency-display): remove unused prop ethLogoHeight ([#24517](https://github.com/MetaMask/metamask-extension/pull/24517))
-- fix: update logos for flare-mainnet and songbird ([#25560](https://github.com/MetaMask/metamask-extension/pull/25560))
-- feat: define account name during creation ([#25191](https://github.com/MetaMask/metamask-extension/pull/25191))
-- chore: MMI move custody component to TS ([#26096](https://github.com/MetaMask/metamask-extension/pull/26096))
-- chore: add portfolio ephemeral domain URL ([#26163](https://github.com/MetaMask/metamask-extension/pull/26163))
-- fix: Flaky test `4byte setting ` ([#26111](https://github.com/MetaMask/metamask-extension/pull/26111))
-- fix: PPOM blockaid update ([#26154](https://github.com/MetaMask/metamask-extension/pull/26154))
-- fix: flaky BTC e2e tests ([#26082](https://github.com/MetaMask/metamask-extension/pull/26082))
-- chore: Add extra event props ([#26123](https://github.com/MetaMask/metamask-extension/pull/26123))
-- refactor: fix event names used to track notifications ([#25521](https://github.com/MetaMask/metamask-extension/pull/25521))
-- test: [Snaps E2E] Create test for snap dialog JSX functionality ([#25493](https://github.com/MetaMask/metamask-extension/pull/25493))
-- chore: update BNB logos ([#26140](https://github.com/MetaMask/metamask-extension/pull/26140))
-- chore: cleanup `.prettierignore` file ([#24828](https://github.com/MetaMask/metamask-extension/pull/24828))
-- chore: Bump `@metamask/ens-controller` to v12 ([#26127](https://github.com/MetaMask/metamask-extension/pull/26127))
-- chore: Bump `@metamask/transaction-controller` to v34 ([#26124](https://github.com/MetaMask/metamask-extension/pull/26124))
-- chore: Create a story for Snackbar component ([#25515](https://github.com/MetaMask/metamask-extension/pull/25515))
-- fix: add new helper function for `openMenuSafe` to mitigate all ocurrences for opening menu with MMI build ([#26079](https://github.com/MetaMask/metamask-extension/pull/26079))
-- feat: make add-team-label use the reusable workflow ([#25807](https://github.com/MetaMask/metamask-extension/pull/25807))
-- chore: MMI-5301 adds enums for custody type and status ([#26006](https://github.com/MetaMask/metamask-extension/pull/26006))
-- fix: enable siwe redesign ([#26136](https://github.com/MetaMask/metamask-extension/pull/26136))
-- chore: cleanup `.prettierignore` file ([#24828](https://github.com/MetaMask/metamask-extension/pull/24828))
-- chore: Bump `@metamask/ens-controller` to v12 ([#26127](https://github.com/MetaMask/metamask-extension/pull/26127))
-- chore: Bump `@metamask/transaction-controller` to v34 ([#26124](https://github.com/MetaMask/metamask-extension/pull/26124))
-- Revert "test: Adding e2e for SIWE and re-enabling redesign for SIWE (#25831)" ([#25831](https://github.com/MetaMask/metamask-extension/pull/25831))
-- chore: Create a story for Snackbar component ([#25515](https://github.com/MetaMask/metamask-extension/pull/25515))
-- fix: add new helper function for `openMenuSafe` to mitigate all ocurrences for opening menu with MMI build ([#26079](https://github.com/MetaMask/metamask-extension/pull/26079))
-- test: Adding e2e for SIWE and re-enabling redesign for SIWE (#25831) ([#25831](https://github.com/MetaMask/metamask-extension/pull/25831))
-- feat: make add-team-label use the reusable workflow ([#25807](https://github.com/MetaMask/metamask-extension/pull/25807))
-- chore: MMI-5301 adds enums for custody type and status ([#26006](https://github.com/MetaMask/metamask-extension/pull/26006))
-- feat: Move ENABLE_CONFIRMATION_REDESIGN feature flag to the developer… ([#26095](https://github.com/MetaMask/metamask-extension/pull/26095))
-- fix: remove btc account from permission connect lists ([#25980](https://github.com/MetaMask/metamask-extension/pull/25980))
-- feat: update network list item to include start accessory and end ([#25507](https://github.com/MetaMask/metamask-extension/pull/25507))
-- chore: mmi 5305 mmi pages typescript migration ([#26081](https://github.com/MetaMask/metamask-extension/pull/26081))
-- fix: Move Snaps hooks out of code fence ([#26120](https://github.com/MetaMask/metamask-extension/pull/26120))
-- feat: Mitigate risk for distracted users on queued transactions from different dApps ([#25852](https://github.com/MetaMask/metamask-extension/pull/25852))
-- fix: lock Chrome version to 126 (#26101) ([#26101](https://github.com/MetaMask/metamask-extension/pull/26101))
-- feat: Add metrics event for advanced details section toggling ([#26083](https://github.com/MetaMask/metamask-extension/pull/26083))
-- fix: display link to privacy-policy explanation in onboarding flow ([#26038](https://github.com/MetaMask/metamask-extension/pull/26038))
-- chore: Create a story for InvalidCustomNetworkAlert component ([#25600](https://github.com/MetaMask/metamask-extension/pull/25600))
-- fix: number formatting on swap + send tx detail ([#26029](https://github.com/MetaMask/metamask-extension/pull/26029))
-- fix: Flaky test `Account Custom Name..` ([#26062](https://github.com/MetaMask/metamask-extension/pull/26062))
-- fix: snap flakiness on `installSnapSimpleKeyring` function ([#26039](https://github.com/MetaMask/metamask-extension/pull/26039))
-- fix: lock Chrome version to 126 ([#26101](https://github.com/MetaMask/metamask-extension/pull/26101))
-- fix: remove halo for tokens ([#26016](https://github.com/MetaMask/metamask-extension/pull/26016))
-- refactor: replace typography with text component in creation-successful.js ([#25552](https://github.com/MetaMask/metamask-extension/pull/25552))
-- fix: `vault decryption` broken tests due to update on window handling ([#26074](https://github.com/MetaMask/metamask-extension/pull/26074))
-- docs: Centralize Author/Team Mapping for Commit Tracking ([#25986](https://github.com/MetaMask/metamask-extension/pull/25986))
-- fix: flaky test: Check the toggle for hex data ([#25899](https://github.com/MetaMask/metamask-extension/pull/25899))
-- chore: migrated institutional ui components to ts ([#25858](https://github.com/MetaMask/metamask-extension/pull/25858))
-- chore: removed unused component ([#26000](https://github.com/MetaMask/metamask-extension/pull/26000))
-- chore: update Bitcoin Snap to version 0.2.5 ([#26058](https://github.com/MetaMask/metamask-extension/pull/26058))
-- refactor: replace Typography with Text component in metametrics.js ([#25630](https://github.com/MetaMask/metamask-extension/pull/25630))
-- refactor: replace typography with text component in review recovery phrase ([#25265](https://github.com/MetaMask/metamask-extension/pull/25265))
-- test: new switchToWindowWithTitle w/ Extension communication ([#25362](https://github.com/MetaMask/metamask-extension/pull/25362))
-- ci: Trimming the gitdiff output before writing to output file ([#26057](https://github.com/MetaMask/metamask-extension/pull/26057))
-- chore: tweak send page styling ([#25982](https://github.com/MetaMask/metamask-extension/pull/25982))
-- fix: mmi flaky tests `Reveal SRP through settings completes quiz and reveals SRP QR after wrong answers` , `Sign Typed Data Signature Request can initiate and reject a Signature Request of Sign Typed Data`, `Sign Typed Data Signature Request can queue multiple Signature Requests of Sign Typed Data and confirm` ([#26055](https://github.com/MetaMask/metamask-extension/pull/26055))
-- chore: Create a story for IconButton component ([#25277](https://github.com/MetaMask/metamask-extension/pull/25277))
-- fix: center token icon ([#26013](https://github.com/MetaMask/metamask-extension/pull/26013))
-- fix: flaky test `Import flow @no-mmi Import wallet using Secret Recovery Phrase with pasting word by word` ([#26049](https://github.com/MetaMask/metamask-extension/pull/26049))
-- fix: flaky test 25912 ([#25913](https://github.com/MetaMask/metamask-extension/pull/25913))
-- chore: add privacy query params to portfolio navigation ([#25958](https://github.com/MetaMask/metamask-extension/pull/25958))
-- fix: (cherry-pick) Remove special reject button case from api spec tests (#26048) ([#26048](https://github.com/MetaMask/metamask-extension/pull/26048))
-- chore: Temporarily disable Playwright Swaps tests ([#26050](https://github.com/MetaMask/metamask-extension/pull/26050))
-- fix: Remove special reject button case from api spec tests ([#26048](https://github.com/MetaMask/metamask-extension/pull/26048))
-- test(e2e): unlock trezor account ([#25824](https://github.com/MetaMask/metamask-extension/pull/25824))
-- fix: Flaky "Signature Approved Event" e2e test ([#26040](https://github.com/MetaMask/metamask-extension/pull/26040))
-- feat: Migration #122 set redesignedConfirmationsEnabled to true ([#25769](https://github.com/MetaMask/metamask-extension/pull/25769))
-- fix: Revert "refactor: use withKeyring method (#25435)" ([#25435](https://github.com/MetaMask/metamask-extension/pull/25435))
-- fix: :label: update the text in the popup to enable notifications ([#26026](https://github.com/MetaMask/metamask-extension/pull/26026))
-- fix: map the supported block explorers ([#25908](https://github.com/MetaMask/metamask-extension/pull/25908))
-- fix: update css for modals ([#25961](https://github.com/MetaMask/metamask-extension/pull/25961))
-- fix: Fix permssions for `update-attributions` workflow ([#26019](https://github.com/MetaMask/metamask-extension/pull/26019))
-- fix: add migration for profile syncing controller ([#26004](https://github.com/MetaMask/metamask-extension/pull/26004))
-- test: Adding e2e for SIWE and re-enabling redesign for SIWE ([#25831](https://github.com/MetaMask/metamask-extension/pull/25831))
-- test: UX: Multichain: Add E2E for signaling network change from Network menu to dapp, Autoswitching networks ([#25765](https://github.com/MetaMask/metamask-extension/pull/25765))
-- feat: Move ENABLE_CONFIRMATION_REDESIGN feature flag to the developer settings page ([#25520](https://github.com/MetaMask/metamask-extension/pull/25520))
-- fix: `yarn:start:test:flask` is broken `Lavapack is not defined` ([#25995](https://github.com/MetaMask/metamask-extension/pull/25995))
-- feat: add utility function to get supported chains from the Security Alerts API ([#25716](https://github.com/MetaMask/metamask-extension/pull/25716))
-- fix: `vault-decryption` test since the order of announcement modals changed ([#25997](https://github.com/MetaMask/metamask-extension/pull/25997))
-- fix: updated switch to this account condition ([#25609](https://github.com/MetaMask/metamask-extension/pull/25609))
-- fix: flaky test Settings Redirects to ENS domains when user inputs ENS into address bar ([#25782](https://github.com/MetaMask/metamask-extension/pull/25782))
-- chore: MMI-5248 introduce the token allowance functionality for MMI ([#25967](https://github.com/MetaMask/metamask-extension/pull/25967))
-- fix: vertically align asset image ([#25988](https://github.com/MetaMask/metamask-extension/pull/25988))
-- feat: Adding state per window in e2e, excluding null state ([#25900](https://github.com/MetaMask/metamask-extension/pull/25900))
-- fix: attribution link ([#25947](https://github.com/MetaMask/metamask-extension/pull/25947))
-- feat: Enable hardware wallets for smart transactions in swaps ([#25742](https://github.com/MetaMask/metamask-extension/pull/25742))
-- fix: fix link redirection ([#25983](https://github.com/MetaMask/metamask-extension/pull/25983))
-- fix: fix overlapping modals ([#25962](https://github.com/MetaMask/metamask-extension/pull/25962))
-- feat: Show the Close extension button on the Smart Transaction Status Page for a pending dapp transaction ([#25965](https://github.com/MetaMask/metamask-extension/pull/25965))
-- fix(multichain): use accounts{Added,Removed} to fetch/clear balances ([#25884](https://github.com/MetaMask/metamask-extension/pull/25884))
-- test: Add integration tests for permit simulation section ([#25856](https://github.com/MetaMask/metamask-extension/pull/25856))
-- fix: fixed max width for permissions page ([#25870](https://github.com/MetaMask/metamask-extension/pull/25870))
-- fix: show current network if domains are undefined ([#25960](https://github.com/MetaMask/metamask-extension/pull/25960))
-- fix: notification slowness and crashes ([#25946](https://github.com/MetaMask/metamask-extension/pull/25946))
-- ci: Disabling non-lint CI on the l10n_crowdin_action branch ([#25809](https://github.com/MetaMask/metamask-extension/pull/25809))
-- refactor: use `withKeyring` method ([#25435](https://github.com/MetaMask/metamask-extension/pull/25435))
-- feat: add BTC support survey link ([#25875](https://github.com/MetaMask/metamask-extension/pull/25875))
-- fix: re-organize files under assets folder ([#25897](https://github.com/MetaMask/metamask-extension/pull/25897))
-- fix: fix css nft detail ([#25931](https://github.com/MetaMask/metamask-extension/pull/25931))
-- fix: Implement Auto-Enable Feature for Basic Functionality in Metamask Extension v12.1.0 ([#25944](https://github.com/MetaMask/metamask-extension/pull/25944))
-- fix: Handle error when offscreen document already exists ([#25138](https://github.com/MetaMask/metamask-extension/pull/25138))
-- test: Expand coverage of sourcemap validator ([#25115](https://github.com/MetaMask/metamask-extension/pull/25115))
-- feat: Add full screen Snap Home and Dialog ([#25670](https://github.com/MetaMask/metamask-extension/pull/25670))
-- chore: swaps codeowners reorg ([#24803](https://github.com/MetaMask/metamask-extension/pull/24803))
-- fix: track token detection enabled ([#25822](https://github.com/MetaMask/metamask-extension/pull/25822))
-- fix: rm locales in other languages ([#25936](https://github.com/MetaMask/metamask-extension/pull/25936))
-- fix: fix ([#25907](https://github.com/MetaMask/metamask-extension/pull/25907))
-- fix: password reset ([#25847](https://github.com/MetaMask/metamask-extension/pull/25847))
-- New Crowdin translations by Github Action ([#24889](https://github.com/MetaMask/metamask-extension/pull/24889))
-- fix: Remove abandoned test:unit:jest command ([#25905](https://github.com/MetaMask/metamask-extension/pull/25905))
-- fix(22851): check if active device to prevent autoconnect for hw ([#25503](https://github.com/MetaMask/metamask-extension/pull/25503))
-- test: Removed step from e2e tests ([#25910](https://github.com/MetaMask/metamask-extension/pull/25910))
-- fix: calcTokenAmount BigNumber more than 15 digits error ([#25799](https://github.com/MetaMask/metamask-extension/pull/25799))
-- feat: add custom form check alerts ([#25259](https://github.com/MetaMask/metamask-extension/pull/25259))
-- fix: test failure on firefox ([#25895](https://github.com/MetaMask/metamask-extension/pull/25895))
-- fix: disables "swap and send" for MMI ([#25886](https://github.com/MetaMask/metamask-extension/pull/25886))
-- fix: Fixed flaky test 24645 ([#25786](https://github.com/MetaMask/metamask-extension/pull/25786))
-- chore: refactor SwapsController so it extends from BaseControllerV2 ([#25681](https://github.com/MetaMask/metamask-extension/pull/25681))
-- feat: Replace "Manage in settings" with "No thanks" in the STX Opt In modal, only show the modal for non-zero balances ([#25848](https://github.com/MetaMask/metamask-extension/pull/25848))
-- feat: Display advanced section within confirmation by default for some users ([#25687](https://github.com/MetaMask/metamask-extension/pull/25687))
-- chore: bump assets-controllers to v36.0.0 ([#25857](https://github.com/MetaMask/metamask-extension/pull/25857))
-- fix: add name to scuttling exception list ([#25849](https://github.com/MetaMask/metamask-extension/pull/25849))
-- fix: update build version to align with firefox's newer version restrictions ([#25456](https://github.com/MetaMask/metamask-extension/pull/25456))
-- feat: regression label ([#25691](https://github.com/MetaMask/metamask-extension/pull/25691))
-- chore: Master sync ([#25816](https://github.com/MetaMask/metamask-extension/pull/25816))
-- fix: contract data in metrics ([#25759](https://github.com/MetaMask/metamask-extension/pull/25759))
-- fix: flaky test `ERC721 NFTs testdapp interaction` ([#25854](https://github.com/MetaMask/metamask-extension/pull/25854))
-- fix: flaky test `Create BTC Account cannot create multiple BTC accounts...` ([#25861](https://github.com/MetaMask/metamask-extension/pull/25861))
-- feat: support creation of Bitcoin testnet accounts ([#25772](https://github.com/MetaMask/metamask-extension/pull/25772))
-- fix: use of an header in a dedicated call ([#25828](https://github.com/MetaMask/metamask-extension/pull/25828))
-- feat(tests): add btc e2e tests ([#25663](https://github.com/MetaMask/metamask-extension/pull/25663))
-- feat: NFT details new design ([#25524](https://github.com/MetaMask/metamask-extension/pull/25524))
-- feat: Add fuzzy matching for name lookup ([#25264](https://github.com/MetaMask/metamask-extension/pull/25264))
-- fix: edit path to dist folder ([#25826](https://github.com/MetaMask/metamask-extension/pull/25826))
-- chore: update @metamask/bitcoin-wallet-snap to 0.2.4 (#25808) ([#25808](https://github.com/MetaMask/metamask-extension/pull/25808))
-- chore: Patch security issue in snaps-utils ([#25827](https://github.com/MetaMask/metamask-extension/pull/25827))
-- feat: add option of copy to info row component ([#25682](https://github.com/MetaMask/metamask-extension/pull/25682))
-- fix: skip blockaid validations for users internal accounts ([#25695](https://github.com/MetaMask/metamask-extension/pull/25695))
-- chore: refactor custody component ([#25684](https://github.com/MetaMask/metamask-extension/pull/25684))
-- Merge origin/develop into master-sync
-- chore: update @metamask/bitcoin-wallet-snap to 0.2.4 ([#25808](https://github.com/MetaMask/metamask-extension/pull/25808))
-- chore: removed unused getCustodianAccountsByAddress method ([#25798](https://github.com/MetaMask/metamask-extension/pull/25798))
-- feat: Make Jest unit tests run faster in GitHub actions ([#25726](https://github.com/MetaMask/metamask-extension/pull/25726))
-- revert: un-revert metrics and signature refactor test ([#25758](https://github.com/MetaMask/metamask-extension/pull/25758))
-- feat: Add `ui_customizations` metric for transactions ([#25736](https://github.com/MetaMask/metamask-extension/pull/25736))
-- test: add e2e tests for navigation (#25652) ([#25652](https://github.com/MetaMask/metamask-extension/pull/25652))
-- chore: remove `BTC_BETA_SUPPORT` flag ([#25776](https://github.com/MetaMask/metamask-extension/pull/25776))
-- chore: update @metamask/bitcoin-wallet-snap to 0.2.3 ([#25775](https://github.com/MetaMask/metamask-extension/pull/25775))
-- feat: add more whitelisted portfolio URLs ([#25767](https://github.com/MetaMask/metamask-extension/pull/25767))
-- fix: Fix page width for fullscreen mode send page ([#25639](https://github.com/MetaMask/metamask-extension/pull/25639))
-- chore: Update Snaps codeowners list ([#25581](https://github.com/MetaMask/metamask-extension/pull/25581))
-- fix: fine-tune for `Delineator` component styles ([#25760](https://github.com/MetaMask/metamask-extension/pull/25760))
-- feat: decode transaction data ([#25597](https://github.com/MetaMask/metamask-extension/pull/25597))
-- feat: add `Delineator` component ([#25610](https://github.com/MetaMask/metamask-extension/pull/25610))
-- feat(ramps): update isNativeTokenBuyable to include BTC ([#25621](https://github.com/MetaMask/metamask-extension/pull/25621))
-- fix: Fix issue 25285 max insufficient funds for gas ([#25574](https://github.com/MetaMask/metamask-extension/pull/25574))
-- feat: add BTC experimental toggle ([#25672](https://github.com/MetaMask/metamask-extension/pull/25672))
-- build: bump gas-fee-controller to v18 and remove patch ([#25679](https://github.com/MetaMask/metamask-extension/pull/25679))
-- fix: show correct asset and balance when BTC account is the selected account ([#25719](https://github.com/MetaMask/metamask-extension/pull/25719))
-- feat(btc): add BTC account creation menu entry ([#25625](https://github.com/MetaMask/metamask-extension/pull/25625))
-- fix: flaky test `Test Snap Metrics test snap update rejected metric` ([#25744](https://github.com/MetaMask/metamask-extension/pull/25744))
-- chore(deps): bump @metamask/accounts-controller from ^17.0.0 to ^17.2.0 ([#25676](https://github.com/MetaMask/metamask-extension/pull/25676))
-- fix: use LAVAMOAT_UPDATE_TOKEN in attributions workflow ([#25731](https://github.com/MetaMask/metamask-extension/pull/25731))
-- fix: caveat mutations for non-EVM accounts ([#25739](https://github.com/MetaMask/metamask-extension/pull/25739))
-- test: Add UI integration tests ([#24428](https://github.com/MetaMask/metamask-extension/pull/24428))
-- fix: revert "test: add e2e tests for navigation (#25652)" ([#25652](https://github.com/MetaMask/metamask-extension/pull/25652))
-- chore: Revert "test: e2e metrics test and refactor" ([#25722](https://github.com/MetaMask/metamask-extension/pull/25722))
-- feat: bundle pre-installed Bitcoin Wallet Snap ([#25715](https://github.com/MetaMask/metamask-extension/pull/25715))
-- fix: protect against phishing domain redirects in main/sub frames for http(s) requests ([#25153](https://github.com/MetaMask/metamask-extension/pull/25153))
-- fix: Fix crash of Transaction screen with smart transaction ([#25717](https://github.com/MetaMask/metamask-extension/pull/25717))
-- fix: Hide MMI Account Mistmatch BannerAlert from Sign-in with Ethereum (SIWE) Redesign Page ([#25662](https://github.com/MetaMask/metamask-extension/pull/25662))
-- fix: flaky test `Create token, approve token and approve token without gas approves an already created token and displays the token approval data` ([#25706](https://github.com/MetaMask/metamask-extension/pull/25706))
-- feat: Enable SIWE Signature Redesign ([#25660](https://github.com/MetaMask/metamask-extension/pull/25660))
-- fix: flaky test `Request-queue UI changes handles three confirmations on three confirmations concurrently` ([#25675](https://github.com/MetaMask/metamask-extension/pull/25675))
-- feat: move unit tests from Circleci to Github actions ([#25570](https://github.com/MetaMask/metamask-extension/pull/25570))
-- test: e2e metrics test and refactor ([#25632](https://github.com/MetaMask/metamask-extension/pull/25632))
-- test: add e2e tests for navigation ([#25652](https://github.com/MetaMask/metamask-extension/pull/25652))
-- feat: support security alerts API ([#25544](https://github.com/MetaMask/metamask-extension/pull/25544))
-- feat(ramps): add flag to ensure ramp networks are only fetched once ([#25686](https://github.com/MetaMask/metamask-extension/pull/25686))
-- fix: allow ramps dev environment on Flask ([#25659](https://github.com/MetaMask/metamask-extension/pull/25659))
-- feat: added check for if the selected account is BTC in transaction-list ([#25642](https://github.com/MetaMask/metamask-extension/pull/25642))
-- feat: Gas Fees Redesign PoC ([#24714](https://github.com/MetaMask/metamask-extension/pull/24714))
-- fix: show connected toast only for EVM accounts ([#25628](https://github.com/MetaMask/metamask-extension/pull/25628))
-- fix: changed logic to use the new banner alert ([#25626](https://github.com/MetaMask/metamask-extension/pull/25626))
-- fix: set network client id for domain ([#25646](https://github.com/MetaMask/metamask-extension/pull/25646))
-- feat: improvement for how we display big and small numbers ([#25438](https://github.com/MetaMask/metamask-extension/pull/25438))
-- chore: restore bot workflow to update attributions ([#25211](https://github.com/MetaMask/metamask-extension/pull/25211))
-- test: add swap e2e tests on Tenderly network ([#25060](https://github.com/MetaMask/metamask-extension/pull/25060))
-- fix: UX: Multichain: Add safeguard to throw error when confirmation chainId doesn't match current chainId ([#25634](https://github.com/MetaMask/metamask-extension/pull/25634))
-- chore: updates MMI custody controller ([#25631](https://github.com/MetaMask/metamask-extension/pull/25631))
-- fix: flaky test `Test Snap Get Locale test snap_getLocale functionality` ([#25648](https://github.com/MetaMask/metamask-extension/pull/25648))
-- fix: Skip blockaid validation for SIWE signature types ([#25612](https://github.com/MetaMask/metamask-extension/pull/25612))
-- feat: Add support for security alerts on zkSync, Berachain, Scroll and Metachain One on extension ([#25555](https://github.com/MetaMask/metamask-extension/pull/25555))
-- fix: Multichain: UX: Check for transactions on all networks and QueuedRequestCount ([#25614](https://github.com/MetaMask/metamask-extension/pull/25614))
-- feat: define which keyring methods Portfolio can call ([#25633](https://github.com/MetaMask/metamask-extension/pull/25633))
-- chore: flaky E2E tests improved ([#25565](https://github.com/MetaMask/metamask-extension/pull/25565))
-- feat: add SIWE mismatch account warning alert ([#25613](https://github.com/MetaMask/metamask-extension/pull/25613))
-- fix: support multichain in blockexplorer and qr code ([#25526](https://github.com/MetaMask/metamask-extension/pull/25526))
-- fix: decimal places displayed on token value on permit pages ([#25410](https://github.com/MetaMask/metamask-extension/pull/25410))
-- feat: added BTC variant to ramps-card and illustration image ([#25615](https://github.com/MetaMask/metamask-extension/pull/25615))
-- fix: Remove unused fixtures and fix test name in smart swaps disabled spec ([#25616](https://github.com/MetaMask/metamask-extension/pull/25616))
-- chore: Update @metamask/smart-transactions-controller from 10.1.2 to 10.1.6 ([#25611](https://github.com/MetaMask/metamask-extension/pull/25611))
-- fix: Fix issue 22837 about unknown error during ledger pair ([#25462](https://github.com/MetaMask/metamask-extension/pull/25462))
-- test: add e2e to swap with snap account ([#25558](https://github.com/MetaMask/metamask-extension/pull/25558))
-- chore: exclude running git diff job for the e2e quality gate in `develop`, `master` and release branches ([#25605](https://github.com/MetaMask/metamask-extension/pull/25605))
-- chore: [Delivery] Update author mapping list for PR ([#25606](https://github.com/MetaMask/metamask-extension/pull/25606))
-- fix: page object selector not found ([#25624](https://github.com/MetaMask/metamask-extension/pull/25624))
-- test: Initial PR for integrating the Page Object Model (POM) into e2e test suite ([#25373](https://github.com/MetaMask/metamask-extension/pull/25373))
-- refactor: Replace deprecated mixins with Text component in selected-account.component.js ([#25262](https://github.com/MetaMask/metamask-extension/pull/25262))
-- refactor: Replace deprecated mixins with Text component in unlock-page.component.js ([#25227](https://github.com/MetaMask/metamask-extension/pull/25227))
-- chore: Create a story for RestoreVaultPage component ([#25284](https://github.com/MetaMask/metamask-extension/pull/25284))
-- fix(snaps): Fix alignment of install origin is `snap-authorship-expanded` ([#25583](https://github.com/MetaMask/metamask-extension/pull/25583))
-- feat: Remove blockaid migration BannerAlert ([#25556](https://github.com/MetaMask/metamask-extension/pull/25556))
-- fix: failingt e2e `Click bridge button from asset page @no-mmi loads portfolio tab when flag is turned off` ([#25607](https://github.com/MetaMask/metamask-extension/pull/25607))
-- chore: adds quality gate for rerunning e2e spec files that are new or have been modified ([#24556](https://github.com/MetaMask/metamask-extension/pull/24556))
-- chore(deps): bump assets controller to v34.0.0 ([#25540](https://github.com/MetaMask/metamask-extension/pull/25540))
-- chore: add bridge controller, store and api utils ([#25044](https://github.com/MetaMask/metamask-extension/pull/25044))
-- fix: add eth_signTypedData and eth_signTypedData_v3 to `methodsRequiringNetworkSwitch` ([#25562](https://github.com/MetaMask/metamask-extension/pull/25562))
- Fixed an issue where the wallet was not accessible with a new password after resetting it ([#25847](https://github.com/MetaMask/metamask-extension/pull/25847))
- Fixed number formatting for swap + send transaction details to avoid scientific notation for small token amounts ([#26029](https://github.com/MetaMask/metamask-extension/pull/26029))
- Fixed an issue with link redirection to ensure proper navigation ([#25983](https://github.com/MetaMask/metamask-extension/pull/25983))
From b5b8b8f660d3ba3ec44aa01531457d4433c93cb3 Mon Sep 17 00:00:00 2001
From: legobeat <109787230+legobeat@users.noreply.github.com>
Date: Tue, 8 Oct 2024 20:53:54 +0000
Subject: [PATCH 16/41] ci: make git-diff-develop work for PRs from foreign
repos (#27268)
The `gh` CLI requires authentication, even if the API endpoints do not.
We can just fetch the PR URL directly without shelling out.
Fixes [CI
error](https://app.circleci.com/pipelines/github/MetaMask/metamask-extension/101231/workflows/7b91edba-0c97-4075-934c-5db83a71a2c0/jobs/3769045).
Also removes dependency on `prep-deps` step by removing dependency on
external module.
---------
Co-authored-by: Howard Braham
---
.circleci/config.yml | 14 ++---
.circleci/scripts/git-diff-develop.ts | 82 ++++++++++++++++-----------
2 files changed, 55 insertions(+), 41 deletions(-)
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 095650aae02d..b2c5ab712973 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -118,11 +118,9 @@ workflows:
- prep-deps
- get-changed-files-with-git-diff:
filters:
- branches:
- ignore:
- - master
- requires:
- - prep-deps
+ branches:
+ ignore:
+ - master
- test-deps-audit:
requires:
- prep-deps
@@ -360,11 +358,10 @@ workflows:
value: << pipeline.git.branch >>
jobs:
- prep-deps
- - get-changed-files-with-git-diff:
- requires:
- - prep-deps
+ - get-changed-files-with-git-diff
- validate-locales-only:
requires:
+ - prep-deps
- get-changed-files-with-git-diff
- test-lint:
requires:
@@ -501,7 +498,6 @@ jobs:
- run: sudo corepack enable
- attach_workspace:
at: .
- - gh/install
- run:
name: Get changed files with git diff
command: npx tsx .circleci/scripts/git-diff-develop.ts
diff --git a/.circleci/scripts/git-diff-develop.ts b/.circleci/scripts/git-diff-develop.ts
index 3cf5022d4e12..9f6c8f0ae4df 100644
--- a/.circleci/scripts/git-diff-develop.ts
+++ b/.circleci/scripts/git-diff-develop.ts
@@ -1,4 +1,3 @@
-import { hasProperty } from '@metamask/utils';
import { exec as execCallback } from 'child_process';
import fs from 'fs';
import path from 'path';
@@ -6,24 +5,38 @@ import { promisify } from 'util';
const exec = promisify(execCallback);
+// The CIRCLE_PR_NUMBER variable is only available on forked Pull Requests
+const PR_NUMBER =
+ process.env.CIRCLE_PR_NUMBER ||
+ process.env.CIRCLE_PULL_REQUEST?.split('/').pop();
+
const MAIN_BRANCH = 'develop';
+const SOURCE_BRANCH = `refs/pull/${PR_NUMBER}/head`;
+
+const CHANGED_FILES_DIR = 'changed-files';
+
+type PRInfo = {
+ base: {
+ ref: string;
+ };
+ body: string;
+};
/**
- * Get the target branch for the given pull request.
+ * Get JSON info about the given pull request
*
- * @returns The name of the branch targeted by the PR.
+ * @returns JSON info from GitHub
*/
-async function getBaseRef(): Promise {
- if (!process.env.CIRCLE_PULL_REQUEST) {
+async function getPrInfo(): Promise {
+ if (!PR_NUMBER) {
return null;
}
- // We're referencing the CIRCLE_PULL_REQUEST environment variable within the script rather than
- // passing it in because this makes it easier to use Bash parameter expansion to extract the
- // PR number from the URL.
- const result = await exec(`gh pr view --json baseRefName "\${CIRCLE_PULL_REQUEST##*/}" --jq '.baseRefName'`);
- const baseRef = result.stdout.trim();
- return baseRef;
+ return await (
+ await fetch(
+ `https://api.github.com/repos/${process.env.CIRCLE_PROJECT_USERNAME}/${process.env.CIRCLE_PROJECT_REPONAME}/pulls/${PR_NUMBER}`,
+ )
+ ).json();
}
/**
@@ -34,8 +47,10 @@ async function getBaseRef(): Promise {
*/
async function fetchWithDepth(depth: number): Promise {
try {
- await exec(`git fetch --depth ${depth} origin develop`);
- await exec(`git fetch --depth ${depth} origin ${process.env.CIRCLE_BRANCH}`);
+ await exec(`git fetch --depth ${depth} origin "${MAIN_BRANCH}"`);
+ await exec(
+ `git fetch --depth ${depth} origin "${SOURCE_BRANCH}:${SOURCE_BRANCH}"`,
+ );
return true;
} catch (error: unknown) {
console.error(`Failed to fetch with depth ${depth}:`, error);
@@ -59,18 +74,16 @@ async function fetchUntilMergeBaseFound() {
await exec(`git merge-base origin/HEAD HEAD`);
return;
} catch (error: unknown) {
- if (
- error instanceof Error &&
- hasProperty(error, 'code') &&
- error.code === 1
- ) {
- console.error(`Error 'no merge base' encountered with depth ${depth}. Incrementing depth...`);
+ if (error instanceof Error && 'code' in error) {
+ console.error(
+ `Error 'no merge base' encountered with depth ${depth}. Incrementing depth...`,
+ );
} else {
throw error;
}
}
}
- await exec(`git fetch --unshallow origin develop`);
+ await exec(`git fetch --unshallow origin "${MAIN_BRANCH}"`);
}
/**
@@ -82,9 +95,11 @@ async function fetchUntilMergeBaseFound() {
*/
async function gitDiff(): Promise {
await fetchUntilMergeBaseFound();
- const { stdout: diffResult } = await exec(`git diff --name-only origin/HEAD...${process.env.CIRCLE_BRANCH}`);
+ const { stdout: diffResult } = await exec(
+ `git diff --name-only "origin/HEAD...${SOURCE_BRANCH}"`,
+ );
if (!diffResult) {
- throw new Error('Unable to get diff after full checkout.');
+ throw new Error('Unable to get diff after full checkout.');
}
return diffResult;
}
@@ -99,30 +114,33 @@ async function storeGitDiffOutput() {
// Create the directory
// This is done first because our CirleCI config requires that this directory is present,
// even if we want to skip this step.
- const outputDir = 'changed-files';
- fs.mkdirSync(outputDir, { recursive: true });
+ fs.mkdirSync(CHANGED_FILES_DIR, { recursive: true });
- console.log(`Determining whether this run is for a PR targetting ${MAIN_BRANCH}`)
- if (!process.env.CIRCLE_PULL_REQUEST) {
- console.log("Not a PR, skipping git diff");
+ console.log(
+ `Determining whether this run is for a PR targeting ${MAIN_BRANCH}`,
+ );
+ if (!PR_NUMBER) {
+ console.log('Not a PR, skipping git diff');
return;
}
- const baseRef = await getBaseRef();
- if (baseRef === null) {
- console.log("Not a PR, skipping git diff");
+ const prInfo = await getPrInfo();
+
+ const baseRef = prInfo?.base.ref;
+ if (!baseRef) {
+ console.log('Not a PR, skipping git diff');
return;
} else if (baseRef !== MAIN_BRANCH) {
console.log(`This is for a PR targeting '${baseRef}', skipping git diff`);
return;
}
- console.log("Attempting to get git diff...");
+ console.log('Attempting to get git diff...');
const diffOutput = await gitDiff();
console.log(diffOutput);
// Store the output of git diff
- const outputPath = path.resolve(outputDir, 'changed-files.txt');
+ const outputPath = path.resolve(CHANGED_FILES_DIR, 'changed-files.txt');
fs.writeFileSync(outputPath, diffOutput.trim());
console.log(`Git diff results saved to ${outputPath}`);
From b34484e515eab5f415d6744106de58d880aab8ff Mon Sep 17 00:00:00 2001
From: Nick Gambino <35090461+gambinish@users.noreply.github.com>
Date: Tue, 8 Oct 2024 15:20:36 -0700
Subject: [PATCH 17/41] feat: Sort/Import Tokens in Extension (#27184)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
### This PR adds Token sorting to the Asset List page, and also moves
Token importing to the top of the Token List. A few of the main changes
introduced:
1. Include `NativeToken` in `TokenList` component to be included in
sorting logic, and treated (as far as sorting is concerned) as any other
token in the list
2. Intoduce a `tokenSortConfig` into state that keeps track of the sort
order, the key being sorted by, and the direction of the sort order.
Also includes an action to update this state.
3. Introduce a `useEffect` that subscribes to `tokenSortConfig` as well
as a few other application state variables to update and sort tokenList
when appropriate.
2. Clean up `asset-list` component, and move some of it's relevant code
into the `useAccountTotalFiatBalance`
**Acceptance Criteria:**
1. Tokens should be sorted by default by declining balance
2. Sort controls should sort tokens alphabetically, and by decreasing
fiat token balance
3. Sort order should persist through refresh
4. Sort order should persist after app is closed and reopened
5. When a token gets imported, it should be included in the sort list,
in the correct order in the list
**A couple of disclaimers. There are still (at least) two bugs that I
discovered that were not caught by tests:**
1. ~~When toggling preferred currency setting, Native Token sorted
incorrectly by decreasing fiat balance~~ ✅ fixed
2. ~~When switching between accounts, token list does not update~~ ✅
fixed
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27184?quickstart=1)
## **Related issues**
Fixes: https://consensyssoftware.atlassian.net/browse/MMASSETS-356
## **Manual testing steps**
1. Go to AssetList page, and click dropdown and select option to sort by
2. Tokens should sort, and remain sorted through refresh and application
close/open (it is in state)
4. Importing tokens should import them into the sort order
## **Screenshots/Recordings**
https://github.com/user-attachments/assets/8ecca5e4-093f-4651-946e-31c612795427
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
.storybook/test-data.js | 5 +
app/_locales/en/messages.json | 10 +
app/scripts/controllers/metametrics.js | 2 +
app/scripts/controllers/metametrics.test.js | 26 ++
.../controllers/preferences-controller.ts | 10 +
app/scripts/migrations/130.test.ts | 91 ++++++
app/scripts/migrations/130.ts | 44 +++
app/scripts/migrations/index.js | 1 +
shared/constants/metametrics.ts | 5 +
test/data/mock-state.json | 7 +-
test/e2e/default-fixture.js | 5 +
test/e2e/fixture-builder.js | 5 +
...rs-after-init-opt-in-background-state.json | 2 +-
.../errors-after-init-opt-in-ui-state.json | 1 +
...s-before-init-opt-in-background-state.json | 7 +-
.../errors-before-init-opt-in-ui-state.json | 7 +-
test/e2e/tests/tokens/add-hide-token.spec.js | 2 +-
.../tokens/custom-token-add-approve.spec.js | 2 +-
.../tokens/custom-token-send-transfer.spec.js | 12 +
test/e2e/tests/tokens/token-details.spec.ts | 2 +-
test/e2e/tests/tokens/token-list.spec.ts | 2 +-
test/e2e/tests/tokens/token-sort.spec.ts | 111 ++++++++
.../tests/transaction/change-assets.spec.js | 2 +-
ui/components/app/app-components.scss | 2 +
.../asset-list-control-bar.tsx | 99 +++++++
.../asset-list-control-bar/index.scss | 8 +
.../asset-list-control-bar/index.ts | 1 +
.../app/assets/asset-list/asset-list.tsx | 145 ++--------
.../import-control/import-control.tsx | 63 +++++
.../assets/asset-list/import-control/index.ts | 1 +
.../assets/asset-list/native-token/index.ts | 1 +
.../asset-list/native-token/native-token.tsx | 59 ++++
.../native-token/use-native-token-balance.ts | 94 +++++++
.../assets/asset-list/sort-control/index.scss | 27 ++
.../assets/asset-list/sort-control/index.ts | 1 +
.../sort-control/sort-control.test.tsx | 119 ++++++++
.../asset-list/sort-control/sort-control.tsx | 116 ++++++++
.../app/assets/token-cell/token-cell.tsx | 2 +-
.../app/assets/token-list/token-list.tsx | 91 ++++--
ui/components/app/assets/util/sort.test.ts | 263 ++++++++++++++++++
ui/components/app/assets/util/sort.ts | 86 ++++++
.../account-overview-btc.test.tsx | 4 +-
.../import-token-link.test.js.snap | 28 --
.../import-token-link.test.js | 7 +-
.../import-token-link/import-token-link.tsx | 47 +---
.../multichain/ramps-card/index.scss | 5 +-
ui/css/design-system/_colors.scss | 2 +
ui/helpers/constants/design-system.ts | 2 +
ui/helpers/utils/common.util.js | 16 ++
ui/hooks/useAccountTotalFiatBalance.js | 42 ++-
ui/hooks/useAccountTotalFiatBalance.test.js | 10 +-
...MultichainAccountTotalFiatBalance.test.tsx | 4 +
ui/pages/routes/routes.component.test.js | 7 +
ui/store/actionConstants.ts | 2 +
ui/store/actions.ts | 10 +-
55 files changed, 1486 insertions(+), 239 deletions(-)
create mode 100644 app/scripts/migrations/130.test.ts
create mode 100644 app/scripts/migrations/130.ts
create mode 100644 test/e2e/tests/tokens/token-sort.spec.ts
create mode 100644 ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx
create mode 100644 ui/components/app/assets/asset-list/asset-list-control-bar/index.scss
create mode 100644 ui/components/app/assets/asset-list/asset-list-control-bar/index.ts
create mode 100644 ui/components/app/assets/asset-list/import-control/import-control.tsx
create mode 100644 ui/components/app/assets/asset-list/import-control/index.ts
create mode 100644 ui/components/app/assets/asset-list/native-token/index.ts
create mode 100644 ui/components/app/assets/asset-list/native-token/native-token.tsx
create mode 100644 ui/components/app/assets/asset-list/native-token/use-native-token-balance.ts
create mode 100644 ui/components/app/assets/asset-list/sort-control/index.scss
create mode 100644 ui/components/app/assets/asset-list/sort-control/index.ts
create mode 100644 ui/components/app/assets/asset-list/sort-control/sort-control.test.tsx
create mode 100644 ui/components/app/assets/asset-list/sort-control/sort-control.tsx
create mode 100644 ui/components/app/assets/util/sort.test.ts
create mode 100644 ui/components/app/assets/util/sort.ts
diff --git a/.storybook/test-data.js b/.storybook/test-data.js
index de94b69f857e..cbcebb6347ed 100644
--- a/.storybook/test-data.js
+++ b/.storybook/test-data.js
@@ -677,6 +677,11 @@ const state = {
currentLocale: 'en',
preferences: {
showNativeTokenAsMainBalance: true,
+ tokenSortConfig: {
+ key: 'token-sort-key',
+ order: 'dsc',
+ sortCallback: 'stringNumeric',
+ },
},
incomingTransactionsPreferences: {
[CHAIN_IDS.MAINNET]: true,
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index 30c913d1de74..60ec9579059d 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -5245,6 +5245,16 @@
"somethingWentWrong": {
"message": "Oops! Something went wrong."
},
+ "sortBy": {
+ "message": "Sort by"
+ },
+ "sortByAlphabetically": {
+ "message": "Alphabetically (A-Z)"
+ },
+ "sortByDecliningBalance": {
+ "message": "Declining balance ($1 high-low)",
+ "description": "Indicates a descending order based on token fiat balance. $1 is the preferred currency symbol"
+ },
"source": {
"message": "Source"
},
diff --git a/app/scripts/controllers/metametrics.js b/app/scripts/controllers/metametrics.js
index 28ced592fb9d..15f4fa9b7788 100644
--- a/app/scripts/controllers/metametrics.js
+++ b/app/scripts/controllers/metametrics.js
@@ -868,6 +868,8 @@ export default class MetaMetricsController {
metamaskState.participateInMetaMetrics,
[MetaMetricsUserTrait.HasMarketingConsent]:
metamaskState.dataCollectionForMarketing,
+ [MetaMetricsUserTrait.TokenSortPreference]:
+ metamaskState.tokenSortConfig?.key || '',
};
if (!previousUserTraits) {
diff --git a/app/scripts/controllers/metametrics.test.js b/app/scripts/controllers/metametrics.test.js
index 3d4845e056d0..a0505700ef01 100644
--- a/app/scripts/controllers/metametrics.test.js
+++ b/app/scripts/controllers/metametrics.test.js
@@ -1122,6 +1122,11 @@ describe('MetaMetricsController', function () {
},
},
},
+ tokenSortConfig: {
+ key: 'token-sort-key',
+ order: 'dsc',
+ sortCallback: 'stringNumeric',
+ },
});
expect(traits).toStrictEqual({
@@ -1153,6 +1158,7 @@ describe('MetaMetricsController', function () {
///: BEGIN:ONLY_INCLUDE_IF(petnames)
[MetaMetricsUserTrait.PetnameAddressCount]: 3,
///: END:ONLY_INCLUDE_IF
+ [MetaMetricsUserTrait.TokenSortPreference]: 'token-sort-key',
});
});
@@ -1181,6 +1187,11 @@ describe('MetaMetricsController', function () {
useNftDetection: false,
theme: 'default',
useTokenDetection: true,
+ tokenSortConfig: {
+ key: 'token-sort-key',
+ order: 'dsc',
+ sortCallback: 'stringNumeric',
+ },
showNativeTokenAsMainBalance: true,
});
@@ -1208,6 +1219,11 @@ describe('MetaMetricsController', function () {
useNftDetection: false,
theme: 'default',
useTokenDetection: true,
+ tokenSortConfig: {
+ key: 'token-sort-key',
+ order: 'dsc',
+ sortCallback: 'stringNumeric',
+ },
showNativeTokenAsMainBalance: false,
});
@@ -1245,6 +1261,11 @@ describe('MetaMetricsController', function () {
useNftDetection: true,
theme: 'default',
useTokenDetection: true,
+ tokenSortConfig: {
+ key: 'token-sort-key',
+ order: 'dsc',
+ sortCallback: 'stringNumeric',
+ },
showNativeTokenAsMainBalance: true,
});
@@ -1267,6 +1288,11 @@ describe('MetaMetricsController', function () {
useNftDetection: true,
theme: 'default',
useTokenDetection: true,
+ tokenSortConfig: {
+ key: 'token-sort-key',
+ order: 'dsc',
+ sortCallback: 'stringNumeric',
+ },
showNativeTokenAsMainBalance: true,
});
expect(updatedTraits).toStrictEqual(null);
diff --git a/app/scripts/controllers/preferences-controller.ts b/app/scripts/controllers/preferences-controller.ts
index a158ac0024d4..eb126b176a41 100644
--- a/app/scripts/controllers/preferences-controller.ts
+++ b/app/scripts/controllers/preferences-controller.ts
@@ -106,6 +106,11 @@ export type Preferences = {
showMultiRpcModal: boolean;
isRedesignedConfirmationsDeveloperEnabled: boolean;
showConfirmationAdvancedDetails: boolean;
+ tokenSortConfig: {
+ key: string;
+ order: string;
+ sortCallback: string;
+ };
shouldShowAggregatedBalancePopover: boolean;
};
@@ -237,6 +242,11 @@ export default class PreferencesController {
showMultiRpcModal: false,
isRedesignedConfirmationsDeveloperEnabled: false,
showConfirmationAdvancedDetails: false,
+ tokenSortConfig: {
+ key: 'tokenFiatAmount',
+ order: 'dsc',
+ sortCallback: 'stringNumeric',
+ },
shouldShowAggregatedBalancePopover: true, // by default user should see popover;
},
// ENS decentralized website resolution
diff --git a/app/scripts/migrations/130.test.ts b/app/scripts/migrations/130.test.ts
new file mode 100644
index 000000000000..94e00949c7a1
--- /dev/null
+++ b/app/scripts/migrations/130.test.ts
@@ -0,0 +1,91 @@
+import { migrate, version } from './130';
+
+const oldVersion = 129;
+
+describe(`migration #${version}`, () => {
+ it('updates the version metadata', async () => {
+ const oldStorage = {
+ meta: { version: oldVersion },
+ data: {},
+ };
+ const newStorage = await migrate(oldStorage);
+ expect(newStorage.meta).toStrictEqual({ version });
+ });
+ describe(`migration #${version}`, () => {
+ it('updates the preferences with a default tokenSortConfig', async () => {
+ const oldStorage = {
+ meta: { version: oldVersion },
+ data: {
+ PreferencesController: {
+ preferences: {},
+ },
+ },
+ };
+ const expectedData = {
+ PreferencesController: {
+ preferences: {
+ tokenSortConfig: {
+ key: 'tokenFiatAmount',
+ order: 'dsc',
+ sortCallback: 'stringNumeric',
+ },
+ },
+ },
+ };
+ const newStorage = await migrate(oldStorage);
+
+ expect(newStorage.data).toStrictEqual(expectedData);
+ });
+
+ it('does nothing if the preferences already has a tokenSortConfig', async () => {
+ const oldStorage = {
+ meta: { version: oldVersion },
+ data: {
+ PreferencesController: {
+ preferences: {
+ tokenSortConfig: {
+ key: 'fooKey',
+ order: 'foo',
+ sortCallback: 'fooCallback',
+ },
+ },
+ },
+ },
+ };
+
+ const newStorage = await migrate(oldStorage);
+
+ expect(newStorage.data).toStrictEqual(oldStorage.data);
+ });
+
+ it('does nothing to other preferences if they exist without a tokenSortConfig', async () => {
+ const oldStorage = {
+ meta: { version: oldVersion },
+ data: {
+ PreferencesController: {
+ preferences: {
+ existingPreference: true,
+ },
+ },
+ },
+ };
+
+ const expectedData = {
+ PreferencesController: {
+ preferences: {
+ existingPreference: true,
+ tokenSortConfig: {
+ key: 'tokenFiatAmount',
+ order: 'dsc',
+ sortCallback: 'stringNumeric',
+ },
+ },
+ },
+ };
+
+ const newStorage = await migrate(oldStorage);
+
+ expect(newStorage.data).toStrictEqual(expectedData);
+ });
+ });
+});
diff --git a/app/scripts/migrations/130.ts b/app/scripts/migrations/130.ts
new file mode 100644
index 000000000000..ccf376ce1e7e
--- /dev/null
+++ b/app/scripts/migrations/130.ts
@@ -0,0 +1,44 @@
+import { hasProperty, isObject } from '@metamask/utils';
+import { cloneDeep } from 'lodash';
+
+type VersionedData = {
+ meta: { version: number };
+ data: Record;
+};
+export const version = 130;
+/**
+ * This migration adds a tokenSortConfig to the user's preferences
+ *
+ *
+ * @param originalVersionedData - Versioned MetaMask extension state, exactly what we persist to dist.
+ * @param originalVersionedData.meta - State metadata.
+ * @param originalVersionedData.meta.version - The current state version.
+ * @param originalVersionedData.data - The persisted MetaMask state, keyed by controller.
+ * @returns Updated versioned MetaMask extension state.
+ */
+export async function migrate(
+ originalVersionedData: VersionedData,
+): Promise {
+ const versionedData = cloneDeep(originalVersionedData);
+ versionedData.meta.version = version;
+ transformState(versionedData.data);
+ return versionedData;
+}
+function transformState(
+ state: Record,
+): Record {
+ if (
+ hasProperty(state, 'PreferencesController') &&
+ isObject(state.PreferencesController) &&
+ hasProperty(state.PreferencesController, 'preferences') &&
+ isObject(state.PreferencesController.preferences) &&
+ !state.PreferencesController.preferences.tokenSortConfig
+ ) {
+ state.PreferencesController.preferences.tokenSortConfig = {
+ key: 'tokenFiatAmount',
+ order: 'dsc',
+ sortCallback: 'stringNumeric',
+ };
+ }
+ return state;
+}
diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js
index 296ff8077613..93a862b5ee02 100644
--- a/app/scripts/migrations/index.js
+++ b/app/scripts/migrations/index.js
@@ -149,6 +149,7 @@ const migrations = [
require('./127'),
require('./128'),
require('./129'),
+ require('./130'),
];
export default migrations;
diff --git a/shared/constants/metametrics.ts b/shared/constants/metametrics.ts
index d0f1cfb87cbe..8faf7c7bfb79 100644
--- a/shared/constants/metametrics.ts
+++ b/shared/constants/metametrics.ts
@@ -472,6 +472,10 @@ export enum MetaMetricsUserTrait {
* Identified when the user selects a currency from settings
*/
CurrentCurrency = 'current_currency',
+ /**
+ * Identified when the user changes token sort order on asset-list
+ */
+ TokenSortPreference = 'token_sort_preference',
}
/**
@@ -630,6 +634,7 @@ export enum MetaMetricsEventName {
TokenScreenOpened = 'Token Screen Opened',
TokenAdded = 'Token Added',
TokenRemoved = 'Token Removed',
+ TokenSortPreference = 'Token Sort Preference',
NFTRemoved = 'NFT Removed',
TokenDetected = 'Token Detected',
TokenHidden = 'Token Hidden',
diff --git a/test/data/mock-state.json b/test/data/mock-state.json
index 32a61c573500..654e915a1305 100644
--- a/test/data/mock-state.json
+++ b/test/data/mock-state.json
@@ -372,7 +372,12 @@
"showFiatInTestnets": false,
"showNativeTokenAsMainBalance": true,
"showTestNetworks": true,
- "smartTransactionsOptInStatus": false
+ "smartTransactionsOptInStatus": false,
+ "tokenSortConfig": {
+ "key": "tokenFiatAmount",
+ "order": "dsc",
+ "sortCallback": "stringNumeric"
+ }
},
"ensResolutionsByAddress": {},
"isAccountMenuOpen": false,
diff --git a/test/e2e/default-fixture.js b/test/e2e/default-fixture.js
index 83b8b29a5e83..2c0dfe9a23cb 100644
--- a/test/e2e/default-fixture.js
+++ b/test/e2e/default-fixture.js
@@ -215,6 +215,11 @@ function defaultFixture(inputChainId = CHAIN_IDS.LOCALHOST) {
showMultiRpcModal: false,
isRedesignedConfirmationsDeveloperEnabled: false,
showConfirmationAdvancedDetails: false,
+ tokenSortConfig: {
+ key: 'tokenFiatAmount',
+ order: 'dsc',
+ sortCallback: 'stringNumeric',
+ },
shouldShowAggregatedBalancePopover: true,
},
selectedAddress: '0x5cfe73b6021e818b776b421b1c4db2474086a7e1',
diff --git a/test/e2e/fixture-builder.js b/test/e2e/fixture-builder.js
index 415af23071e7..f1e9a7e5ae1d 100644
--- a/test/e2e/fixture-builder.js
+++ b/test/e2e/fixture-builder.js
@@ -77,6 +77,11 @@ function onboardingFixture() {
showMultiRpcModal: false,
isRedesignedConfirmationsDeveloperEnabled: false,
showConfirmationAdvancedDetails: false,
+ tokenSortConfig: {
+ key: 'tokenFiatAmount',
+ order: 'dsc',
+ sortCallback: 'stringNumeric',
+ },
shouldShowAggregatedBalancePopover: true,
},
useExternalServices: true,
diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json
index 8d8c8c1ae895..559e8a256d43 100644
--- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json
+++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-background-state.json
@@ -215,7 +215,7 @@
"isRedesignedConfirmationsDeveloperEnabled": "boolean",
"redesignedConfirmationsEnabled": true,
"redesignedTransactionsEnabled": "boolean",
- "showMultiRpcModal": "boolean",
+ "tokenSortConfig": "object",
"shouldShowAggregatedBalancePopover": "boolean"
},
"ipfsGateway": "string",
diff --git a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json
index b1131ec4e7a2..2df9ee4e2f23 100644
--- a/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json
+++ b/test/e2e/tests/metrics/state-snapshots/errors-after-init-opt-in-ui-state.json
@@ -37,6 +37,7 @@
"isRedesignedConfirmationsDeveloperEnabled": "boolean",
"redesignedConfirmationsEnabled": true,
"redesignedTransactionsEnabled": "boolean",
+ "tokenSortConfig": "object",
"showMultiRpcModal": "boolean",
"shouldShowAggregatedBalancePopover": "boolean"
},
diff --git a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json
index f40b2687316b..d22b69967027 100644
--- a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json
+++ b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-background-state.json
@@ -80,11 +80,11 @@
},
"NetworkController": {
"selectedNetworkClientId": "string",
+ "networkConfigurations": "object",
"networksMetadata": {
"networkConfigurationId": { "EIPS": {}, "status": "available" }
},
- "providerConfig": "object",
- "networkConfigurations": "object"
+ "providerConfig": "object"
},
"OnboardingController": {
"completedOnboarding": true,
@@ -114,8 +114,9 @@
"smartTransactionsOptInStatus": false,
"showNativeTokenAsMainBalance": true,
"petnamesEnabled": true,
- "showConfirmationAdvancedDetails": false,
"isRedesignedConfirmationsDeveloperEnabled": "boolean",
+ "showConfirmationAdvancedDetails": false,
+ "tokenSortConfig": "object",
"showMultiRpcModal": "boolean",
"shouldShowAggregatedBalancePopover": "boolean"
},
diff --git a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json
index 3c692fa59405..2dfd6ac6ef21 100644
--- a/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json
+++ b/test/e2e/tests/metrics/state-snapshots/errors-before-init-opt-in-ui-state.json
@@ -80,11 +80,11 @@
},
"NetworkController": {
"selectedNetworkClientId": "string",
+ "networkConfigurations": "object",
"networksMetadata": {
"networkConfigurationId": { "EIPS": {}, "status": "available" }
},
- "providerConfig": "object",
- "networkConfigurations": "object"
+ "providerConfig": "object"
},
"OnboardingController": {
"completedOnboarding": true,
@@ -114,8 +114,9 @@
"smartTransactionsOptInStatus": false,
"showNativeTokenAsMainBalance": true,
"petnamesEnabled": true,
- "showConfirmationAdvancedDetails": false,
"isRedesignedConfirmationsDeveloperEnabled": "boolean",
+ "showConfirmationAdvancedDetails": false,
+ "tokenSortConfig": "object",
"showMultiRpcModal": "boolean",
"shouldShowAggregatedBalancePopover": "boolean"
},
diff --git a/test/e2e/tests/tokens/add-hide-token.spec.js b/test/e2e/tests/tokens/add-hide-token.spec.js
index a13ef9caa2b5..535948ba1c9b 100644
--- a/test/e2e/tests/tokens/add-hide-token.spec.js
+++ b/test/e2e/tests/tokens/add-hide-token.spec.js
@@ -119,7 +119,7 @@ describe('Add existing token using search', function () {
async ({ driver }) => {
await unlockWallet(driver);
- await driver.clickElement({ text: 'Import tokens', tag: 'button' });
+ await driver.clickElement({ text: 'Import', tag: 'button' });
await driver.fill('input[placeholder="Search tokens"]', 'BAT');
await driver.clickElement({
text: 'BAT',
diff --git a/test/e2e/tests/tokens/custom-token-add-approve.spec.js b/test/e2e/tests/tokens/custom-token-add-approve.spec.js
index a9cf1829a808..7a59243da403 100644
--- a/test/e2e/tests/tokens/custom-token-add-approve.spec.js
+++ b/test/e2e/tests/tokens/custom-token-add-approve.spec.js
@@ -35,7 +35,7 @@ describe('Create token, approve token and approve token without gas', function (
);
await clickNestedButton(driver, 'Tokens');
- await driver.clickElement({ text: 'Import tokens', tag: 'button' });
+ await driver.clickElement({ text: 'Import', tag: 'button' });
await clickNestedButton(driver, 'Custom token');
await driver.fill(
'[data-testid="import-tokens-modal-custom-address"]',
diff --git a/test/e2e/tests/tokens/custom-token-send-transfer.spec.js b/test/e2e/tests/tokens/custom-token-send-transfer.spec.js
index de2aa2addcf8..40b1872011bd 100644
--- a/test/e2e/tests/tokens/custom-token-send-transfer.spec.js
+++ b/test/e2e/tests/tokens/custom-token-send-transfer.spec.js
@@ -136,6 +136,12 @@ describe('Transfer custom tokens @no-mmi', function () {
text: '-1.5 TST',
});
+ // this selector helps prevent flakiness. it allows driver to wait until send transfer is "confirmed"
+ await driver.waitForSelector({
+ text: 'Confirmed',
+ tag: 'div',
+ });
+
// check token amount is correct after transaction
await clickNestedButton(driver, 'Tokens');
const tokenAmount = await driver.findElement(
@@ -192,6 +198,12 @@ describe('Transfer custom tokens @no-mmi', function () {
text: 'Send TST',
});
+ // this selector helps prevent flakiness. it allows driver to wait until send transfer is "confirmed"
+ await driver.waitForSelector({
+ text: 'Confirmed',
+ tag: 'div',
+ });
+
// check token amount is correct after transaction
await clickNestedButton(driver, 'Tokens');
const tokenAmount = await driver.findElement(
diff --git a/test/e2e/tests/tokens/token-details.spec.ts b/test/e2e/tests/tokens/token-details.spec.ts
index 349c273c721c..0d577ab20f19 100644
--- a/test/e2e/tests/tokens/token-details.spec.ts
+++ b/test/e2e/tests/tokens/token-details.spec.ts
@@ -27,7 +27,7 @@ describe('Token Details', function () {
};
const importToken = async (driver: Driver) => {
- await driver.clickElement({ text: 'Import tokens', tag: 'button' });
+ await driver.clickElement({ text: 'Import', tag: 'button' });
await clickNestedButton(driver, 'Custom token');
await driver.fill(
'[data-testid="import-tokens-modal-custom-address"]',
diff --git a/test/e2e/tests/tokens/token-list.spec.ts b/test/e2e/tests/tokens/token-list.spec.ts
index 32b5ea85e3ae..bffef04c40dd 100644
--- a/test/e2e/tests/tokens/token-list.spec.ts
+++ b/test/e2e/tests/tokens/token-list.spec.ts
@@ -27,7 +27,7 @@ describe('Token List', function () {
};
const importToken = async (driver: Driver) => {
- await driver.clickElement({ text: 'Import tokens', tag: 'button' });
+ await driver.clickElement({ text: 'Import', tag: 'button' });
await clickNestedButton(driver, 'Custom token');
await driver.fill(
'[data-testid="import-tokens-modal-custom-address"]',
diff --git a/test/e2e/tests/tokens/token-sort.spec.ts b/test/e2e/tests/tokens/token-sort.spec.ts
new file mode 100644
index 000000000000..e0d335ee0fd6
--- /dev/null
+++ b/test/e2e/tests/tokens/token-sort.spec.ts
@@ -0,0 +1,111 @@
+import { strict as assert } from 'assert';
+import { Context } from 'mocha';
+import { CHAIN_IDS } from '../../../../shared/constants/network';
+import FixtureBuilder from '../../fixture-builder';
+import {
+ clickNestedButton,
+ defaultGanacheOptions,
+ regularDelayMs,
+ unlockWallet,
+ withFixtures,
+} from '../../helpers';
+import { Driver } from '../../webdriver/driver';
+
+describe('Token List', function () {
+ const chainId = CHAIN_IDS.MAINNET;
+ const tokenAddress = '0x2EFA2Cb29C2341d8E5Ba7D3262C9e9d6f1Bf3711';
+ const symbol = 'ABC';
+
+ const fixtures = {
+ fixtures: new FixtureBuilder({ inputChainId: chainId }).build(),
+ ganacheOptions: {
+ ...defaultGanacheOptions,
+ chainId: parseInt(chainId, 16),
+ },
+ };
+
+ const importToken = async (driver: Driver) => {
+ await driver.clickElement({ text: 'Import', tag: 'button' });
+ await clickNestedButton(driver, 'Custom token');
+ await driver.fill(
+ '[data-testid="import-tokens-modal-custom-address"]',
+ tokenAddress,
+ );
+ await driver.waitForSelector('p.mm-box--color-error-default');
+ await driver.fill(
+ '[data-testid="import-tokens-modal-custom-symbol"]',
+ symbol,
+ );
+ await driver.delay(2000);
+ await driver.clickElement({ text: 'Next', tag: 'button' });
+ await driver.clickElement(
+ '[data-testid="import-tokens-modal-import-button"]',
+ );
+ await driver.findElement({ text: 'Token imported', tag: 'h6' });
+ };
+
+ it('should sort alphabetically and by decreasing balance', async function () {
+ await withFixtures(
+ {
+ ...fixtures,
+ title: (this as Context).test?.fullTitle(),
+ },
+ async ({ driver }: { driver: Driver }) => {
+ await unlockWallet(driver);
+ await importToken(driver);
+
+ const tokenListBeforeSorting = await driver.findElements(
+ '[data-testid="multichain-token-list-button"]',
+ );
+ const tokenSymbolsBeforeSorting = await Promise.all(
+ tokenListBeforeSorting.map(async (tokenElement) => {
+ return tokenElement.getText();
+ }),
+ );
+
+ assert.ok(tokenSymbolsBeforeSorting[0].includes('Ethereum'));
+
+ await await driver.clickElement(
+ '[data-testid="sort-by-popover-toggle"]',
+ );
+ await await driver.clickElement('[data-testid="sortByAlphabetically"]');
+
+ await driver.delay(regularDelayMs);
+ const tokenListAfterSortingAlphabetically = await driver.findElements(
+ '[data-testid="multichain-token-list-button"]',
+ );
+ const tokenListSymbolsAfterSortingAlphabetically = await Promise.all(
+ tokenListAfterSortingAlphabetically.map(async (tokenElement) => {
+ return tokenElement.getText();
+ }),
+ );
+
+ assert.ok(
+ tokenListSymbolsAfterSortingAlphabetically[0].includes('ABC'),
+ );
+
+ await await driver.clickElement(
+ '[data-testid="sort-by-popover-toggle"]',
+ );
+ await await driver.clickElement(
+ '[data-testid="sortByDecliningBalance"]',
+ );
+
+ await driver.delay(regularDelayMs);
+ const tokenListBeforeSortingByDecliningBalance =
+ await driver.findElements(
+ '[data-testid="multichain-token-list-button"]',
+ );
+
+ const tokenListAfterSortingByDecliningBalance = await Promise.all(
+ tokenListBeforeSortingByDecliningBalance.map(async (tokenElement) => {
+ return tokenElement.getText();
+ }),
+ );
+ assert.ok(
+ tokenListAfterSortingByDecliningBalance[0].includes('Ethereum'),
+ );
+ },
+ );
+ });
+});
diff --git a/test/e2e/tests/transaction/change-assets.spec.js b/test/e2e/tests/transaction/change-assets.spec.js
index 11bb7489a829..7ce971fd8d80 100644
--- a/test/e2e/tests/transaction/change-assets.spec.js
+++ b/test/e2e/tests/transaction/change-assets.spec.js
@@ -342,7 +342,7 @@ describe('Change assets', function () {
// Make sure gas is updated by resetting amount and hex data
// Note: this is needed until the race condition is fixed on the wallet level (issue #25243)
- await driver.fill('[data-testid="currency-input"]', '2');
+ await driver.fill('[data-testid="currency-input"]', '2.000042');
await hexDataLocator.fill('0x');
await hexDataLocator.fill('');
diff --git a/ui/components/app/app-components.scss b/ui/components/app/app-components.scss
index a9f65cad0714..900c49731594 100644
--- a/ui/components/app/app-components.scss
+++ b/ui/components/app/app-components.scss
@@ -53,6 +53,8 @@
@import 'srp-input/srp-input';
@import 'snaps/snap-privacy-warning/index';
@import 'tab-bar/index';
+@import 'assets/asset-list/asset-list-control-bar/index';
+@import 'assets/asset-list/sort-control/index';
@import 'assets/token-cell/token-cell';
@import 'assets/token-list-display/token-list-display';
@import 'transaction-activity-log/index';
diff --git a/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx b/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx
new file mode 100644
index 000000000000..696c3ca7c89f
--- /dev/null
+++ b/ui/components/app/assets/asset-list/asset-list-control-bar/asset-list-control-bar.tsx
@@ -0,0 +1,99 @@
+import React, { useRef, useState } from 'react';
+import {
+ Box,
+ ButtonBase,
+ ButtonBaseSize,
+ IconName,
+ Popover,
+ PopoverPosition,
+} from '../../../../component-library';
+import SortControl from '../sort-control';
+import {
+ BackgroundColor,
+ BorderColor,
+ BorderStyle,
+ Display,
+ JustifyContent,
+ TextColor,
+} from '../../../../../helpers/constants/design-system';
+import ImportControl from '../import-control';
+import { useI18nContext } from '../../../../../hooks/useI18nContext';
+// TODO: Remove restricted import
+// eslint-disable-next-line import/no-restricted-paths
+import { getEnvironmentType } from '../../../../../../app/scripts/lib/util';
+import {
+ ENVIRONMENT_TYPE_NOTIFICATION,
+ ENVIRONMENT_TYPE_POPUP,
+} from '../../../../../../shared/constants/app';
+
+type AssetListControlBarProps = {
+ showTokensLinks?: boolean;
+};
+
+const AssetListControlBar = ({ showTokensLinks }: AssetListControlBarProps) => {
+ const t = useI18nContext();
+ const controlBarRef = useRef(null); // Create a ref
+ const [isPopoverOpen, setIsPopoverOpen] = useState(false);
+
+ const windowType = getEnvironmentType();
+ const isFullScreen =
+ windowType !== ENVIRONMENT_TYPE_NOTIFICATION &&
+ windowType !== ENVIRONMENT_TYPE_POPUP;
+
+ const handleOpenPopover = () => {
+ setIsPopoverOpen(!isPopoverOpen);
+ };
+
+ const closePopover = () => {
+ setIsPopoverOpen(false);
+ };
+
+ return (
+
+
+ {t('sortBy')}
+
+
+
+
+
+
+ );
+};
+
+export default AssetListControlBar;
diff --git a/ui/components/app/assets/asset-list/asset-list-control-bar/index.scss b/ui/components/app/assets/asset-list/asset-list-control-bar/index.scss
new file mode 100644
index 000000000000..3ed7ae082766
--- /dev/null
+++ b/ui/components/app/assets/asset-list/asset-list-control-bar/index.scss
@@ -0,0 +1,8 @@
+.asset-list-control-bar {
+ padding-top: 8px;
+ padding-bottom: 8px;
+
+ &__button:hover {
+ background-color: var(--color-background-hover);
+ }
+}
diff --git a/ui/components/app/assets/asset-list/asset-list-control-bar/index.ts b/ui/components/app/assets/asset-list/asset-list-control-bar/index.ts
new file mode 100644
index 000000000000..c9eff91c6fcf
--- /dev/null
+++ b/ui/components/app/assets/asset-list/asset-list-control-bar/index.ts
@@ -0,0 +1 @@
+export { default } from './asset-list-control-bar';
diff --git a/ui/components/app/assets/asset-list/asset-list.tsx b/ui/components/app/assets/asset-list/asset-list.tsx
index a84ec99037f9..5cfeb6803875 100644
--- a/ui/components/app/assets/asset-list/asset-list.tsx
+++ b/ui/components/app/assets/asset-list/asset-list.tsx
@@ -1,22 +1,15 @@
import React, { useContext, useState } from 'react';
import { useSelector } from 'react-redux';
import TokenList from '../token-list';
-import { PRIMARY, SECONDARY } from '../../../../helpers/constants/common';
+import { PRIMARY } from '../../../../helpers/constants/common';
import { useUserPreferencedCurrency } from '../../../../hooks/useUserPreferencedCurrency';
import {
getDetectedTokensInCurrentNetwork,
getIstokenDetectionInactiveOnNonMainnetSupportedNetwork,
- getShouldHideZeroBalanceTokens,
getSelectedAccount,
- getPreferences,
} from '../../../../selectors';
import {
- getMultichainCurrentNetwork,
- getMultichainNativeCurrency,
getMultichainIsEvm,
- getMultichainShouldShowFiat,
- getMultichainCurrencyImage,
- getMultichainIsMainnet,
getMultichainSelectedAccountCachedBalance,
///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask)
getMultichainIsBitcoin,
@@ -32,14 +25,10 @@ import {
import DetectedToken from '../../detected-token/detected-token';
import {
DetectedTokensBanner,
- TokenListItem,
ImportTokenLink,
ReceiveModal,
} from '../../../multichain';
-import { useAccountTotalFiatBalance } from '../../../../hooks/useAccountTotalFiatBalance';
-import { useIsOriginalNativeTokenSymbol } from '../../../../hooks/useIsOriginalNativeTokenSymbol';
import { useI18nContext } from '../../../../hooks/useI18nContext';
-import { roundToDecimalPlacesRemovingExtraZeroes } from '../../../../helpers/utils/util';
import { FundingMethodModal } from '../../../multichain/funding-method-modal/funding-method-modal';
///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask)
import {
@@ -48,42 +37,30 @@ import {
} from '../../../multichain/ramps-card/ramps-card';
import { getIsNativeTokenBuyable } from '../../../../ducks/ramps';
///: END:ONLY_INCLUDE_IF
+import AssetListControlBar from './asset-list-control-bar';
+import NativeToken from './native-token';
export type TokenWithBalance = {
address: string;
symbol: string;
- string: string;
+ string?: string;
image: string;
+ secondary?: string;
+ tokenFiatAmount?: string;
+ isNative?: boolean;
};
-type AssetListProps = {
+export type AssetListProps = {
onClickAsset: (arg: string) => void;
- showTokensLinks: boolean;
+ showTokensLinks?: boolean;
};
const AssetList = ({ onClickAsset, showTokensLinks }: AssetListProps) => {
const [showDetectedTokens, setShowDetectedTokens] = useState(false);
- const nativeCurrency = useSelector(getMultichainNativeCurrency);
- const showFiat = useSelector(getMultichainShouldShowFiat);
- const isMainnet = useSelector(getMultichainIsMainnet);
- const { showNativeTokenAsMainBalance } = useSelector(getPreferences);
- const { chainId, ticker, type, rpcUrl } = useSelector(
- getMultichainCurrentNetwork,
- );
- const isOriginalNativeSymbol = useIsOriginalNativeTokenSymbol(
- chainId,
- ticker,
- type,
- rpcUrl,
- );
+ const selectedAccount = useSelector(getSelectedAccount);
const t = useI18nContext();
const trackEvent = useContext(MetaMetricsContext);
const balance = useSelector(getMultichainSelectedAccountCachedBalance);
- const balanceIsLoading = !balance;
- const selectedAccount = useSelector(getSelectedAccount);
- const shouldHideZeroBalanceTokens = useSelector(
- getShouldHideZeroBalanceTokens,
- );
const {
currency: primaryCurrency,
@@ -92,27 +69,12 @@ const AssetList = ({ onClickAsset, showTokensLinks }: AssetListProps) => {
ethNumberOfDecimals: 4,
shouldCheckShowNativeToken: true,
});
- const {
- currency: secondaryCurrency,
- numberOfDecimals: secondaryNumberOfDecimals,
- } = useUserPreferencedCurrency(SECONDARY, {
- ethNumberOfDecimals: 4,
- shouldCheckShowNativeToken: true,
- });
- const [primaryCurrencyDisplay, primaryCurrencyProperties] =
- useCurrencyDisplay(balance, {
- numberOfDecimals: primaryNumberOfDecimals,
- currency: primaryCurrency,
- });
-
- const [secondaryCurrencyDisplay, secondaryCurrencyProperties] =
- useCurrencyDisplay(balance, {
- numberOfDecimals: secondaryNumberOfDecimals,
- currency: secondaryCurrency,
- });
+ const [, primaryCurrencyProperties] = useCurrencyDisplay(balance, {
+ numberOfDecimals: primaryNumberOfDecimals,
+ currency: primaryCurrency,
+ });
- const primaryTokenImage = useSelector(getMultichainCurrencyImage);
const detectedTokens = useSelector(getDetectedTokensInCurrentNetwork) || [];
const isTokenDetectionInactiveOnNonMainnetSupportedNetwork = useSelector(
getIstokenDetectionInactiveOnNonMainnetSupportedNetwork,
@@ -126,23 +88,6 @@ const AssetList = ({ onClickAsset, showTokensLinks }: AssetListProps) => {
setShowReceiveModal(true);
};
- const accountTotalFiatBalance = useAccountTotalFiatBalance(
- selectedAccount,
- shouldHideZeroBalanceTokens,
- );
-
- const tokensWithBalances =
- accountTotalFiatBalance.tokensWithBalances as TokenWithBalance[];
-
- const { loading } = accountTotalFiatBalance;
-
- tokensWithBalances.forEach((token) => {
- token.string = roundToDecimalPlacesRemovingExtraZeroes(
- token.string,
- 5,
- ) as string;
- });
-
const balanceIsZero = useSelector(
getMultichainSelectedAccountCachedBalanceIsZero,
);
@@ -150,6 +95,7 @@ const AssetList = ({ onClickAsset, showTokensLinks }: AssetListProps) => {
///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask)
const isBuyableChain = useSelector(getIsNativeTokenBuyable);
const shouldShowBuy = isBuyableChain && balanceIsZero;
+ const isBtc = useSelector(getMultichainIsBitcoin);
///: END:ONLY_INCLUDE_IF
const isEvm = useSelector(getMultichainIsEvm);
@@ -157,15 +103,6 @@ const AssetList = ({ onClickAsset, showTokensLinks }: AssetListProps) => {
// for EVM assets
const shouldShowTokensLinks = showTokensLinks ?? isEvm;
- ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask)
- const isBtc = useSelector(getMultichainIsBitcoin);
- ///: END:ONLY_INCLUDE_IF
-
- let isStakeable = isMainnet && isEvm;
- ///: BEGIN:ONLY_INCLUDE_IF(build-mmi)
- isStakeable = false;
- ///: END:ONLY_INCLUDE_IF
-
return (
<>
{detectedTokens.length > 0 &&
@@ -176,6 +113,21 @@ const AssetList = ({ onClickAsset, showTokensLinks }: AssetListProps) => {
margin={4}
/>
)}
+
+ }
+ onTokenClick={(tokenAddress: string) => {
+ onClickAsset(tokenAddress);
+ trackEvent({
+ event: MetaMetricsEventName.TokenScreenOpened,
+ category: MetaMetricsEventCategory.Navigation,
+ properties: {
+ token_symbol: primaryCurrencyProperties.suffix,
+ location: 'Home',
+ },
+ });
+ }}
+ />
{
///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask)
shouldShowBuy ? (
@@ -192,43 +144,6 @@ const AssetList = ({ onClickAsset, showTokensLinks }: AssetListProps) => {
) : null
///: END:ONLY_INCLUDE_IF
}
- onClickAsset(nativeCurrency)}
- title={nativeCurrency}
- // The primary and secondary currencies are subject to change based on the user's settings
- // TODO: rename this primary/secondary concept here to be more intuitive, regardless of setting
- primary={isOriginalNativeSymbol ? secondaryCurrencyDisplay : undefined}
- tokenSymbol={
- showNativeTokenAsMainBalance
- ? primaryCurrencyProperties.suffix
- : secondaryCurrencyProperties.suffix
- }
- secondary={
- showFiat && isOriginalNativeSymbol
- ? primaryCurrencyDisplay
- : undefined
- }
- tokenImage={balanceIsLoading ? null : primaryTokenImage}
- isOriginalTokenSymbol={isOriginalNativeSymbol}
- isNativeCurrency
- isStakeable={isStakeable}
- showPercentage
- />
- {
- onClickAsset(tokenAddress);
- trackEvent({
- event: MetaMetricsEventName.TokenScreenOpened,
- category: MetaMetricsEventCategory.Navigation,
- properties: {
- token_symbol: primaryCurrencyProperties.suffix,
- location: 'Home',
- },
- });
- }}
- />
{shouldShowTokensLinks && (
{
+ const dispatch = useDispatch();
+ const trackEvent = useContext(MetaMetricsContext);
+ const t = useI18nContext();
+ const isEvm = useSelector(getMultichainIsEvm);
+ // NOTE: Since we can parametrize it now, we keep the original behavior
+ // for EVM assets
+ const shouldShowTokensLinks = showTokensLinks ?? isEvm;
+
+ return (
+ {
+ dispatch(showImportTokensModal());
+ trackEvent({
+ category: MetaMetricsEventCategory.Navigation,
+ event: MetaMetricsEventName.TokenImportButtonClicked,
+ properties: {
+ location: 'HOME',
+ },
+ });
+ }}
+ >
+ {t('import')}
+
+ );
+};
+
+export default AssetListControlBar;
diff --git a/ui/components/app/assets/asset-list/import-control/index.ts b/ui/components/app/assets/asset-list/import-control/index.ts
new file mode 100644
index 000000000000..b871f41ae8b4
--- /dev/null
+++ b/ui/components/app/assets/asset-list/import-control/index.ts
@@ -0,0 +1 @@
+export { default } from './import-control';
diff --git a/ui/components/app/assets/asset-list/native-token/index.ts b/ui/components/app/assets/asset-list/native-token/index.ts
new file mode 100644
index 000000000000..6feb276bed54
--- /dev/null
+++ b/ui/components/app/assets/asset-list/native-token/index.ts
@@ -0,0 +1 @@
+export { default } from './native-token';
diff --git a/ui/components/app/assets/asset-list/native-token/native-token.tsx b/ui/components/app/assets/asset-list/native-token/native-token.tsx
new file mode 100644
index 000000000000..cf0191b3de66
--- /dev/null
+++ b/ui/components/app/assets/asset-list/native-token/native-token.tsx
@@ -0,0 +1,59 @@
+import React from 'react';
+import { useSelector } from 'react-redux';
+import {
+ getMultichainCurrentNetwork,
+ getMultichainNativeCurrency,
+ getMultichainIsEvm,
+ getMultichainCurrencyImage,
+ getMultichainIsMainnet,
+ getMultichainSelectedAccountCachedBalance,
+} from '../../../../../selectors/multichain';
+import { TokenListItem } from '../../../../multichain';
+import { useIsOriginalNativeTokenSymbol } from '../../../../../hooks/useIsOriginalNativeTokenSymbol';
+import { AssetListProps } from '../asset-list';
+import { useNativeTokenBalance } from './use-native-token-balance';
+// import { getPreferences } from '../../../../../selectors';
+
+const NativeToken = ({ onClickAsset }: AssetListProps) => {
+ const nativeCurrency = useSelector(getMultichainNativeCurrency);
+ const isMainnet = useSelector(getMultichainIsMainnet);
+ const { chainId, ticker, type, rpcUrl } = useSelector(
+ getMultichainCurrentNetwork,
+ );
+ const isOriginalNativeSymbol = useIsOriginalNativeTokenSymbol(
+ chainId,
+ ticker,
+ type,
+ rpcUrl,
+ );
+ const balance = useSelector(getMultichainSelectedAccountCachedBalance);
+ const balanceIsLoading = !balance;
+
+ const { string, symbol, secondary } = useNativeTokenBalance();
+
+ const primaryTokenImage = useSelector(getMultichainCurrencyImage);
+
+ const isEvm = useSelector(getMultichainIsEvm);
+
+ let isStakeable = isMainnet && isEvm;
+ ///: BEGIN:ONLY_INCLUDE_IF(build-mmi)
+ isStakeable = false;
+ ///: END:ONLY_INCLUDE_IF
+
+ return (
+ onClickAsset(nativeCurrency)}
+ title={nativeCurrency}
+ primary={string}
+ tokenSymbol={symbol}
+ secondary={secondary}
+ tokenImage={balanceIsLoading ? null : primaryTokenImage}
+ isOriginalTokenSymbol={isOriginalNativeSymbol}
+ isNativeCurrency
+ isStakeable={isStakeable}
+ showPercentage
+ />
+ );
+};
+
+export default NativeToken;
diff --git a/ui/components/app/assets/asset-list/native-token/use-native-token-balance.ts b/ui/components/app/assets/asset-list/native-token/use-native-token-balance.ts
new file mode 100644
index 000000000000..a14e65ac572b
--- /dev/null
+++ b/ui/components/app/assets/asset-list/native-token/use-native-token-balance.ts
@@ -0,0 +1,94 @@
+import currencyFormatter from 'currency-formatter';
+import { useSelector } from 'react-redux';
+
+import {
+ getMultichainCurrencyImage,
+ getMultichainCurrentNetwork,
+ getMultichainSelectedAccountCachedBalance,
+ getMultichainShouldShowFiat,
+} from '../../../../../selectors/multichain';
+import { getCurrentCurrency, getPreferences } from '../../../../../selectors';
+import { useIsOriginalNativeTokenSymbol } from '../../../../../hooks/useIsOriginalNativeTokenSymbol';
+import { PRIMARY, SECONDARY } from '../../../../../helpers/constants/common';
+import { useUserPreferencedCurrency } from '../../../../../hooks/useUserPreferencedCurrency';
+import { useCurrencyDisplay } from '../../../../../hooks/useCurrencyDisplay';
+import { TokenWithBalance } from '../asset-list';
+
+export const useNativeTokenBalance = () => {
+ const showFiat = useSelector(getMultichainShouldShowFiat);
+ const primaryTokenImage = useSelector(getMultichainCurrencyImage);
+ const { showNativeTokenAsMainBalance } = useSelector(getPreferences);
+ const { chainId, ticker, type, rpcUrl } = useSelector(
+ getMultichainCurrentNetwork,
+ );
+ const isOriginalNativeSymbol = useIsOriginalNativeTokenSymbol(
+ chainId,
+ ticker,
+ type,
+ rpcUrl,
+ );
+ const balance = useSelector(getMultichainSelectedAccountCachedBalance);
+ const currentCurrency = useSelector(getCurrentCurrency);
+ const {
+ currency: primaryCurrency,
+ numberOfDecimals: primaryNumberOfDecimals,
+ } = useUserPreferencedCurrency(PRIMARY, {
+ ethNumberOfDecimals: 4,
+ shouldCheckShowNativeToken: true,
+ });
+ const {
+ currency: secondaryCurrency,
+ numberOfDecimals: secondaryNumberOfDecimals,
+ } = useUserPreferencedCurrency(SECONDARY, {
+ ethNumberOfDecimals: 4,
+ shouldCheckShowNativeToken: true,
+ });
+
+ const [primaryCurrencyDisplay, primaryCurrencyProperties] =
+ useCurrencyDisplay(balance, {
+ numberOfDecimals: primaryNumberOfDecimals,
+ currency: primaryCurrency,
+ });
+
+ const [secondaryCurrencyDisplay, secondaryCurrencyProperties] =
+ useCurrencyDisplay(balance, {
+ numberOfDecimals: secondaryNumberOfDecimals,
+ currency: secondaryCurrency,
+ });
+
+ const primaryBalance = isOriginalNativeSymbol
+ ? secondaryCurrencyDisplay
+ : undefined;
+
+ const secondaryBalance =
+ showFiat && isOriginalNativeSymbol ? primaryCurrencyDisplay : undefined;
+
+ const tokenSymbol = showNativeTokenAsMainBalance
+ ? primaryCurrencyProperties.suffix
+ : secondaryCurrencyProperties.suffix;
+
+ const unformattedTokenFiatAmount = showNativeTokenAsMainBalance
+ ? secondaryCurrencyDisplay.toString()
+ : primaryCurrencyDisplay.toString();
+
+ // useCurrencyDisplay passes along the symbol and formatting into the value here
+ // for sorting we need the raw value, without the currency and it should be decimal
+ // this is the easiest way to do this without extensive refactoring of useCurrencyDisplay
+ const tokenFiatAmount = currencyFormatter
+ .unformat(unformattedTokenFiatAmount, {
+ code: currentCurrency.toUpperCase(),
+ })
+ .toString();
+
+ const nativeTokenWithBalance: TokenWithBalance = {
+ address: '',
+ symbol: tokenSymbol ?? '',
+ string: primaryBalance,
+ image: primaryTokenImage,
+ secondary: secondaryBalance,
+ tokenFiatAmount,
+ isNative: true,
+ };
+
+ return nativeTokenWithBalance;
+};
diff --git a/ui/components/app/assets/asset-list/sort-control/index.scss b/ui/components/app/assets/asset-list/sort-control/index.scss
new file mode 100644
index 000000000000..76e61c1025ae
--- /dev/null
+++ b/ui/components/app/assets/asset-list/sort-control/index.scss
@@ -0,0 +1,27 @@
+.selectable-list-item-wrapper {
+ position: relative;
+}
+
+.selectable-list-item {
+ cursor: pointer;
+ padding: 16px;
+
+ &--selected {
+ background: var(--color-primary-muted);
+ }
+
+ &:not(.selectable-list-item--selected) {
+ &:hover,
+ &:focus-within {
+ background: var(--color-background-default-hover);
+ }
+ }
+
+ &__selected-indicator {
+ width: 4px;
+ height: calc(100% - 8px);
+ position: absolute;
+ top: 4px;
+ left: 4px;
+ }
+}
diff --git a/ui/components/app/assets/asset-list/sort-control/index.ts b/ui/components/app/assets/asset-list/sort-control/index.ts
new file mode 100644
index 000000000000..7e5ecace780f
--- /dev/null
+++ b/ui/components/app/assets/asset-list/sort-control/index.ts
@@ -0,0 +1 @@
+export { default } from './sort-control';
diff --git a/ui/components/app/assets/asset-list/sort-control/sort-control.test.tsx b/ui/components/app/assets/asset-list/sort-control/sort-control.test.tsx
new file mode 100644
index 000000000000..4aac598bd838
--- /dev/null
+++ b/ui/components/app/assets/asset-list/sort-control/sort-control.test.tsx
@@ -0,0 +1,119 @@
+import React from 'react';
+import { screen, fireEvent } from '@testing-library/react';
+import { useSelector } from 'react-redux';
+import { setTokenSortConfig } from '../../../../../store/actions';
+import { renderWithProvider } from '../../../../../../test/lib/render-helpers';
+import { MetaMetricsContext } from '../../../../../contexts/metametrics';
+import { getCurrentCurrency, getPreferences } from '../../../../../selectors';
+import SortControl from './sort-control';
+
+// Mock the sortAssets utility
+jest.mock('../../util/sort', () => ({
+ sortAssets: jest.fn(() => []), // mock sorting implementation
+}));
+
+// Mock the setTokenSortConfig action creator
+jest.mock('../../../../../store/actions', () => ({
+ setTokenSortConfig: jest.fn(),
+}));
+
+// Mock the dispatch function
+const mockDispatch = jest.fn();
+
+jest.mock('react-redux', () => {
+ const actual = jest.requireActual('react-redux');
+ return {
+ ...actual,
+ useSelector: jest.fn(),
+ useDispatch: () => mockDispatch,
+ };
+});
+
+const mockHandleClose = jest.fn();
+
+describe('SortControl', () => {
+ const mockTrackEvent = jest.fn();
+
+ const renderComponent = () => {
+ (useSelector as jest.Mock).mockImplementation((selector) => {
+ if (selector === getPreferences) {
+ return {
+ key: 'tokenFiatAmount',
+ sortCallback: 'stringNumeric',
+ order: 'dsc',
+ };
+ }
+ if (selector === getCurrentCurrency) {
+ return 'usd';
+ }
+ return undefined;
+ });
+
+ return renderWithProvider(
+
+
+ ,
+ );
+ };
+
+ beforeEach(() => {
+ mockDispatch.mockClear();
+ mockTrackEvent.mockClear();
+ (setTokenSortConfig as jest.Mock).mockClear();
+ });
+
+ it('renders correctly', () => {
+ renderComponent();
+
+ expect(screen.getByTestId('sortByAlphabetically')).toBeInTheDocument();
+ expect(screen.getByTestId('sortByDecliningBalance')).toBeInTheDocument();
+ });
+
+ it('dispatches setTokenSortConfig with expected config, and tracks event when Alphabetically is clicked', () => {
+ renderComponent();
+
+ const alphabeticallyButton = screen.getByTestId(
+ 'sortByAlphabetically__button',
+ );
+ fireEvent.click(alphabeticallyButton);
+
+ expect(mockDispatch).toHaveBeenCalled();
+ expect(setTokenSortConfig).toHaveBeenCalledWith({
+ key: 'symbol',
+ sortCallback: 'alphaNumeric',
+ order: 'asc',
+ });
+
+ expect(mockTrackEvent).toHaveBeenCalledWith({
+ category: 'Settings',
+ event: 'Token Sort Preference',
+ properties: {
+ token_sort_preference: 'symbol',
+ },
+ });
+ });
+
+ it('dispatches setTokenSortConfig with expected config, and tracks event when Declining balance is clicked', () => {
+ renderComponent();
+
+ const decliningBalanceButton = screen.getByTestId(
+ 'sortByDecliningBalance__button',
+ );
+ fireEvent.click(decliningBalanceButton);
+
+ expect(mockDispatch).toHaveBeenCalled();
+ expect(setTokenSortConfig).toHaveBeenCalledWith({
+ key: 'tokenFiatAmount',
+ sortCallback: 'stringNumeric',
+ order: 'dsc',
+ });
+
+ expect(mockTrackEvent).toHaveBeenCalledWith({
+ category: 'Settings',
+ event: 'Token Sort Preference',
+ properties: {
+ token_sort_preference: 'tokenFiatAmount',
+ },
+ });
+ });
+});
diff --git a/ui/components/app/assets/asset-list/sort-control/sort-control.tsx b/ui/components/app/assets/asset-list/sort-control/sort-control.tsx
new file mode 100644
index 000000000000..c45a5488f1a6
--- /dev/null
+++ b/ui/components/app/assets/asset-list/sort-control/sort-control.tsx
@@ -0,0 +1,116 @@
+import React, { ReactNode, useContext } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+import classnames from 'classnames';
+import { Box, Text } from '../../../../component-library';
+import { SortOrder, SortingCallbacksT } from '../../util/sort';
+import {
+ BackgroundColor,
+ BorderRadius,
+ TextColor,
+ TextVariant,
+} from '../../../../../helpers/constants/design-system';
+import { setTokenSortConfig } from '../../../../../store/actions';
+import { MetaMetricsContext } from '../../../../../contexts/metametrics';
+import {
+ MetaMetricsEventCategory,
+ MetaMetricsEventName,
+ MetaMetricsUserTrait,
+} from '../../../../../../shared/constants/metametrics';
+import { getCurrentCurrency, getPreferences } from '../../../../../selectors';
+import { useI18nContext } from '../../../../../hooks/useI18nContext';
+import { getCurrencySymbol } from '../../../../../helpers/utils/common.util';
+
+// intentionally used generic naming convention for styled selectable list item
+// inspired from ui/components/multichain/network-list-item
+// should probably be broken out into component library
+type SelectableListItemProps = {
+ isSelected: boolean;
+ onClick?: React.MouseEventHandler;
+ testId?: string;
+ children: ReactNode;
+};
+
+export const SelectableListItem = ({
+ isSelected,
+ onClick,
+ testId,
+ children,
+}: SelectableListItemProps) => {
+ return (
+
+
+
+ {children}
+
+
+ {isSelected && (
+
+ )}
+
+ );
+};
+
+type SortControlProps = {
+ handleClose: () => void;
+};
+
+const SortControl = ({ handleClose }: SortControlProps) => {
+ const t = useI18nContext();
+ const trackEvent = useContext(MetaMetricsContext);
+ const { tokenSortConfig } = useSelector(getPreferences);
+ const currentCurrency = useSelector(getCurrentCurrency);
+
+ const dispatch = useDispatch();
+
+ const handleSort = (
+ key: string,
+ sortCallback: keyof SortingCallbacksT,
+ order: SortOrder,
+ ) => {
+ dispatch(
+ setTokenSortConfig({
+ key,
+ sortCallback,
+ order,
+ }),
+ );
+ trackEvent({
+ category: MetaMetricsEventCategory.Settings,
+ event: MetaMetricsEventName.TokenSortPreference,
+ properties: {
+ [MetaMetricsUserTrait.TokenSortPreference]: key,
+ },
+ });
+ handleClose();
+ };
+ return (
+ <>
+ handleSort('symbol', 'alphaNumeric', 'asc')}
+ testId="sortByAlphabetically"
+ >
+ {t('sortByAlphabetically')}
+
+ handleSort('tokenFiatAmount', 'stringNumeric', 'dsc')}
+ testId="sortByDecliningBalance"
+ >
+ {t('sortByDecliningBalance', [getCurrencySymbol(currentCurrency)])}
+
+ >
+ );
+};
+
+export default SortControl;
diff --git a/ui/components/app/assets/token-cell/token-cell.tsx b/ui/components/app/assets/token-cell/token-cell.tsx
index 2cd5cb84b8ab..5f5b43d6c098 100644
--- a/ui/components/app/assets/token-cell/token-cell.tsx
+++ b/ui/components/app/assets/token-cell/token-cell.tsx
@@ -10,7 +10,7 @@ import { getIntlLocale } from '../../../../ducks/locale/locale';
type TokenCellProps = {
address: string;
symbol: string;
- string: string;
+ string?: string;
image: string;
onClick?: (arg: string) => void;
};
diff --git a/ui/components/app/assets/token-list/token-list.tsx b/ui/components/app/assets/token-list/token-list.tsx
index 194ea2762191..8a107b154fb9 100644
--- a/ui/components/app/assets/token-list/token-list.tsx
+++ b/ui/components/app/assets/token-list/token-list.tsx
@@ -1,4 +1,5 @@
-import React from 'react';
+import React, { ReactNode, useMemo } from 'react';
+import { shallowEqual, useSelector } from 'react-redux';
import TokenCell from '../token-cell';
import { useI18nContext } from '../../../../hooks/useI18nContext';
import { Box } from '../../../component-library';
@@ -8,39 +9,87 @@ import {
JustifyContent,
} from '../../../../helpers/constants/design-system';
import { TokenWithBalance } from '../asset-list/asset-list';
+import { sortAssets } from '../util/sort';
+import {
+ getPreferences,
+ getSelectedAccount,
+ getShouldHideZeroBalanceTokens,
+ getTokenExchangeRates,
+} from '../../../../selectors';
+import { useAccountTotalFiatBalance } from '../../../../hooks/useAccountTotalFiatBalance';
+import { getConversionRate } from '../../../../ducks/metamask/metamask';
+import { useNativeTokenBalance } from '../asset-list/native-token/use-native-token-balance';
type TokenListProps = {
onTokenClick: (arg: string) => void;
- tokens: TokenWithBalance[];
- loading: boolean;
+ nativeToken: ReactNode;
};
export default function TokenList({
onTokenClick,
- tokens,
- loading = false,
+ nativeToken,
}: TokenListProps) {
const t = useI18nContext();
+ const { tokenSortConfig } = useSelector(getPreferences);
+ const selectedAccount = useSelector(getSelectedAccount);
+ const conversionRate = useSelector(getConversionRate);
+ const nativeTokenWithBalance = useNativeTokenBalance();
+ const shouldHideZeroBalanceTokens = useSelector(
+ getShouldHideZeroBalanceTokens,
+ );
+ const contractExchangeRates = useSelector(
+ getTokenExchangeRates,
+ shallowEqual,
+ );
+ const { tokensWithBalances, loading } = useAccountTotalFiatBalance(
+ selectedAccount,
+ shouldHideZeroBalanceTokens,
+ ) as {
+ tokensWithBalances: TokenWithBalance[];
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ mergedRates: any;
+ loading: boolean;
+ };
- if (loading) {
- return (
-
- {t('loadingTokens')}
-
+ const sortedTokens = useMemo(() => {
+ return sortAssets(
+ [nativeTokenWithBalance, ...tokensWithBalances],
+ tokenSortConfig,
);
- }
+ }, [
+ tokensWithBalances,
+ tokenSortConfig,
+ conversionRate,
+ contractExchangeRates,
+ ]);
- return (
+ return loading ? (
+
+ {t('loadingTokens')}
+
+ ) : (
- {tokens.map((tokenData, index) => (
-
- ))}
+ {sortedTokens.map((tokenData) => {
+ if (tokenData?.isNative) {
+ // we need cloneElement so that we can pass the unique key
+ return React.cloneElement(nativeToken as React.ReactElement, {
+ key: `${tokenData.symbol}-${tokenData.address}`,
+ });
+ }
+ return (
+
+ );
+ })}
);
}
diff --git a/ui/components/app/assets/util/sort.test.ts b/ui/components/app/assets/util/sort.test.ts
new file mode 100644
index 000000000000..f4a99e31b641
--- /dev/null
+++ b/ui/components/app/assets/util/sort.test.ts
@@ -0,0 +1,263 @@
+import { sortAssets } from './sort';
+
+type MockAsset = {
+ name: string;
+ balance: string;
+ createdAt: Date;
+ profile: {
+ id: string;
+ info?: {
+ category?: string;
+ };
+ };
+};
+
+const mockAssets: MockAsset[] = [
+ {
+ name: 'Asset Z',
+ balance: '500',
+ createdAt: new Date('2023-01-01'),
+ profile: { id: '1', info: { category: 'gold' } },
+ },
+ {
+ name: 'Asset A',
+ balance: '600',
+ createdAt: new Date('2022-05-15'),
+ profile: { id: '4', info: { category: 'silver' } },
+ },
+ {
+ name: 'Asset B',
+ balance: '400',
+ createdAt: new Date('2021-07-20'),
+ profile: { id: '2', info: { category: 'bronze' } },
+ },
+];
+
+// Define the sorting tests
+describe('sortAssets function - nested value handling with dates and numeric sorting', () => {
+ test('sorts by name in ascending order', () => {
+ const sortedById = sortAssets(mockAssets, {
+ key: 'name',
+ sortCallback: 'alphaNumeric',
+ order: 'asc',
+ });
+
+ expect(sortedById[0].name).toBe('Asset A');
+ expect(sortedById[sortedById.length - 1].name).toBe('Asset Z');
+ });
+
+ test('sorts by balance in ascending order (stringNumeric)', () => {
+ const sortedById = sortAssets(mockAssets, {
+ key: 'balance',
+ sortCallback: 'stringNumeric',
+ order: 'asc',
+ });
+
+ expect(sortedById[0].balance).toBe('400');
+ expect(sortedById[sortedById.length - 1].balance).toBe('600');
+ });
+
+ test('sorts by balance in ascending order (numeric)', () => {
+ const sortedById = sortAssets(mockAssets, {
+ key: 'balance',
+ sortCallback: 'numeric',
+ order: 'asc',
+ });
+
+ expect(sortedById[0].balance).toBe('400');
+ expect(sortedById[sortedById.length - 1].balance).toBe('600');
+ });
+
+ test('sorts by profile.id in ascending order', () => {
+ const sortedById = sortAssets(mockAssets, {
+ key: 'profile.id',
+ sortCallback: 'stringNumeric',
+ order: 'asc',
+ });
+
+ expect(sortedById[0].profile.id).toBe('1');
+ expect(sortedById[sortedById.length - 1].profile.id).toBe('4');
+ });
+
+ test('sorts by profile.id in descending order', () => {
+ const sortedById = sortAssets(mockAssets, {
+ key: 'profile.id',
+ sortCallback: 'stringNumeric',
+ order: 'dsc',
+ });
+
+ expect(sortedById[0].profile.id).toBe('4');
+ expect(sortedById[sortedById.length - 1].profile.id).toBe('1');
+ });
+
+ test('sorts by deeply nested profile.info.category in ascending order', () => {
+ const sortedByCategory = sortAssets(mockAssets, {
+ key: 'profile.info.category',
+ sortCallback: 'alphaNumeric',
+ order: 'asc',
+ });
+
+ // Expecting the assets with defined categories to be sorted first
+ expect(sortedByCategory[0].profile.info?.category).toBe('bronze');
+ expect(
+ sortedByCategory[sortedByCategory.length - 1].profile.info?.category,
+ ).toBe('silver');
+ });
+
+ test('sorts by createdAt (date) in ascending order', () => {
+ const sortedByDate = sortAssets(mockAssets, {
+ key: 'createdAt',
+ sortCallback: 'date',
+ order: 'asc',
+ });
+
+ expect(sortedByDate[0].createdAt).toEqual(new Date('2021-07-20'));
+ expect(sortedByDate[sortedByDate.length - 1].createdAt).toEqual(
+ new Date('2023-01-01'),
+ );
+ });
+
+ test('sorts by createdAt (date) in descending order', () => {
+ const sortedByDate = sortAssets(mockAssets, {
+ key: 'createdAt',
+ sortCallback: 'date',
+ order: 'dsc',
+ });
+
+ expect(sortedByDate[0].createdAt).toEqual(new Date('2023-01-01'));
+ expect(sortedByDate[sortedByDate.length - 1].createdAt).toEqual(
+ new Date('2021-07-20'),
+ );
+ });
+
+ test('handles undefined deeply nested value gracefully when sorting', () => {
+ const invlaidAsset = {
+ name: 'Asset Y',
+ balance: '600',
+ createdAt: new Date('2024-01-01'),
+ profile: { id: '3' }, // No category info
+ };
+ const sortedByCategory = sortAssets([...mockAssets, invlaidAsset], {
+ key: 'profile.info.category',
+ sortCallback: 'alphaNumeric',
+ order: 'asc',
+ });
+
+ // Expect the undefined categories to be at the end
+ expect(
+ // @ts-expect-error // testing for undefined value
+ sortedByCategory[sortedByCategory.length - 1].profile.info?.category,
+ ).toBeUndefined();
+ });
+});
+
+// Utility function to generate large mock data
+function generateLargeMockData(size: number): MockAsset[] {
+ const mockData: MockAsset[] = [];
+ for (let i = 0; i < size; i++) {
+ mockData.push({
+ name: `Asset ${String.fromCharCode(65 + (i % 26))}`,
+ balance: `${Math.floor(Math.random() * 1000)}`, // Random balance between 0 and 999
+ createdAt: new Date(Date.now() - Math.random() * 10000000000), // Random date within the past ~115 days
+ profile: {
+ id: `${i + 1}`,
+ info: {
+ category: ['gold', 'silver', 'bronze'][i % 3], // Cycles between 'gold', 'silver', 'bronze'
+ },
+ },
+ });
+ }
+ return mockData;
+}
+
+// Generate a large dataset for testing
+const largeDataset = generateLargeMockData(10000); // 10,000 mock assets
+
+// Define the sorting tests for large datasets
+describe('sortAssets function - large dataset handling', () => {
+ const MAX_EXECUTION_TIME_MS = 500; // Set max allowed execution time (in milliseconds)
+
+ test('sorts large dataset by name in ascending order', () => {
+ const startTime = Date.now();
+ const sortedByName = sortAssets(largeDataset, {
+ key: 'name',
+ sortCallback: 'alphaNumeric',
+ order: 'asc',
+ });
+
+ const endTime = Date.now();
+ const executionTime = endTime - startTime;
+
+ expect(sortedByName[0].name).toBe('Asset A');
+ expect(sortedByName[sortedByName.length - 1].name).toBe('Asset Z');
+ expect(executionTime).toBeLessThan(MAX_EXECUTION_TIME_MS);
+ });
+
+ test('sorts large dataset by balance in ascending order', () => {
+ const startTime = Date.now();
+ const sortedByBalance = sortAssets(largeDataset, {
+ key: 'balance',
+ sortCallback: 'numeric',
+ order: 'asc',
+ });
+
+ const endTime = Date.now();
+ const executionTime = endTime - startTime;
+
+ const balances = sortedByBalance.map((asset) => asset.balance);
+ expect(balances).toEqual(
+ balances.slice().sort((a, b) => parseInt(a, 10) - parseInt(b, 10)),
+ );
+ expect(executionTime).toBeLessThan(MAX_EXECUTION_TIME_MS);
+ });
+
+ test('sorts large dataset by balance in descending order', () => {
+ const startTime = Date.now();
+ const sortedByBalance = sortAssets(largeDataset, {
+ key: 'balance',
+ sortCallback: 'numeric',
+ order: 'dsc',
+ });
+
+ const endTime = Date.now();
+ const executionTime = endTime - startTime;
+
+ const balances = sortedByBalance.map((asset) => asset.balance);
+ expect(balances).toEqual(
+ balances.slice().sort((a, b) => parseInt(b, 10) - parseInt(a, 10)),
+ );
+ expect(executionTime).toBeLessThan(MAX_EXECUTION_TIME_MS);
+ });
+
+ test('sorts large dataset by createdAt (date) in ascending order', () => {
+ const startTime = Date.now();
+ const sortedByDate = sortAssets(largeDataset, {
+ key: 'createdAt',
+ sortCallback: 'date',
+ order: 'asc',
+ });
+
+ const endTime = Date.now();
+ const executionTime = endTime - startTime;
+
+ const dates = sortedByDate.map((asset) => asset.createdAt.getTime());
+ expect(dates).toEqual(dates.slice().sort((a, b) => a - b));
+ expect(executionTime).toBeLessThan(MAX_EXECUTION_TIME_MS);
+ });
+
+ test('sorts large dataset by createdAt (date) in descending order', () => {
+ const startTime = Date.now();
+ const sortedByDate = sortAssets(largeDataset, {
+ key: 'createdAt',
+ sortCallback: 'date',
+ order: 'dsc',
+ });
+
+ const endTime = Date.now();
+ const executionTime = endTime - startTime;
+
+ const dates = sortedByDate.map((asset) => asset.createdAt.getTime());
+ expect(dates).toEqual(dates.slice().sort((a, b) => b - a));
+ expect(executionTime).toBeLessThan(MAX_EXECUTION_TIME_MS);
+ });
+});
diff --git a/ui/components/app/assets/util/sort.ts b/ui/components/app/assets/util/sort.ts
new file mode 100644
index 000000000000..b24a1c8e96a9
--- /dev/null
+++ b/ui/components/app/assets/util/sort.ts
@@ -0,0 +1,86 @@
+import { get } from 'lodash';
+
+export type SortOrder = 'asc' | 'dsc';
+export type SortCriteria = {
+ key: string;
+ order?: 'asc' | 'dsc';
+ sortCallback: SortCallbackKeys;
+};
+
+export type SortingType = number | string | Date;
+type SortCallbackKeys = keyof SortingCallbacksT;
+
+export type SortingCallbacksT = {
+ numeric: (a: number, b: number) => number;
+ stringNumeric: (a: string, b: string) => number;
+ alphaNumeric: (a: string, b: string) => number;
+ date: (a: Date, b: Date) => number;
+};
+
+// All sortingCallbacks should be asc order, sortAssets function handles asc/dsc
+const sortingCallbacks: SortingCallbacksT = {
+ numeric: (a: number, b: number) => a - b,
+ stringNumeric: (a: string, b: string) => {
+ return (
+ parseFloat(parseFloat(a).toFixed(5)) -
+ parseFloat(parseFloat(b).toFixed(5))
+ );
+ },
+ alphaNumeric: (a: string, b: string) => a.localeCompare(b),
+ date: (a: Date, b: Date) => a.getTime() - b.getTime(),
+};
+
+// Utility function to access nested properties by key path
+function getNestedValue(obj: T, keyPath: string): SortingType {
+ return get(obj, keyPath) as SortingType;
+}
+
+export function sortAssets(array: T[], criteria: SortCriteria): T[] {
+ const { key, order = 'asc', sortCallback } = criteria;
+
+ return [...array].sort((a, b) => {
+ const aValue = getNestedValue(a, key);
+ const bValue = getNestedValue(b, key);
+
+ // Always move undefined values to the end, regardless of sort order
+ if (aValue === undefined) {
+ return 1;
+ }
+
+ if (bValue === undefined) {
+ return -1;
+ }
+
+ let comparison: number;
+
+ switch (sortCallback) {
+ case 'stringNumeric':
+ case 'alphaNumeric':
+ comparison = sortingCallbacks[sortCallback](
+ aValue as string,
+ bValue as string,
+ );
+ break;
+ case 'numeric':
+ comparison = sortingCallbacks.numeric(
+ aValue as number,
+ bValue as number,
+ );
+ break;
+ case 'date':
+ comparison = sortingCallbacks.date(aValue as Date, bValue as Date);
+ break;
+ default:
+ if (aValue < bValue) {
+ comparison = -1;
+ } else if (aValue > bValue) {
+ comparison = 1;
+ } else {
+ comparison = 0;
+ }
+ }
+
+ // Modify to sort in ascending or descending order
+ return order === 'asc' ? comparison : -comparison;
+ });
+}
diff --git a/ui/components/multichain/account-overview/account-overview-btc.test.tsx b/ui/components/multichain/account-overview/account-overview-btc.test.tsx
index 34cbed54c127..9d265657432b 100644
--- a/ui/components/multichain/account-overview/account-overview-btc.test.tsx
+++ b/ui/components/multichain/account-overview/account-overview-btc.test.tsx
@@ -40,7 +40,9 @@ describe('AccountOverviewBtc', () => {
const { queryByTestId } = render();
expect(queryByTestId('account-overview__asset-tab')).toBeInTheDocument();
- expect(queryByTestId('import-token-button')).not.toBeInTheDocument();
+ const button = queryByTestId('import-token-button');
+ expect(button).toBeInTheDocument(); // Verify the button is present
+ expect(button).toBeDisabled(); // Verify the button is disabled
// TODO: This one might be required, but we do not really handle tokens for BTC yet...
expect(queryByTestId('refresh-list-button')).not.toBeInTheDocument();
});
diff --git a/ui/components/multichain/import-token-link/__snapshots__/import-token-link.test.js.snap b/ui/components/multichain/import-token-link/__snapshots__/import-token-link.test.js.snap
index 9dd39fea147f..e8fa1e945dba 100644
--- a/ui/components/multichain/import-token-link/__snapshots__/import-token-link.test.js.snap
+++ b/ui/components/multichain/import-token-link/__snapshots__/import-token-link.test.js.snap
@@ -5,20 +5,6 @@ exports[`Import Token Link should match snapshot for goerli chainId 1`] = `
-
-
-
- Import tokens
-
-
@@ -42,20 +28,6 @@ exports[`Import Token Link should match snapshot for mainnet chainId 1`] = `
-
-
-
- Import tokens
-
-
diff --git a/ui/components/multichain/import-token-link/import-token-link.test.js b/ui/components/multichain/import-token-link/import-token-link.test.js
index 722d2b4106ff..641a39d1bff3 100644
--- a/ui/components/multichain/import-token-link/import-token-link.test.js
+++ b/ui/components/multichain/import-token-link/import-token-link.test.js
@@ -5,6 +5,7 @@ import { detectTokens } from '../../../store/actions';
import { renderWithProvider } from '../../../../test/lib/render-helpers';
import { CHAIN_IDS } from '../../../../shared/constants/network';
import { mockNetworkState } from '../../../../test/stub/networks';
+import ImportControl from '../../app/assets/asset-list/import-control';
import { ImportTokenLink } from '.';
const mockPushHistory = jest.fn();
@@ -65,7 +66,7 @@ describe('Import Token Link', () => {
const store = configureMockStore()(mockState);
- renderWithProvider(
, store);
+ renderWithProvider(
, store); // should this be RefreshTokenLink?
const refreshList = screen.getByTestId('refresh-list-button');
fireEvent.click(refreshList);
@@ -82,11 +83,11 @@ describe('Import Token Link', () => {
const store = configureMockStore()(mockState);
- renderWithProvider(
, store);
+ renderWithProvider(
, store);
const importToken = screen.getByTestId('import-token-button');
fireEvent.click(importToken);
- expect(screen.getByText('Import tokens')).toBeInTheDocument();
+ expect(screen.getByText('Import')).toBeInTheDocument();
});
});
diff --git a/ui/components/multichain/import-token-link/import-token-link.tsx b/ui/components/multichain/import-token-link/import-token-link.tsx
index 6c7c9b6a8e6b..022369dd5002 100644
--- a/ui/components/multichain/import-token-link/import-token-link.tsx
+++ b/ui/components/multichain/import-token-link/import-token-link.tsx
@@ -1,5 +1,5 @@
-import React, { useContext } from 'react';
-import { useDispatch, useSelector } from 'react-redux';
+import React from 'react';
+import { useDispatch } from 'react-redux';
import classnames from 'classnames';
import {
ButtonLink,
@@ -9,16 +9,7 @@ import {
} from '../../component-library';
import { AlignItems, Display } from '../../../helpers/constants/design-system';
import { useI18nContext } from '../../../hooks/useI18nContext';
-import { detectTokens, showImportTokensModal } from '../../../store/actions';
-import { MetaMetricsContext } from '../../../contexts/metametrics';
-import {
- MetaMetricsEventCategory,
- MetaMetricsEventName,
-} from '../../../../shared/constants/metametrics';
-import {
- getIsTokenDetectionSupported,
- getIsTokenDetectionInactiveOnMainnet,
-} from '../../../selectors';
+import { detectTokens } from '../../../store/actions';
import type { BoxProps } from '../../component-library/box';
import type { ImportTokenLinkProps } from './import-token-link.types';
@@ -26,46 +17,14 @@ export const ImportTokenLink: React.FC
= ({
className = '',
...props
}): JSX.Element => {
- const trackEvent = useContext(MetaMetricsContext);
const t = useI18nContext();
const dispatch = useDispatch();
- const isTokenDetectionSupported = useSelector(getIsTokenDetectionSupported);
- const isTokenDetectionInactiveOnMainnet = useSelector(
- getIsTokenDetectionInactiveOnMainnet,
- );
-
- const isTokenDetectionAvailable =
- isTokenDetectionSupported ||
- isTokenDetectionInactiveOnMainnet ||
- Boolean(process.env.IN_TEST);
return (
)}
>
-
- {
- dispatch(showImportTokensModal());
- trackEvent({
- category: MetaMetricsEventCategory.Navigation,
- event: MetaMetricsEventName.TokenImportButtonClicked,
- properties: {
- location: 'HOME',
- },
- });
- }}
- >
- {isTokenDetectionAvailable
- ? t('importTokensCamelCase')
- : t('importTokensCamelCase').charAt(0).toUpperCase() +
- t('importTokensCamelCase').slice(1)}
-
-
s.toUpperCase());
}
+
+export function getCurrencySymbol(currencyCode) {
+ const supportedCurrencyCodes = {
+ EUR: '\u20AC',
+ HKD: '\u0024',
+ JPY: '\u00A5',
+ PHP: '\u20B1',
+ RUB: '\u20BD',
+ SGD: '\u0024',
+ USD: '\u0024',
+ };
+ if (supportedCurrencyCodes[currencyCode.toUpperCase()]) {
+ return supportedCurrencyCodes[currencyCode.toUpperCase()];
+ }
+ return currencyCode.toUpperCase();
+}
diff --git a/ui/hooks/useAccountTotalFiatBalance.js b/ui/hooks/useAccountTotalFiatBalance.js
index 9a3fe389b4de..b0c9b293c906 100644
--- a/ui/hooks/useAccountTotalFiatBalance.js
+++ b/ui/hooks/useAccountTotalFiatBalance.js
@@ -1,10 +1,12 @@
import { shallowEqual, useSelector } from 'react-redux';
+import { toChecksumAddress } from 'ethereumjs-util';
import {
getAllTokens,
getCurrentChainId,
getCurrentCurrency,
getMetaMaskCachedBalances,
getTokenExchangeRates,
+ getConfirmationExchangeRates,
getNativeCurrencyImage,
getTokenList,
} from '../selectors';
@@ -19,7 +21,7 @@ import {
} from '../ducks/metamask/metamask';
import { formatCurrency } from '../helpers/utils/confirm-tx.util';
import { getTokenFiatAmount } from '../helpers/utils/token-util';
-import { isEqualCaseInsensitive } from '../../shared/modules/string-utils';
+import { roundToDecimalPlacesRemovingExtraZeroes } from '../helpers/utils/util';
import { useTokenTracker } from './useTokenTracker';
export const useAccountTotalFiatBalance = (
@@ -34,6 +36,7 @@ export const useAccountTotalFiatBalance = (
getTokenExchangeRates,
shallowEqual,
);
+ const confirmationExchangeRates = useSelector(getConfirmationExchangeRates);
const cachedBalances = useSelector(getMetaMaskCachedBalances);
const balance = cachedBalances?.[account?.address] ?? 0;
@@ -59,15 +62,14 @@ export const useAccountTotalFiatBalance = (
hideZeroBalanceTokens: shouldHideZeroBalanceTokens,
});
+ const mergedRates = {
+ ...contractExchangeRates,
+ ...confirmationExchangeRates,
+ };
+
// Create fiat values for token balances
const tokenFiatBalances = tokensWithBalances.map((token) => {
- const contractExchangeTokenKey = Object.keys(contractExchangeRates).find(
- (key) => isEqualCaseInsensitive(key, token.address),
- );
- const tokenExchangeRate =
- (contractExchangeTokenKey &&
- contractExchangeRates[contractExchangeTokenKey]) ??
- 0;
+ const tokenExchangeRate = mergedRates[toChecksumAddress(token.address)];
const totalFiatValue = getTokenFiatAmount(
tokenExchangeRate,
@@ -136,6 +138,29 @@ export const useAccountTotalFiatBalance = (
...tokenFiatBalances,
).toString(10);
+ // we need to append some values to tokensWithBalance for UI
+ // this code was ported from asset-list
+ tokensWithBalances.forEach((token) => {
+ // token.string is the balance displayed in the TokenList UI
+ token.string = roundToDecimalPlacesRemovingExtraZeroes(token.string, 5);
+ });
+
+ // to sort by fiat balance, we need to compute this at this level
+ tokensWithBalances.forEach((token) => {
+ const tokenExchangeRate = mergedRates[toChecksumAddress(token.address)];
+
+ token.tokenFiatAmount =
+ getTokenFiatAmount(
+ tokenExchangeRate,
+ conversionRate,
+ currentCurrency,
+ token.string, // tokenAmount
+ token.symbol, // tokenSymbol
+ false, // no currency symbol prefix
+ false, // no ticker symbol suffix
+ ) || '0';
+ });
+
// Fiat balance formatted in user's desired currency (ex: "$8.90")
const formattedFiat = formatCurrency(totalFiatBalance, currentCurrency);
@@ -160,5 +185,6 @@ export const useAccountTotalFiatBalance = (
tokensWithBalances,
loading,
orderedTokenList,
+ mergedRates,
};
};
diff --git a/ui/hooks/useAccountTotalFiatBalance.test.js b/ui/hooks/useAccountTotalFiatBalance.test.js
index c883eb37cc1e..9fb1227367e1 100644
--- a/ui/hooks/useAccountTotalFiatBalance.test.js
+++ b/ui/hooks/useAccountTotalFiatBalance.test.js
@@ -125,19 +125,25 @@ describe('useAccountTotalFiatBalance', () => {
image: undefined,
isERC721: undefined,
decimals: 6,
- string: '0.04857',
+ string: 0.04857,
balanceError: null,
+ tokenFiatAmount: '0.05',
},
{
address: '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e',
symbol: 'YFI',
balance: '1409247882142934',
decimals: 18,
- string: '0.001409247882142934',
+ string: 0.00141,
balanceError: null,
+ tokenFiatAmount: '7.52',
},
],
loading: false,
+ mergedRates: {
+ '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e': 3.304588,
+ '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': 0.0006189,
+ },
orderedTokenList: [
{
fiatBalance: '1.85',
diff --git a/ui/hooks/useMultichainAccountTotalFiatBalance.test.tsx b/ui/hooks/useMultichainAccountTotalFiatBalance.test.tsx
index 888d70e1d62c..ffd664612a02 100644
--- a/ui/hooks/useMultichainAccountTotalFiatBalance.test.tsx
+++ b/ui/hooks/useMultichainAccountTotalFiatBalance.test.tsx
@@ -141,6 +141,10 @@ describe('useMultichainAccountTotalFiatBalance', () => {
expect(result.current).toStrictEqual({
formattedFiat: '$9.41',
loading: false,
+ mergedRates: {
+ '0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e': 3.304588,
+ '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48': 0.0006189,
+ },
totalWeiBalance: '14ba1e6a08a9ed',
tokensWithBalances: mockTokenBalances,
totalFiatBalance: '9.41',
diff --git a/ui/pages/routes/routes.component.test.js b/ui/pages/routes/routes.component.test.js
index ec8c4e96c864..6151fedc687b 100644
--- a/ui/pages/routes/routes.component.test.js
+++ b/ui/pages/routes/routes.component.test.js
@@ -115,6 +115,13 @@ describe('Routes Component', () => {
announcements: {},
...mockNetworkState({ chainId: CHAIN_IDS.MAINNET }),
newPrivacyPolicyToastShownDate: new Date('0'),
+ preferences: {
+ tokenSortConfig: {
+ key: 'token-sort-key',
+ order: 'dsc',
+ sortCallback: 'stringNumeric',
+ },
+ },
},
send: {
...mockSendState.send,
diff --git a/ui/store/actionConstants.ts b/ui/store/actionConstants.ts
index 6e1e33d9531f..6f8080e516ae 100644
--- a/ui/store/actionConstants.ts
+++ b/ui/store/actionConstants.ts
@@ -174,3 +174,5 @@ export const HIDE_KEYRING_SNAP_REMOVAL_RESULT =
export const SET_SHOW_NFT_AUTO_DETECT_MODAL_UPGRADE =
'SET_SHOW_NFT_AUTO_DETECT_MODAL_UPGRADE';
+
+export const TOKEN_SORT_CRITERIA = 'TOKEN_SORT_CRITERIA';
diff --git a/ui/store/actions.ts b/ui/store/actions.ts
index a8fadb95ddeb..3dbf61ba0386 100644
--- a/ui/store/actions.ts
+++ b/ui/store/actions.ts
@@ -119,6 +119,7 @@ import { getMethodDataAsync } from '../../shared/lib/four-byte';
import { DecodedTransactionDataResponse } from '../../shared/types/transaction-decode';
import { LastInteractedConfirmationInfo } from '../pages/confirmations/types/confirm';
import { EndTraceRequest } from '../../shared/lib/trace';
+import { SortCriteria } from '../components/app/assets/util/sort';
import {
CaveatTypes,
EndowmentTypes,
@@ -3000,6 +3001,7 @@ export function setFeatureFlag(
export function setPreference(
preference: string,
value: boolean | string | object,
+ showLoading: boolan = true,
): ThunkAction<
Promise,
MetaMaskReduxState,
@@ -3007,13 +3009,13 @@ export function setPreference(
AnyAction
> {
return (dispatch: MetaMaskReduxDispatch) => {
- dispatch(showLoadingIndication());
+ showLoading && dispatch(showLoadingIndication());
return new Promise((resolve, reject) => {
callBackgroundMethod(
'setPreference',
[preference, value],
(err, updatedPreferences) => {
- dispatch(hideLoadingIndication());
+ showLoading && dispatch(hideLoadingIndication());
if (err) {
dispatch(displayWarning(err));
reject(err);
@@ -3083,6 +3085,10 @@ export function setRedesignedConfirmationsDeveloperEnabled(value: boolean) {
return setPreference('isRedesignedConfirmationsDeveloperEnabled', value);
}
+export function setTokenSortConfig(value: SortCriteria) {
+ return setPreference('tokenSortConfig', value, false);
+}
+
export function setSmartTransactionsOptInStatus(
value: boolean,
): ThunkAction {
From ad1fb6c77f3c53ffa62031874e4a3b70626d28f2 Mon Sep 17 00:00:00 2001
From: Matthew Walsh
Date: Wed, 9 Oct 2024 10:01:38 +0100
Subject: [PATCH 18/41] fix: UI startup with no Sentry DSN (#27714)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
Provide the correct functions to the mock scope used when Sentry is not
enabled.
Add unit tests to verify trace functions with no Sentry global object.
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27714?quickstart=1)
## **Related issues**
## **Manual testing steps**
## **Screenshots/Recordings**
### **Before**
### **After**
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
shared/lib/trace.test.ts | 37 +++++++++++++++++++++++++++++++++++++
shared/lib/trace.ts | 2 +-
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/shared/lib/trace.test.ts b/shared/lib/trace.test.ts
index 7cd39eba03d1..ff55ec0f2df0 100644
--- a/shared/lib/trace.test.ts
+++ b/shared/lib/trace.test.ts
@@ -170,6 +170,27 @@ describe('Trace', () => {
expect(setMeasurementMock).toHaveBeenCalledTimes(1);
expect(setMeasurementMock).toHaveBeenCalledWith('tag3', 123, 'none');
});
+
+ it('supports no global Sentry object', () => {
+ globalThis.sentry = undefined;
+
+ let callbackExecuted = false;
+
+ trace(
+ {
+ name: NAME_MOCK,
+ tags: TAGS_MOCK,
+ data: DATA_MOCK,
+ parentContext: PARENT_CONTEXT_MOCK,
+ startTime: 123,
+ },
+ () => {
+ callbackExecuted = true;
+ },
+ );
+
+ expect(callbackExecuted).toBe(true);
+ });
});
describe('endTrace', () => {
@@ -264,5 +285,21 @@ describe('Trace', () => {
expect(spanEndMock).toHaveBeenCalledTimes(0);
});
+
+ it('supports no global Sentry object', () => {
+ globalThis.sentry = undefined;
+
+ expect(() => {
+ trace({
+ name: NAME_MOCK,
+ id: ID_MOCK,
+ tags: TAGS_MOCK,
+ data: DATA_MOCK,
+ parentContext: PARENT_CONTEXT_MOCK,
+ });
+
+ endTrace({ name: NAME_MOCK, id: ID_MOCK });
+ }).not.toThrow();
+ });
});
});
diff --git a/shared/lib/trace.ts b/shared/lib/trace.ts
index a067858a969c..5ca256371502 100644
--- a/shared/lib/trace.ts
+++ b/shared/lib/trace.ts
@@ -352,7 +352,7 @@ function sentryWithIsolationScope(callback: (scope: Sentry.Scope) => T): T {
if (!actual) {
const scope = {
// eslint-disable-next-line no-empty-function
- setTags: () => {},
+ setTag: () => {},
} as unknown as Sentry.Scope;
return callback(scope);
From ca92f78cc1e94bdcd1fc7ade35a973ddf4bf484f Mon Sep 17 00:00:00 2001
From: Charly Chevalier
Date: Wed, 9 Oct 2024 13:53:10 +0200
Subject: [PATCH 19/41] fix(btc): fetch btc balance right after account
creation (#27628)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
The BTC balance is being refreshed automatically by the
`(Multichain)BalancesController` and the `(Multichain)BalanceTracker`,
this logic is running periodically and is being cached to avoid asking
the balance to frequently to the Bitcoin Snap.
An non-EVM is automatically being tracked when a
`AccountsController:accountAdded` is fired. However, since the
messenger's events are being run synchronously, having some asynchronous
calls might not be processed right away.
To workaround this, we are now force-fetching after the account
creation. This logic is being executed in an asynchronous context, which
means we can truly `await` the balance fetching which allows the UI to
be updated "instantly" (as fast as the Snap will fetch the balance in
the Bitcoin case).
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27628?quickstart=1)
## **Related issues**
N/A
## **Manual testing steps**
1. `yarn start:flask`
2. Enable bitcoin support: Settings > Experimental > "Enable bitcoin
support"
3. Create a mainnet account
4. The balance should show right away
You can also try the same steps with a testnet account, but it seems
that our current providers is having some problems with the testnet
balances.
## **Screenshots/Recordings**
### **Before**
https://github.com/user-attachments/assets/23f3c499-008a-4456-a00c-ad0cf4232b73
### **After**
https://github.com/user-attachments/assets/c602040c-922f-48c7-b526-a906da41d4f6
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
.../lib/accounts/BalancesController.ts | 9 +++
app/scripts/lib/accounts/BalancesTracker.ts | 3 +-
.../lib/snap-keyring/bitcoin-wallet-snap.ts | 30 ----------
shared/lib/accounts/bitcoin-wallet-snap.ts | 11 ++++
.../account-list-menu/account-list-menu.tsx | 28 +++------
.../useBitcoinWalletSnapClient.test.ts | 57 +++++++++++++++++++
.../accounts/useBitcoinWalletSnapClient.ts | 52 +++++++++++++++++
7 files changed, 140 insertions(+), 50 deletions(-)
delete mode 100644 app/scripts/lib/snap-keyring/bitcoin-wallet-snap.ts
create mode 100644 shared/lib/accounts/bitcoin-wallet-snap.ts
create mode 100644 ui/hooks/accounts/useBitcoinWalletSnapClient.test.ts
create mode 100644 ui/hooks/accounts/useBitcoinWalletSnapClient.ts
diff --git a/app/scripts/lib/accounts/BalancesController.ts b/app/scripts/lib/accounts/BalancesController.ts
index 9f9ead59ed90..e657fe47e64f 100644
--- a/app/scripts/lib/accounts/BalancesController.ts
+++ b/app/scripts/lib/accounts/BalancesController.ts
@@ -274,6 +274,8 @@ export class BalancesController extends BaseController<
* @param accountId - The account ID.
*/
async updateBalance(accountId: string) {
+ // NOTE: No need to track the account here, since we start tracking those when
+ // the "AccountsController:accountAdded" is fired.
await this.#tracker.updateBalance(accountId);
}
@@ -311,6 +313,13 @@ export class BalancesController extends BaseController<
}
this.#tracker.track(account.id, BTC_AVG_BLOCK_TIME);
+ // NOTE: Unfortunately, we cannot update the balance right away here, because
+ // messenger's events are running synchronously and fetching the balance is
+ // asynchronous.
+ // Updating the balance here would resume at some point but the event emitter
+ // will not `await` this (so we have no real control "when" the balance will
+ // really be updated), see:
+ // - https://github.com/MetaMask/core/blob/v213.0.0/packages/accounts-controller/src/AccountsController.ts#L1036-L1039
}
/**
diff --git a/app/scripts/lib/accounts/BalancesTracker.ts b/app/scripts/lib/accounts/BalancesTracker.ts
index 48ecd6f84cca..7359bcd2f8b6 100644
--- a/app/scripts/lib/accounts/BalancesTracker.ts
+++ b/app/scripts/lib/accounts/BalancesTracker.ts
@@ -102,7 +102,8 @@ export class BalancesTracker {
// and try to sync with the "real block time"!
const info = this.#balances[accountId];
const isOutdated = Date.now() - info.lastUpdated >= info.blockTime;
- if (isOutdated) {
+ const hasNoBalanceYet = info.lastUpdated === 0;
+ if (hasNoBalanceYet || isOutdated) {
await this.#updateBalance(accountId);
this.#balances[accountId].lastUpdated = Date.now();
}
diff --git a/app/scripts/lib/snap-keyring/bitcoin-wallet-snap.ts b/app/scripts/lib/snap-keyring/bitcoin-wallet-snap.ts
deleted file mode 100644
index 98f231607dba..000000000000
--- a/app/scripts/lib/snap-keyring/bitcoin-wallet-snap.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import { SnapId } from '@metamask/snaps-sdk';
-import { Sender } from '@metamask/keyring-api';
-import { HandlerType } from '@metamask/snaps-utils';
-import { Json, JsonRpcRequest } from '@metamask/utils';
-// This dependency is still installed as part of the `package.json`, however
-// the Snap is being pre-installed only for Flask build (for the moment).
-import BitcoinWalletSnap from '@metamask/bitcoin-wallet-snap/dist/preinstalled-snap.json';
-// TODO: Remove restricted import
-// eslint-disable-next-line import/no-restricted-paths
-import { handleSnapRequest } from '../../../../ui/store/actions';
-
-export const BITCOIN_WALLET_SNAP_ID: SnapId =
- BitcoinWalletSnap.snapId as SnapId;
-
-export const BITCOIN_WALLET_NAME: string =
- BitcoinWalletSnap.manifest.proposedName;
-
-export class BitcoinWalletSnapSender implements Sender {
- send = async (request: JsonRpcRequest): Promise => {
- // We assume the caller of this module is aware of this. If we try to use this module
- // without having the pre-installed Snap, this will likely throw an error in
- // the `handleSnapRequest` action.
- return (await handleSnapRequest({
- origin: 'metamask',
- snapId: BITCOIN_WALLET_SNAP_ID,
- handler: HandlerType.OnKeyringRequest,
- request,
- })) as Json;
- };
-}
diff --git a/shared/lib/accounts/bitcoin-wallet-snap.ts b/shared/lib/accounts/bitcoin-wallet-snap.ts
new file mode 100644
index 000000000000..58f367b173e1
--- /dev/null
+++ b/shared/lib/accounts/bitcoin-wallet-snap.ts
@@ -0,0 +1,11 @@
+import { SnapId } from '@metamask/snaps-sdk';
+// This dependency is still installed as part of the `package.json`, however
+// the Snap is being pre-installed only for Flask build (for the moment).
+import BitcoinWalletSnap from '@metamask/bitcoin-wallet-snap/dist/preinstalled-snap.json';
+
+// export const BITCOIN_WALLET_SNAP_ID: SnapId = 'local:http://localhost:8080';
+export const BITCOIN_WALLET_SNAP_ID: SnapId =
+ BitcoinWalletSnap.snapId as SnapId;
+
+export const BITCOIN_WALLET_NAME: string =
+ BitcoinWalletSnap.manifest.proposedName;
diff --git a/ui/components/multichain/account-list-menu/account-list-menu.tsx b/ui/components/multichain/account-list-menu/account-list-menu.tsx
index 99051042d2dd..2e5925dbf9cf 100644
--- a/ui/components/multichain/account-list-menu/account-list-menu.tsx
+++ b/ui/components/multichain/account-list-menu/account-list-menu.tsx
@@ -9,18 +9,13 @@ import {
///: BEGIN:ONLY_INCLUDE_IF(build-flask)
InternalAccount,
KeyringAccountType,
- KeyringClient,
///: END:ONLY_INCLUDE_IF
} from '@metamask/keyring-api';
///: BEGIN:ONLY_INCLUDE_IF(build-flask)
-import { CaipChainId } from '@metamask/utils';
import {
BITCOIN_WALLET_NAME,
BITCOIN_WALLET_SNAP_ID,
- BitcoinWalletSnapSender,
- // TODO: Remove restricted import
- // eslint-disable-next-line import/no-restricted-paths
-} from '../../../../app/scripts/lib/snap-keyring/bitcoin-wallet-snap';
+} from '../../../../shared/lib/accounts/bitcoin-wallet-snap';
///: END:ONLY_INCLUDE_IF
import {
Box,
@@ -97,6 +92,7 @@ import {
hasCreatedBtcTestnetAccount,
} from '../../../selectors/accounts';
import { MultichainNetworks } from '../../../../shared/constants/multichain/networks';
+import { useBitcoinWalletSnapClient } from '../../../hooks/accounts/useBitcoinWalletSnapClient';
///: END:ONLY_INCLUDE_IF
import {
InternalAccountWithBalance,
@@ -261,15 +257,7 @@ export const AccountListMenu = ({
hasCreatedBtcTestnetAccount,
);
- const createBitcoinAccount = async (scope: CaipChainId) => {
- // Client to create the account using the Bitcoin Snap
- const client = new KeyringClient(new BitcoinWalletSnapSender());
-
- // This will trigger the Snap account creation flow (+ account renaming)
- await client.createAccount({
- scope,
- });
- };
+ const bitcoinWalletSnapClient = useBitcoinWalletSnapClient();
///: END:ONLY_INCLUDE_IF
const [searchQuery, setSearchQuery] = useState('');
@@ -413,10 +401,12 @@ export const AccountListMenu = ({
// The account creation + renaming is handled by the
// Snap account bridge, so we need to close the current
- // model
+ // modal
onClose();
- await createBitcoinAccount(MultichainNetworks.BITCOIN);
+ await bitcoinWalletSnapClient.createAccount(
+ MultichainNetworks.BITCOIN,
+ );
}}
data-testid="multichain-account-menu-popover-add-btc-account"
>
@@ -436,10 +426,10 @@ export const AccountListMenu = ({
startIconName={IconName.Add}
onClick={async () => {
// The account creation + renaming is handled by the Snap account bridge, so
- // we need to close the current model
+ // we need to close the current modal
onClose();
- await createBitcoinAccount(
+ await bitcoinWalletSnapClient.createAccount(
MultichainNetworks.BITCOIN_TESTNET,
);
}}
diff --git a/ui/hooks/accounts/useBitcoinWalletSnapClient.test.ts b/ui/hooks/accounts/useBitcoinWalletSnapClient.test.ts
new file mode 100644
index 000000000000..6032a7636128
--- /dev/null
+++ b/ui/hooks/accounts/useBitcoinWalletSnapClient.test.ts
@@ -0,0 +1,57 @@
+import { renderHook } from '@testing-library/react-hooks';
+import { HandlerType } from '@metamask/snaps-utils';
+import { BtcAccountType, BtcMethod } from '@metamask/keyring-api';
+import { MultichainNetworks } from '../../../shared/constants/multichain/networks';
+import { BITCOIN_WALLET_SNAP_ID } from '../../../shared/lib/accounts/bitcoin-wallet-snap';
+import {
+ handleSnapRequest,
+ multichainUpdateBalance,
+} from '../../store/actions';
+import { useBitcoinWalletSnapClient } from './useBitcoinWalletSnapClient';
+
+jest.mock('../../store/actions', () => ({
+ handleSnapRequest: jest.fn(),
+ multichainUpdateBalance: jest.fn(),
+}));
+
+const mockHandleSnapRequest = handleSnapRequest as jest.Mock;
+const mockMultichainUpdateBalance = multichainUpdateBalance as jest.Mock;
+
+describe('useBitcoinWalletSnapClient', () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ const mockAccount = {
+ address: 'tb1q2hjrlnf8kmtt5dj6e49gqzy6jnpe0sj7ty50cl',
+ id: '11a33c6b-0d46-43f4-a401-01587d575fd0',
+ options: {},
+ methods: [BtcMethod.SendMany],
+ type: BtcAccountType.P2wpkh,
+ };
+
+ it('dispatch a Snap keyring request to create a Bitcoin account', async () => {
+ const { result } = renderHook(() => useBitcoinWalletSnapClient());
+ const bitcoinWalletSnapClient = result.current;
+
+ mockHandleSnapRequest.mockResolvedValue(mockAccount);
+
+ await bitcoinWalletSnapClient.createAccount(MultichainNetworks.BITCOIN);
+ expect(mockHandleSnapRequest).toHaveBeenCalledWith({
+ origin: 'metamask',
+ snapId: BITCOIN_WALLET_SNAP_ID,
+ handler: HandlerType.OnKeyringRequest,
+ request: expect.any(Object),
+ });
+ });
+
+ it('force fetches the balance after creating a Bitcoin account', async () => {
+ const { result } = renderHook(() => useBitcoinWalletSnapClient());
+ const bitcoinWalletSnapClient = result.current;
+
+ mockHandleSnapRequest.mockResolvedValue(mockAccount);
+
+ await bitcoinWalletSnapClient.createAccount(MultichainNetworks.BITCOIN);
+ expect(mockMultichainUpdateBalance).toHaveBeenCalledWith(mockAccount.id);
+ });
+});
diff --git a/ui/hooks/accounts/useBitcoinWalletSnapClient.ts b/ui/hooks/accounts/useBitcoinWalletSnapClient.ts
new file mode 100644
index 000000000000..debe911ac391
--- /dev/null
+++ b/ui/hooks/accounts/useBitcoinWalletSnapClient.ts
@@ -0,0 +1,52 @@
+import { KeyringClient, Sender } from '@metamask/keyring-api';
+import { HandlerType } from '@metamask/snaps-utils';
+import { CaipChainId, Json, JsonRpcRequest } from '@metamask/utils';
+import { useMemo } from 'react';
+import {
+ handleSnapRequest,
+ multichainUpdateBalance,
+} from '../../store/actions';
+import { BITCOIN_WALLET_SNAP_ID } from '../../../shared/lib/accounts/bitcoin-wallet-snap';
+
+export class BitcoinWalletSnapSender implements Sender {
+ send = async (request: JsonRpcRequest): Promise => {
+ // We assume the caller of this module is aware of this. If we try to use this module
+ // without having the pre-installed Snap, this will likely throw an error in
+ // the `handleSnapRequest` action.
+ return (await handleSnapRequest({
+ origin: 'metamask',
+ snapId: BITCOIN_WALLET_SNAP_ID,
+ handler: HandlerType.OnKeyringRequest,
+ request,
+ })) as Json;
+ };
+}
+
+export class BitcoinWalletSnapClient {
+ readonly #client: KeyringClient;
+
+ constructor() {
+ this.#client = new KeyringClient(new BitcoinWalletSnapSender());
+ }
+
+ async createAccount(scope: CaipChainId) {
+ // This will trigger the Snap account creation flow (+ account renaming)
+ const account = await this.#client.createAccount({
+ scope,
+ });
+
+ // NOTE: The account's balance is going to be tracked automatically on when the new account
+ // will be added to the Snap bridge keyring (see `BalancesController:#handleOnAccountAdded`).
+ // However, the balance won't be fetched right away. To workaround this, we trigger the
+ // fetch explicitly here (since we are already in a `async` call) and wait for it to be updated!
+ await multichainUpdateBalance(account.id);
+ }
+}
+
+export function useBitcoinWalletSnapClient() {
+ const client = useMemo(() => {
+ return new BitcoinWalletSnapClient();
+ }, []);
+
+ return client;
+}
From 583d400d6d88087f6ec1659589f9f4c1a3ae4650 Mon Sep 17 00:00:00 2001
From: Pedro Figueiredo
Date: Wed, 9 Oct 2024 13:22:24 +0100
Subject: [PATCH 20/41] fix: Prefer token symbol to token name (#27693)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
The petnames component defaults to show the name of the token instead of
the symbol. Adding `preferContractSymbol` to the component overrides it
to show the token symbol instead, for brevity.
The PR adds the prop to petnames components inside tx simulations and
the address row component.
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27693?quickstart=1)
## **Related issues**
Fixes: https://github.com/MetaMask/MetaMask-planning/issues/3371
## **Manual testing steps**
1. Go to this page...
2.
3.
## **Screenshots/Recordings**
### **Before**
### **After**
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
ui/components/app/confirm/info/row/address.tsx | 6 +++++-
.../approve-static-simulation.tsx | 1 +
.../revoke-static-simulation/revoke-static-simulation.tsx | 2 ++
.../revoke-set-approval-for-all-static-simulation.tsx | 7 ++++++-
.../set-approval-for-all-static-simulation.tsx | 1 +
.../permit-simulation/value-display/value-display.tsx | 6 +++++-
6 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/ui/components/app/confirm/info/row/address.tsx b/ui/components/app/confirm/info/row/address.tsx
index ec8a0c7c669d..7d28851ece92 100644
--- a/ui/components/app/confirm/info/row/address.tsx
+++ b/ui/components/app/confirm/info/row/address.tsx
@@ -44,7 +44,11 @@ export const ConfirmInfoRowAddress = memo(
// component can support variations. See this comment for context: //
// https://github.com/MetaMask/metamask-extension/pull/23487#discussion_r1525055546
isPetNamesEnabled && !isSnapUsingThis ? (
-
+
) : (
<>
{
diff --git a/ui/pages/confirmations/components/confirm/info/approve/revoke-static-simulation/revoke-static-simulation.tsx b/ui/pages/confirmations/components/confirm/info/approve/revoke-static-simulation/revoke-static-simulation.tsx
index 199852538f17..38ff93ba9b36 100644
--- a/ui/pages/confirmations/components/confirm/info/approve/revoke-static-simulation/revoke-static-simulation.tsx
+++ b/ui/pages/confirmations/components/confirm/info/approve/revoke-static-simulation/revoke-static-simulation.tsx
@@ -23,6 +23,7 @@ export const RevokeStaticSimulation = () => {
@@ -36,6 +37,7 @@ export const RevokeStaticSimulation = () => {
diff --git a/ui/pages/confirmations/components/confirm/info/set-approval-for-all-info/revoke-set-approval-for-all-static-simulation/revoke-set-approval-for-all-static-simulation.tsx b/ui/pages/confirmations/components/confirm/info/set-approval-for-all-info/revoke-set-approval-for-all-static-simulation/revoke-set-approval-for-all-static-simulation.tsx
index 7cc141fb64e5..64e90a7066e6 100644
--- a/ui/pages/confirmations/components/confirm/info/set-approval-for-all-info/revoke-set-approval-for-all-static-simulation/revoke-set-approval-for-all-static-simulation.tsx
+++ b/ui/pages/confirmations/components/confirm/info/set-approval-for-all-info/revoke-set-approval-for-all-static-simulation/revoke-set-approval-for-all-static-simulation.tsx
@@ -29,6 +29,7 @@ export const RevokeSetApprovalForAllStaticSimulation = ({
@@ -39,7 +40,11 @@ export const RevokeSetApprovalForAllStaticSimulation = ({
-
+
diff --git a/ui/pages/confirmations/components/confirm/info/set-approval-for-all-info/set-approval-for-all-static-simulation/set-approval-for-all-static-simulation.tsx b/ui/pages/confirmations/components/confirm/info/set-approval-for-all-info/set-approval-for-all-static-simulation/set-approval-for-all-static-simulation.tsx
index c50d10094486..177ef4080860 100644
--- a/ui/pages/confirmations/components/confirm/info/set-approval-for-all-info/set-approval-for-all-static-simulation/set-approval-for-all-static-simulation.tsx
+++ b/ui/pages/confirmations/components/confirm/info/set-approval-for-all-info/set-approval-for-all-static-simulation/set-approval-for-all-static-simulation.tsx
@@ -47,6 +47,7 @@ export const SetApprovalForAllStaticSimulation = () => {
diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.tsx
index 25fad3020103..633191cd2638 100644
--- a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.tsx
+++ b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.tsx
@@ -116,7 +116,11 @@ const PermitSimulationValueDisplay: React.FC<
-
+
{fiatValue && }
From 65e656c95fb71fbc401bcedb4600f9c9ec13b5bb Mon Sep 17 00:00:00 2001
From: "devin-ai-integration[bot]"
<158243242+devin-ai-integration[bot]@users.noreply.github.com>
Date: Wed, 9 Oct 2024 14:35:20 +0200
Subject: [PATCH 21/41] test: [POM] Migrate create snap account e2e tests to
page object modal (#27697)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
This PR migrates the create-snap-account e2e tests to the Page Object
Model (POM) pattern, improving test stability and maintainability.
Changes include:
- Migrate test create-snap-account.spec.ts to POM
- Avoid several delays in the original function implementation
- remove create single account testcase because we already test it in
`test/e2e/tests/account/create-remove-account-snap.spec.ts `
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27155?quickstart=1)
## **Related issues**
Fixes: https://github.com/MetaMask/metamask-extension/issues/27699
## **Manual testing steps**
Check code readability, make sure tests pass.
## **Screenshots/Recordings**
### **Before**
### **After**
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---------
Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Chloe Gao
---
test/e2e/accounts/create-snap-account.spec.ts | 345 ------------------
.../pages/snap-simple-keyring-page.ts | 73 +++-
....ts => create-remove-account-snap.spec.ts} | 4 +-
.../tests/account/create-snap-account.spec.ts | 140 +++++++
4 files changed, 208 insertions(+), 354 deletions(-)
delete mode 100644 test/e2e/accounts/create-snap-account.spec.ts
rename test/e2e/tests/account/{remove-account-snap.spec.ts => create-remove-account-snap.spec.ts} (93%)
create mode 100644 test/e2e/tests/account/create-snap-account.spec.ts
diff --git a/test/e2e/accounts/create-snap-account.spec.ts b/test/e2e/accounts/create-snap-account.spec.ts
deleted file mode 100644
index 2a35b4b4c805..000000000000
--- a/test/e2e/accounts/create-snap-account.spec.ts
+++ /dev/null
@@ -1,345 +0,0 @@
-import { Suite } from 'mocha';
-
-import FixtureBuilder from '../fixture-builder';
-import { defaultGanacheOptions, WINDOW_TITLES, withFixtures } from '../helpers';
-import { Driver } from '../webdriver/driver';
-import { installSnapSimpleKeyring } from './common';
-
-/**
- * Starts the flow to create a Snap account, including unlocking the wallet,
- * connecting to the test Snaps page, installing the Snap, and initiating the
- * create account process on the dapp. The function ends with switching to the
- * first confirmation in the extension.
- *
- * @param driver - The WebDriver instance used to control the browser.
- * @returns A promise that resolves when the setup steps are complete.
- */
-async function startCreateSnapAccountFlow(driver: Driver): Promise {
- await installSnapSimpleKeyring(driver, false);
-
- // move back to the Snap window to test the create account flow
- await driver.waitAndSwitchToWindowWithTitle(
- 2,
- WINDOW_TITLES.SnapSimpleKeyringDapp,
- );
-
- // 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',
- });
-
- await driver.clickElement({
- text: 'Create Account',
- tag: 'button',
- });
-
- // Wait until dialog is opened before proceeding
- await driver.waitAndSwitchToWindowWithTitle(3, WINDOW_TITLES.Dialog);
-}
-
-describe('Create Snap Account', function (this: Suite) {
- it('create Snap account popup contains correct Snap name and snapId', async function () {
- await withFixtures(
- {
- fixtures: new FixtureBuilder().build(),
- ganacheOptions: defaultGanacheOptions,
- title: this.test?.fullTitle(),
- },
- async ({ driver }: { driver: Driver }) => {
- // start the create account flow and switch to dialog window
- await startCreateSnapAccountFlow(driver);
-
- await driver.findElement({
- css: '[data-testid="confirmation-submit-button"]',
- text: 'Create',
- });
-
- await driver.findElement({
- css: '[data-testid="confirmation-cancel-button"]',
- text: 'Cancel',
- });
-
- await driver.findElement({
- css: '[data-testid="create-snap-account-content-title"]',
- text: 'Create account',
- });
- },
- );
- });
-
- it('create Snap account confirmation flow ends in approval success', async function () {
- await withFixtures(
- {
- fixtures: new FixtureBuilder().build(),
- ganacheOptions: defaultGanacheOptions,
- title: this.test?.fullTitle(),
- },
- async ({ driver }: { driver: Driver }) => {
- // start the create account flow and switch to dialog window
- await startCreateSnapAccountFlow(driver);
-
- // click the create button on the confirmation modal
- await driver.clickElement('[data-testid="confirmation-submit-button"]');
-
- // click the add account button on the naming modal
- await driver.clickElement(
- '[data-testid="submit-add-account-with-name"]',
- );
-
- // success screen should show account created with the snap suggested name
- await driver.findElement({
- tag: 'h3',
- text: 'Account created',
- });
- await driver.findElement({
- css: '.multichain-account-list-item__account-name__button',
- text: 'SSK Account',
- });
-
- // click the okay button
- await driver.clickElement('[data-testid="confirmation-submit-button"]');
-
- // switch back to the test dapp/Snap window
- await driver.waitAndSwitchToWindowWithTitle(
- 2,
- WINDOW_TITLES.SnapSimpleKeyringDapp,
- );
-
- // account should be created on the dapp
- await driver.findElement({
- tag: 'p',
- text: 'Successful request',
- });
-
- // switch to extension full screen view
- await driver.switchToWindowWithTitle(
- WINDOW_TITLES.ExtensionInFullScreenView,
- );
-
- // account should be created with the snap suggested name
- await driver.findElement({
- css: '[data-testid="account-menu-icon"]',
- text: 'SSK Account',
- });
- },
- );
- });
-
- it('creates multiple Snap accounts with increasing numeric suffixes', async function () {
- await withFixtures(
- {
- fixtures: new FixtureBuilder().build(),
- ganacheOptions: defaultGanacheOptions,
- title: this.test?.fullTitle(),
- },
- async ({ driver }: { driver: Driver }) => {
- await installSnapSimpleKeyring(driver, false);
-
- const expectedNames = ['SSK Account', 'SSK Account 2', 'SSK Account 3'];
-
- for (const [index, expectedName] of expectedNames.entries()) {
- // move to the dapp window
- await driver.waitAndSwitchToWindowWithTitle(
- 2,
- WINDOW_TITLES.SnapSimpleKeyringDapp,
- );
-
- // create new account on dapp
- if (index === 0) {
- // Only click the div for the first snap account creation
- await driver.clickElement({
- text: 'Create account',
- tag: 'div',
- });
- }
- await driver.clickElement({
- text: 'Create Account',
- tag: 'button',
- });
-
- // wait until dialog is opened before proceeding
- await driver.waitAndSwitchToWindowWithTitle(3, WINDOW_TITLES.Dialog);
-
- // click the create button on the confirmation modal
- await driver.clickElement(
- '[data-testid="confirmation-submit-button"]',
- );
-
- // click the add account button on the naming modal
- await driver.clickElement(
- '[data-testid="submit-add-account-with-name"]',
- );
-
- // click the okay button on the success screen
- await driver.clickElement(
- '[data-testid="confirmation-submit-button"]',
- );
-
- // switch to extension full screen view
- await driver.switchToWindowWithTitle(
- WINDOW_TITLES.ExtensionInFullScreenView,
- );
-
- // verify the account is created with the expected name
- await driver.findElement({
- css: '[data-testid="account-menu-icon"]',
- text: expectedName,
- });
- }
- },
- );
- });
-
- it('create Snap account confirmation flow ends in approval success with custom name input', async function () {
- await withFixtures(
- {
- fixtures: new FixtureBuilder().build(),
- ganacheOptions: defaultGanacheOptions,
- title: this.test?.fullTitle(),
- },
- async ({ driver }: { driver: Driver }) => {
- // start the create account flow and switch to dialog window
- await startCreateSnapAccountFlow(driver);
-
- // click the create button on the confirmation modal
- await driver.clickElement('[data-testid="confirmation-submit-button"]');
-
- // Add a custom name to the account
- const newAccountLabel = 'Custom name';
- await driver.fill('[placeholder="SSK Account"]', newAccountLabel);
- // click the add account button on the naming modal
- await driver.clickElement(
- '[data-testid="submit-add-account-with-name"]',
- );
-
- // success screen should show account created with the custom name
- await driver.findElement({
- tag: 'h3',
- text: 'Account created',
- });
- await driver.findElement({
- css: '.multichain-account-list-item__account-name__button',
- text: newAccountLabel,
- });
-
- // click the okay button
- await driver.clickElement('[data-testid="confirmation-submit-button"]');
-
- // switch back to the test dapp/Snap window
- await driver.waitAndSwitchToWindowWithTitle(
- 2,
- WINDOW_TITLES.SnapSimpleKeyringDapp,
- );
-
- // account should be created on the dapp
- await driver.findElement({
- tag: 'p',
- text: 'Successful request',
- });
-
- // switch to extension full screen view
- await driver.switchToWindowWithTitle(
- WINDOW_TITLES.ExtensionInFullScreenView,
- );
-
- // account should be created with the custom name
- await driver.findElement({
- css: '[data-testid="account-menu-icon"]',
- text: newAccountLabel,
- });
- },
- );
- });
-
- it('create Snap account confirmation cancellation results in error in Snap', async function () {
- await withFixtures(
- {
- fixtures: new FixtureBuilder().build(),
- ganacheOptions: defaultGanacheOptions,
- title: this.test?.fullTitle(),
- },
- async ({ driver }: { driver: Driver }) => {
- // start the create account flow and switch to dialog window
- await startCreateSnapAccountFlow(driver);
-
- // cancel account creation
- await driver.clickElement('[data-testid="confirmation-cancel-button"]');
-
- // switch back to the test dapp/Snap window
- await driver.waitAndSwitchToWindowWithTitle(
- 2,
- WINDOW_TITLES.SnapSimpleKeyringDapp,
- );
-
- // account should not be created in Snap
- await driver.findElement({
- tag: 'p',
- text: 'Error request',
- });
-
- // switch to extension full screen view
- await driver.switchToWindowWithTitle(
- WINDOW_TITLES.ExtensionInFullScreenView,
- );
-
- // account should not be created
- await driver.assertElementNotPresent({
- css: '[data-testid="account-menu-icon"]',
- text: 'SSK Account',
- });
- },
- );
- });
-
- it('cancelling naming Snap account results in account not created', async function () {
- await withFixtures(
- {
- fixtures: new FixtureBuilder().build(),
- ganacheOptions: defaultGanacheOptions,
- title: this.test?.fullTitle(),
- },
- async ({ driver }: { driver: Driver }) => {
- // start the create account flow and switch to dialog window
- await startCreateSnapAccountFlow(driver);
-
- // confirm account creation
- await driver.clickElement('[data-testid="confirmation-submit-button"]');
-
- // click the cancel button on the naming modal
- await driver.clickElement(
- '[data-testid="cancel-add-account-with-name"]',
- );
-
- // switch back to the test dapp/Snap window
- await driver.waitAndSwitchToWindowWithTitle(
- 2,
- WINDOW_TITLES.SnapSimpleKeyringDapp,
- );
-
- // account should not be created in Snap
- await driver.findElement({
- tag: 'p',
- text: 'Error request',
- });
-
- // switch to extension full screen view
- await driver.switchToWindowWithTitle(
- WINDOW_TITLES.ExtensionInFullScreenView,
- );
-
- // account should not be created
- await driver.assertElementNotPresent({
- css: '[data-testid="account-menu-icon"]',
- text: 'SSK Account',
- });
- },
- );
- });
-});
diff --git a/test/e2e/page-objects/pages/snap-simple-keyring-page.ts b/test/e2e/page-objects/pages/snap-simple-keyring-page.ts
index 8b20f1bc3bc0..fd4ae9d1ecc1 100644
--- a/test/e2e/page-objects/pages/snap-simple-keyring-page.ts
+++ b/test/e2e/page-objects/pages/snap-simple-keyring-page.ts
@@ -19,11 +19,17 @@ class SnapSimpleKeyringPage {
tag: 'h3',
};
+ private readonly cancelAddAccountWithNameButton =
+ '[data-testid="cancel-add-account-with-name"]';
+
private readonly confirmAddtoMetamask = {
text: 'Confirm',
tag: 'button',
};
+ private readonly confirmationCancelButton =
+ '[data-testid="confirmation-cancel-button"]';
+
private readonly confirmationSubmitButton =
'[data-testid="confirmation-submit-button"]';
@@ -54,6 +60,11 @@ class SnapSimpleKeyringPage {
private readonly createSnapAccountName = '#account-name';
+ private readonly errorRequestMessage = {
+ text: 'Error request',
+ tag: 'p',
+ };
+
private readonly installationCompleteMessage = {
text: 'Installation complete',
tag: 'h2',
@@ -95,19 +106,41 @@ class SnapSimpleKeyringPage {
console.log('Snap Simple Keyring page is loaded');
}
+ async cancelCreateSnapOnConfirmationScreen(): Promise {
+ console.log('Cancel create snap on confirmation screen');
+ await this.driver.clickElementAndWaitForWindowToClose(
+ this.confirmationCancelButton,
+ );
+ }
+
+ async cancelCreateSnapOnFillNameScreen(): Promise {
+ console.log('Cancel create snap on fill name screen');
+ await this.driver.clickElementAndWaitForWindowToClose(
+ this.cancelAddAccountWithNameButton,
+ );
+ }
+
+ async confirmCreateSnapOnConfirmationScreen(): Promise {
+ console.log('Confirm create snap on confirmation screen');
+ await this.driver.clickElement(this.confirmationSubmitButton);
+ }
+
/**
* Creates a new account on the Snap Simple Keyring page and checks the account is created.
+ *
+ * @param accountName - Optional: name for the snap account. Defaults to "SSK Account".
+ * @param isFirstAccount - Indicates if this is the first snap account being created. Defaults to true.
*/
- async createNewAccount(): Promise {
+ async createNewAccount(
+ accountName: string = 'SSK Account',
+ isFirstAccount: boolean = true,
+ ): Promise {
console.log('Create new account on Snap Simple Keyring page');
- await this.driver.clickElement(this.createAccountSection);
- await this.driver.clickElement(this.createAccountButton);
-
- await this.driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await this.driver.waitForSelector(this.createAccountMessage);
- await this.driver.clickElement(this.confirmationSubmitButton);
+ await this.openCreateSnapAccountConfirmationScreen(isFirstAccount);
+ await this.confirmCreateSnapOnConfirmationScreen();
await this.driver.waitForSelector(this.createSnapAccountName);
+ await this.driver.fill(this.createSnapAccountName, accountName);
await this.driver.clickElement(this.submitAddAccountWithNameButton);
await this.driver.waitForSelector(this.accountCreatedMessage);
@@ -146,6 +179,25 @@ class SnapSimpleKeyringPage {
await this.check_simpleKeyringSnapConnected();
}
+ /**
+ * Opens the create snap account confirmation screen.
+ *
+ * @param isFirstAccount - Indicates if this is the first snap account being created. Defaults to true.
+ */
+ async openCreateSnapAccountConfirmationScreen(
+ isFirstAccount: boolean = true,
+ ): Promise {
+ console.log('Open create snap account confirmation screen');
+ if (isFirstAccount) {
+ await this.driver.clickElement(this.createAccountSection);
+ }
+ await this.driver.clickElement(this.createAccountButton);
+
+ await this.driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+ await this.driver.waitForSelector(this.createAccountMessage);
+ await this.driver.waitForSelector(this.confirmationCancelButton);
+ }
+
async toggleUseSyncApproval() {
console.log('Toggle Use Synchronous Approval');
await this.driver.clickElement(this.useSyncApprovalToggle);
@@ -158,6 +210,13 @@ class SnapSimpleKeyringPage {
await this.driver.waitForSelector(this.accountSupportedMethods);
}
+ async check_errorRequestMessageDisplayed(): Promise {
+ console.log(
+ 'Check error request message is displayed on snap simple keyring page',
+ );
+ await this.driver.waitForSelector(this.errorRequestMessage);
+ }
+
async check_simpleKeyringSnapConnected(): Promise {
console.log('Check simple keyring snap is connected');
await this.driver.waitForSelector(this.snapConnectedMessage);
diff --git a/test/e2e/tests/account/remove-account-snap.spec.ts b/test/e2e/tests/account/create-remove-account-snap.spec.ts
similarity index 93%
rename from test/e2e/tests/account/remove-account-snap.spec.ts
rename to test/e2e/tests/account/create-remove-account-snap.spec.ts
index 2f0e2ab96a33..5d8517f66b26 100644
--- a/test/e2e/tests/account/remove-account-snap.spec.ts
+++ b/test/e2e/tests/account/create-remove-account-snap.spec.ts
@@ -9,8 +9,8 @@ import SnapSimpleKeyringPage from '../../page-objects/pages/snap-simple-keyring-
import { installSnapSimpleKeyring } from '../../page-objects/flows/snap-simple-keyring.flow';
import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow';
-describe('Remove Account Snap @no-mmi', function (this: Suite) {
- it('disable a snap and remove it', async function () {
+describe('Create and remove Snap Account @no-mmi', function (this: Suite) {
+ it('create snap account and remove it by removing snap', async function () {
await withFixtures(
{
fixtures: new FixtureBuilder().build(),
diff --git a/test/e2e/tests/account/create-snap-account.spec.ts b/test/e2e/tests/account/create-snap-account.spec.ts
new file mode 100644
index 000000000000..387b7149c53c
--- /dev/null
+++ b/test/e2e/tests/account/create-snap-account.spec.ts
@@ -0,0 +1,140 @@
+import { Suite } from 'mocha';
+import { Driver } from '../../webdriver/driver';
+import FixtureBuilder from '../../fixture-builder';
+import { withFixtures, WINDOW_TITLES } from '../../helpers';
+import AccountListPage from '../../page-objects/pages/account-list-page';
+import HeaderNavbar from '../../page-objects/pages/header-navbar';
+import SnapSimpleKeyringPage from '../../page-objects/pages/snap-simple-keyring-page';
+import { installSnapSimpleKeyring } from '../../page-objects/flows/snap-simple-keyring.flow';
+import { loginWithBalanceValidation } from '../../page-objects/flows/login.flow';
+
+describe('Create Snap Account @no-mmi', function (this: Suite) {
+ it('create Snap account with custom name input ends in approval success', async function () {
+ await withFixtures(
+ {
+ fixtures: new FixtureBuilder().build(),
+ title: this.test?.fullTitle(),
+ },
+ async ({ driver }: { driver: Driver }) => {
+ await loginWithBalanceValidation(driver);
+ await installSnapSimpleKeyring(driver);
+ const snapSimpleKeyringPage = new SnapSimpleKeyringPage(driver);
+
+ const newCustomAccountLabel = 'Custom name';
+ await snapSimpleKeyringPage.createNewAccount(newCustomAccountLabel);
+
+ // Check snap account is displayed after adding the custom snap account.
+ await driver.switchToWindowWithTitle(
+ WINDOW_TITLES.ExtensionInFullScreenView,
+ );
+ await new HeaderNavbar(driver).check_accountLabel(
+ newCustomAccountLabel,
+ );
+ },
+ );
+ });
+
+ it('creates multiple Snap accounts with increasing numeric suffixes', async function () {
+ await withFixtures(
+ {
+ fixtures: new FixtureBuilder().build(),
+ title: this.test?.fullTitle(),
+ },
+ async ({ driver }: { driver: Driver }) => {
+ await loginWithBalanceValidation(driver);
+ await installSnapSimpleKeyring(driver);
+ const snapSimpleKeyringPage = new SnapSimpleKeyringPage(driver);
+ const expectedNames = ['SSK Account', 'SSK Account 2', 'SSK Account 3'];
+
+ // Create multiple snap accounts on snap simple keyring page
+ for (const expectedName of expectedNames) {
+ if (expectedName === 'SSK Account') {
+ await snapSimpleKeyringPage.createNewAccount(expectedName, true);
+ } else {
+ await snapSimpleKeyringPage.createNewAccount(expectedName, false);
+ }
+ }
+
+ // Check 3 created snap accounts are displayed in the account list.
+ await driver.switchToWindowWithTitle(
+ WINDOW_TITLES.ExtensionInFullScreenView,
+ );
+ await new HeaderNavbar(driver).openAccountMenu();
+ const accountListPage = new AccountListPage(driver);
+ await accountListPage.check_pageIsLoaded();
+ for (const expectedName of expectedNames) {
+ await accountListPage.check_accountDisplayedInAccountList(
+ expectedName,
+ );
+ }
+ },
+ );
+ });
+
+ it('create Snap account canceling on confirmation screen results in error on Snap', async function () {
+ await withFixtures(
+ {
+ fixtures: new FixtureBuilder().build(),
+ title: this.test?.fullTitle(),
+ },
+ async ({ driver }: { driver: Driver }) => {
+ await loginWithBalanceValidation(driver);
+ await installSnapSimpleKeyring(driver);
+ const snapSimpleKeyringPage = new SnapSimpleKeyringPage(driver);
+
+ // cancel snap account creation on confirmation screen
+ await snapSimpleKeyringPage.openCreateSnapAccountConfirmationScreen();
+ await snapSimpleKeyringPage.cancelCreateSnapOnConfirmationScreen();
+ await driver.switchToWindowWithTitle(
+ WINDOW_TITLES.SnapSimpleKeyringDapp,
+ );
+ await snapSimpleKeyringPage.check_errorRequestMessageDisplayed();
+
+ // Check snap account is not displayed in account list after canceling the creation
+ await driver.switchToWindowWithTitle(
+ WINDOW_TITLES.ExtensionInFullScreenView,
+ );
+ await new HeaderNavbar(driver).openAccountMenu();
+ const accountListPage = new AccountListPage(driver);
+ await accountListPage.check_pageIsLoaded();
+ await accountListPage.check_accountIsNotDisplayedInAccountList(
+ 'SSK Account',
+ );
+ },
+ );
+ });
+
+ it('create Snap account canceling on fill name screen results in error on Snap', async function () {
+ await withFixtures(
+ {
+ fixtures: new FixtureBuilder().build(),
+ title: this.test?.fullTitle(),
+ },
+ async ({ driver }: { driver: Driver }) => {
+ await loginWithBalanceValidation(driver);
+ await installSnapSimpleKeyring(driver);
+ const snapSimpleKeyringPage = new SnapSimpleKeyringPage(driver);
+
+ // cancel snap account creation on fill name screen
+ await snapSimpleKeyringPage.openCreateSnapAccountConfirmationScreen();
+ await snapSimpleKeyringPage.confirmCreateSnapOnConfirmationScreen();
+ await snapSimpleKeyringPage.cancelCreateSnapOnFillNameScreen();
+ await driver.switchToWindowWithTitle(
+ WINDOW_TITLES.SnapSimpleKeyringDapp,
+ );
+ await snapSimpleKeyringPage.check_errorRequestMessageDisplayed();
+
+ // Check snap account is not displayed in account list after canceling the creation
+ await driver.switchToWindowWithTitle(
+ WINDOW_TITLES.ExtensionInFullScreenView,
+ );
+ await new HeaderNavbar(driver).openAccountMenu();
+ const accountListPage = new AccountListPage(driver);
+ await accountListPage.check_pageIsLoaded();
+ await accountListPage.check_accountIsNotDisplayedInAccountList(
+ 'SSK Account',
+ );
+ },
+ );
+ });
+});
From 8f2bab54f6cb8bc092348b0863bdb4239398efc0 Mon Sep 17 00:00:00 2001
From: Pedro Figueiredo
Date: Wed, 9 Oct 2024 17:30:11 +0100
Subject: [PATCH 22/41] fix: Limit amount of decimals on spending cap modal
(#27672)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
If the user tries to add more decimals to the spending cap than what the
token supports, the spending cap cannot be submitted and a notice is
displayed.
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27672?quickstart=1)
## **Related issues**
Fixes: https://github.com/MetaMask/metamask-extension/issues/27618
## **Manual testing steps**
1. Go to this page...
2.
3.
## **Screenshots/Recordings**
### **Before**
### **After**
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
app/_locales/en/messages.json | 3 ++
.../edit-spending-cap-modal.test.tsx | 28 ++++++++++++++++++-
.../edit-spending-cap-modal.tsx | 25 +++++++++++++++--
3 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index 60ec9579059d..b7345f8d4f6c 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -1838,6 +1838,9 @@
"editSpendingCapDesc": {
"message": "Enter the amount that you feel comfortable being spent on your behalf."
},
+ "editSpendingCapError": {
+ "message": "The spending cap can’t exceed $1 decimal digits. Remove decimal digits to continue."
+ },
"enable": {
"message": "Enable"
},
diff --git a/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.test.tsx b/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.test.tsx
index e4604fb715ab..448506f17126 100644
--- a/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.test.tsx
+++ b/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.test.tsx
@@ -3,7 +3,10 @@ import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { getMockApproveConfirmState } from '../../../../../../../../test/data/confirmations/helper';
import { renderWithConfirmContextProvider } from '../../../../../../../../test/lib/confirmations/render-helpers';
-import { EditSpendingCapModal } from './edit-spending-cap-modal';
+import {
+ countDecimalDigits,
+ EditSpendingCapModal,
+} from './edit-spending-cap-modal';
jest.mock('react-dom', () => ({
...jest.requireActual('react-dom'),
@@ -78,3 +81,26 @@ describe(' ', () => {
expect(container).toMatchSnapshot();
});
});
+
+describe('countDecimalDigits()', () => {
+ // @ts-expect-error This is missing from the Mocha type definitions
+ it.each([
+ { numberString: '0', expectedDecimals: 0 },
+ { numberString: '100', expectedDecimals: 0 },
+ { numberString: '100.123', expectedDecimals: 3 },
+ { numberString: '3.141592654', expectedDecimals: 9 },
+ ])(
+ 'should return $expectedDecimals decimals for `$numberString`',
+ ({
+ numberString,
+ expectedDecimals,
+ }: {
+ numberString: string;
+ expectedDecimals: number;
+ }) => {
+ const actual = countDecimalDigits(numberString);
+
+ expect(actual).toEqual(expectedDecimals);
+ },
+ );
+});
diff --git a/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx b/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx
index e7431457f5c2..2762e99652a5 100644
--- a/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx
+++ b/ui/pages/confirmations/components/confirm/info/approve/edit-spending-cap-modal/edit-spending-cap-modal.tsx
@@ -32,6 +32,10 @@ import { useConfirmContext } from '../../../../../context/confirm';
import { useAssetDetails } from '../../../../../hooks/useAssetDetails';
import { useApproveTokenSimulation } from '../hooks/use-approve-token-simulation';
+export function countDecimalDigits(numberString: string) {
+ return numberString.split('.')[1]?.length || 0;
+}
+
export const EditSpendingCapModal = ({
isOpenEditSpendingCapModal,
setIsOpenEditSpendingCapModal,
@@ -116,10 +120,14 @@ export const EditSpendingCapModal = ({
setCustomSpendingCapInputValue(formattedSpendingCap.toString());
}, [customSpendingCapInputValue, formattedSpendingCap]);
+ const showDecimalError =
+ decimals &&
+ parseInt(decimals, 10) < countDecimalDigits(customSpendingCapInputValue);
+
return (
setIsOpenEditSpendingCapModal(false)}
+ onClose={handleCancel}
isClosedOnEscapeKey
isClosedOnOutsideClick
className="edit-spending-cap-modal"
@@ -154,6 +162,15 @@ export const EditSpendingCapModal = ({
style={{ width: '100%' }}
inputProps={{ 'data-testid': 'custom-spending-cap-input' }}
/>
+ {showDecimalError && (
+
+ {t('editSpendingCapError', [decimals])}
+
+ )}
From 420e4a668305860ee7a3e05853f64ebf546c71bf Mon Sep 17 00:00:00 2001
From: Charly Chevalier
Date: Wed, 9 Oct 2024 19:03:29 +0200
Subject: [PATCH 23/41] fix(multichain): fix getMultichainCurrentCurrency
selector (#27726)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
The `getMultichainCurrentCurrency` selector was buggy. It resulted in a
very weird interactions where the "current currency" was being selected
based on the currently selected account.
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27726?quickstart=1)
## **Related issues**
Fixes:
- https://github.com/MetaMask/accounts-planning/issues/612
## **Manual testing steps**
1. `yarn start:flask`
2. Settings > Experimental > "Enable Bitcoin support"
3. Create some Bitcoin accounts
4. Change your preferred currency on: Settings > General
5. Look at the account list:
- Bitcoin should always use USD or BTC unit
- Other EVM acounts should always use the preferred unit (fiat or
crypto)
## **Screenshots/Recordings**
### **Before**
https://github.com/user-attachments/assets/0ea7e341-8d04-43c6-aea6-8ff5f004c024
### **After**
https://github.com/user-attachments/assets/9e2feafd-97ed-4b51-b712-aad21f7d99b7
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
ui/selectors/multichain.ts | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/ui/selectors/multichain.ts b/ui/selectors/multichain.ts
index 2ef892db3353..1148e8d86468 100644
--- a/ui/selectors/multichain.ts
+++ b/ui/selectors/multichain.ts
@@ -244,10 +244,13 @@ export function getMultichainNativeCurrency(
: getMultichainProviderConfig(state, account).ticker;
}
-export function getMultichainCurrentCurrency(state: MultichainState) {
+export function getMultichainCurrentCurrency(
+ state: MultichainState,
+ account?: InternalAccount,
+) {
const currentCurrency = getCurrentCurrency(state);
- if (getMultichainIsEvm(state)) {
+ if (getMultichainIsEvm(state, account)) {
return currentCurrency;
}
@@ -256,7 +259,7 @@ export function getMultichainCurrentCurrency(state: MultichainState) {
// fallback to the current ticker symbol value
return currentCurrency && currentCurrency.toLowerCase() === 'usd'
? 'usd'
- : getMultichainProviderConfig(state).ticker;
+ : getMultichainProviderConfig(state, account).ticker;
}
export function getMultichainCurrencyImage(
From b9a24a7403a5988d0acc32e36ff53bf0195a42ce Mon Sep 17 00:00:00 2001
From: Jack Clancy
Date: Wed, 9 Oct 2024 18:30:25 +0100
Subject: [PATCH 24/41] =?UTF-8?q?fix:=20trying=20to=20access=20an=20undefi?=
=?UTF-8?q?ned=20object=20in=20swaps=20review=20quote=20compo=E2=80=A6=20(?=
=?UTF-8?q?#27708)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
Fixes the two errors with trade and decimals being undefined that have
been causing crashes starting around the 12.1/12.2 release. I was unable
to find the root cause of this issue. Variables in the redux store seem
to return as undefined, which leads me to think it might be some sort of
redux race condition. The lowest common denominator of this error seems
to be that `getUsedQuote` selector in the `ReviewQuote` component. I
have added an additional condition to the render guard in the parent
component `prepare-swaps-page` to prevent these errors
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27708?quickstart=1)
## **Related issues**
[MMS-1569](https://consensyssoftware.atlassian.net/jira/software/projects/MMS/boards/447/backlog?assignee=5ae37c7e42b8a62c4e15d92a&selectedIssue=MMS-1569)
## **Manual testing steps**
1. Open Swaps Page
2. Enter swap amount
3. Edit to token and amount rapidly multiple times
4. Page should not crash
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
[MMS-1569]:
https://consensyssoftware.atlassian.net/browse/MMS-1569?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
---
ui/pages/swaps/prepare-swap-page/prepare-swap-page.js | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/ui/pages/swaps/prepare-swap-page/prepare-swap-page.js b/ui/pages/swaps/prepare-swap-page/prepare-swap-page.js
index 7ea900c5eb59..72050df4aca9 100644
--- a/ui/pages/swaps/prepare-swap-page/prepare-swap-page.js
+++ b/ui/pages/swaps/prepare-swap-page/prepare-swap-page.js
@@ -52,6 +52,7 @@ import {
getTransactionSettingsOpened,
setTransactionSettingsOpened,
getLatestAddedTokenTo,
+ getUsedQuote,
} from '../../../ducks/swaps/swaps';
import {
getSwapsDefaultToken,
@@ -190,9 +191,10 @@ export default function PrepareSwapPage({
const rpcPrefs = useSelector(getRpcPrefsForCurrentProvider, shallowEqual);
const tokenList = useSelector(getTokenList, isEqual);
const quotes = useSelector(getQuotes, isEqual);
+ const usedQuote = useSelector(getUsedQuote, isEqual);
const latestAddedTokenTo = useSelector(getLatestAddedTokenTo, isEqual);
const numberOfQuotes = Object.keys(quotes).length;
- const areQuotesPresent = numberOfQuotes > 0;
+ const areQuotesPresent = numberOfQuotes > 0 && usedQuote;
const swapsErrorKey = useSelector(getSwapsErrorKey);
const aggregatorMetadata = useSelector(getAggregatorMetadata, shallowEqual);
const transactionSettingsOpened = useSelector(
From 50dceb55ee2e4c6421d7eaf0e4a28fbd7b232489 Mon Sep 17 00:00:00 2001
From: AugmentedMode <31675118+AugmentedMode@users.noreply.github.com>
Date: Wed, 9 Oct 2024 19:03:01 -0400
Subject: [PATCH 25/41] fix: remove old phishfort list from clients (#27743)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
This PR fixes an issue that prevented users from receiving the updated
hotlist from ETH Phishing Detect. While the client still fetched the
hotlist, the `PhishingDetector` was unable to update with the new URLs
included in the hotlist.
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27743?quickstart=1)
## **Related issues**
Fixes: https://github.com/MetaMask/metamask-extension/issues/27737
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---------
Co-authored-by: Mark Stacey
---
app/scripts/migrations/126.1.test.ts | 142 +++++++++++++++++++++++++++
app/scripts/migrations/126.1.ts | 54 ++++++++++
app/scripts/migrations/index.js | 1 +
3 files changed, 197 insertions(+)
create mode 100644 app/scripts/migrations/126.1.test.ts
create mode 100644 app/scripts/migrations/126.1.ts
diff --git a/app/scripts/migrations/126.1.test.ts b/app/scripts/migrations/126.1.test.ts
new file mode 100644
index 000000000000..0d21a675ebcc
--- /dev/null
+++ b/app/scripts/migrations/126.1.test.ts
@@ -0,0 +1,142 @@
+import { migrate, version } from './126.1';
+
+const oldVersion = 126.1;
+
+const mockPhishingListMetaMask = {
+ allowlist: [],
+ blocklist: ['malicious1.com'],
+ c2DomainBlocklist: ['malicious2.com'],
+ fuzzylist: [],
+ tolerance: 0,
+ version: 1,
+ lastUpdated: Date.now(),
+ name: 'MetaMask',
+};
+
+const mockPhishingListPhishfort = {
+ allowlist: [],
+ blocklist: ['phishfort1.com'],
+ c2DomainBlocklist: ['phishfort2.com'],
+ fuzzylist: [],
+ tolerance: 0,
+ version: 1,
+ lastUpdated: Date.now(),
+ name: 'Phishfort',
+};
+
+describe(`migration #${version}`, () => {
+ it('updates the version metadata', async () => {
+ const oldStorage = {
+ meta: { version: oldVersion },
+ data: {},
+ };
+
+ const newStorage = await migrate(oldStorage);
+
+ expect(newStorage.meta).toStrictEqual({ version });
+ });
+
+ it('keeps only the MetaMask phishing list in PhishingControllerState', async () => {
+ const oldState = {
+ PhishingController: {
+ phishingLists: [mockPhishingListMetaMask, mockPhishingListPhishfort],
+ whitelist: [],
+ hotlistLastFetched: 0,
+ stalelistLastFetched: 0,
+ c2DomainBlocklistLastFetched: 0,
+ },
+ };
+
+ const transformedState = await migrate({
+ meta: { version: oldVersion },
+ data: oldState,
+ });
+
+ const updatedPhishingController = transformedState.data
+ .PhishingController as Record;
+
+ expect(updatedPhishingController.phishingLists).toStrictEqual([
+ mockPhishingListMetaMask,
+ ]);
+ });
+
+ it('removes all phishing lists if MetaMask is not present', async () => {
+ const oldState = {
+ PhishingController: {
+ phishingLists: [mockPhishingListPhishfort],
+ whitelist: [],
+ hotlistLastFetched: 0,
+ stalelistLastFetched: 0,
+ c2DomainBlocklistLastFetched: 0,
+ },
+ };
+
+ const transformedState = await migrate({
+ meta: { version: oldVersion },
+ data: oldState,
+ });
+
+ const updatedPhishingController = transformedState.data
+ .PhishingController as Record;
+
+ expect(updatedPhishingController.phishingLists).toStrictEqual([]);
+ });
+
+ it('does nothing if PhishingControllerState is empty', async () => {
+ const oldState = {
+ PhishingController: {
+ phishingLists: [],
+ whitelist: [],
+ hotlistLastFetched: 0,
+ stalelistLastFetched: 0,
+ c2DomainBlocklistLastFetched: 0,
+ },
+ };
+
+ const transformedState = await migrate({
+ meta: { version: oldVersion },
+ data: oldState,
+ });
+
+ const updatedPhishingController = transformedState.data
+ .PhishingController as Record;
+
+ expect(updatedPhishingController.phishingLists).toStrictEqual([]);
+ });
+
+ it('does nothing if PhishingController is not in the state', async () => {
+ const oldState = {
+ NetworkController: {
+ providerConfig: {
+ chainId: '0x1',
+ },
+ },
+ };
+
+ const transformedState = await migrate({
+ meta: { version: oldVersion },
+ data: oldState,
+ });
+
+ expect(transformedState.data).toStrictEqual(oldState);
+ });
+
+ it('does nothing if phishingLists is not an array (null)', async () => {
+ const oldState: Record = {
+ PhishingController: {
+ phishingLists: null,
+ whitelist: [],
+ hotlistLastFetched: 0,
+ stalelistLastFetched: 0,
+ c2DomainBlocklistLastFetched: 0,
+ },
+ };
+
+ const transformedState = await migrate({
+ meta: { version: oldVersion },
+ data: oldState,
+ });
+
+ expect(transformedState.data).toStrictEqual(oldState);
+ });
+});
diff --git a/app/scripts/migrations/126.1.ts b/app/scripts/migrations/126.1.ts
new file mode 100644
index 000000000000..81e609e672f1
--- /dev/null
+++ b/app/scripts/migrations/126.1.ts
@@ -0,0 +1,54 @@
+import { hasProperty, isObject } from '@metamask/utils';
+import { cloneDeep } from 'lodash';
+
+type VersionedData = {
+ meta: { version: number };
+ data: Record;
+};
+
+export const version = 126.1;
+
+/**
+ * This migration removes `providerConfig` from the network controller state.
+ *
+ * @param originalVersionedData - Versioned MetaMask extension state, exactly what we persist to dist.
+ * @param originalVersionedData.meta - State metadata.
+ * @param originalVersionedData.meta.version - The current state version.
+ * @param originalVersionedData.data - The persisted MetaMask state, keyed by controller.
+ * @returns Updated versioned MetaMask extension state.
+ */
+export async function migrate(
+ originalVersionedData: VersionedData,
+): Promise {
+ const versionedData = cloneDeep(originalVersionedData);
+ versionedData.meta.version = version;
+ transformState(versionedData.data);
+ return versionedData;
+}
+
+function transformState(
+ state: Record,
+): Record {
+ if (
+ hasProperty(state, 'PhishingController') &&
+ isObject(state.PhishingController) &&
+ hasProperty(state.PhishingController, 'phishingLists')
+ ) {
+ const phishingController = state.PhishingController;
+
+ if (!Array.isArray(phishingController.phishingLists)) {
+ console.error(
+ `Migration ${version}: Invalid PhishingController.phishingLists state`,
+ );
+ return state;
+ }
+
+ phishingController.phishingLists = phishingController.phishingLists.filter(
+ (list) => list.name === 'MetaMask',
+ );
+
+ state.PhishingController = phishingController;
+ }
+
+ return state;
+}
diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js
index 93a862b5ee02..a72fd34c3c28 100644
--- a/app/scripts/migrations/index.js
+++ b/app/scripts/migrations/index.js
@@ -146,6 +146,7 @@ const migrations = [
require('./125'),
require('./125.1'),
require('./126'),
+ require('./126.1'),
require('./127'),
require('./128'),
require('./129'),
From 687cf3a2d23a6dba6fb672029095a537d7902582 Mon Sep 17 00:00:00 2001
From: Howard Braham
Date: Thu, 10 Oct 2024 00:39:15 -0700
Subject: [PATCH 26/41] ci: followup to CircleCI Sentry reporting (#27548)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
Implementing some suggestions from @matthewwalsh0 from #27412
~Also incorporates changes from @legobeat's #27268~
- Renamed `doNotForceSentryForThisTest` to `doNotForceForThisTest`
because the `Sentry` is now implied by the parent property
- Abstracted to `addFlagsFromPrBody()` and `addFlagsFromGitMessage()`
functions
- Only supports one flag right now (`tracesSampleRate`) but it's built
to be easily extendable for anything
- It's now an incredibly powerful general way to pass runtime flags into
the Extension in CircleCI, either through the PR body or through the Git
commit message
- In either the PR body or the Git commit message, add a line like
`flags = {"sentry": {"tracesSampleRate": x.xx}}`
If you do both, Git commit message takes precedence
- This changes the format from
`[flags.sentry.tracesSampleRate: x.xx]` to
`flags = {"sentry": {"tracesSampleRate": x.xx}}`
Note: This PR, as is, will hit the following error because it's trying
to actually parse the sample code above with `x.xx`. The good news is it
fails gracefully.
```
Error parsing flags from PR body, ignoring flags
SyntaxError: Unexpected token 'x', ..."pleRate": x.xx}}" is not valid JSON
```
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27548?quickstart=1)
## **Related issues**
Followup to: #27412
## **Manual testing steps**
## **Screenshots/Recordings**
### **Before**
### **After**
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
.circleci/scripts/git-diff-develop.ts | 19 +++--
app/scripts/lib/manifestFlags.ts | 2 +-
app/scripts/lib/setupSentry.js | 6 +-
test/e2e/set-manifest-flags.ts | 95 ++++++++++++++++++++-----
test/e2e/tests/metrics/errors.spec.js | 28 ++++----
test/e2e/tests/metrics/sessions.spec.ts | 4 +-
test/e2e/tests/metrics/traces.spec.ts | 8 +--
7 files changed, 117 insertions(+), 45 deletions(-)
diff --git a/.circleci/scripts/git-diff-develop.ts b/.circleci/scripts/git-diff-develop.ts
index 9f6c8f0ae4df..43435db17418 100644
--- a/.circleci/scripts/git-diff-develop.ts
+++ b/.circleci/scripts/git-diff-develop.ts
@@ -104,12 +104,18 @@ async function gitDiff(): Promise {
return diffResult;
}
+function writePrBodyToFile(prBody: string) {
+ const prBodyPath = path.resolve(CHANGED_FILES_DIR, 'pr-body.txt');
+ fs.writeFileSync(prBodyPath, prBody.trim());
+ console.log(`PR body saved to ${prBodyPath}`);
+}
+
/**
- * Stores the output of git diff to a file.
+ * Main run function, stores the output of git diff and the body of the matching PR to a file.
*
- * @returns Returns a promise that resolves when the git diff output is successfully stored.
+ * @returns Returns a promise that resolves when the git diff output and PR body is successfully stored.
*/
-async function storeGitDiffOutput() {
+async function storeGitDiffOutputAndPrBody() {
try {
// Create the directory
// This is done first because our CirleCI config requires that this directory is present,
@@ -132,6 +138,7 @@ async function storeGitDiffOutput() {
return;
} else if (baseRef !== MAIN_BRANCH) {
console.log(`This is for a PR targeting '${baseRef}', skipping git diff`);
+ writePrBodyToFile(prInfo.body);
return;
}
@@ -142,8 +149,10 @@ async function storeGitDiffOutput() {
// Store the output of git diff
const outputPath = path.resolve(CHANGED_FILES_DIR, 'changed-files.txt');
fs.writeFileSync(outputPath, diffOutput.trim());
-
console.log(`Git diff results saved to ${outputPath}`);
+
+ writePrBodyToFile(prInfo.body);
+
process.exit(0);
} catch (error: any) {
console.error('An error occurred:', error.message);
@@ -151,4 +160,4 @@ async function storeGitDiffOutput() {
}
}
-storeGitDiffOutput();
+storeGitDiffOutputAndPrBody();
diff --git a/app/scripts/lib/manifestFlags.ts b/app/scripts/lib/manifestFlags.ts
index a013373ac9f2..93925bf63a0c 100644
--- a/app/scripts/lib/manifestFlags.ts
+++ b/app/scripts/lib/manifestFlags.ts
@@ -11,7 +11,7 @@ export type ManifestFlags = {
};
sentry?: {
tracesSampleRate?: number;
- doNotForceSentryForThisTest?: boolean;
+ forceEnable?: boolean;
};
};
diff --git a/app/scripts/lib/setupSentry.js b/app/scripts/lib/setupSentry.js
index e6f4a0d4524e..d440578144cc 100644
--- a/app/scripts/lib/setupSentry.js
+++ b/app/scripts/lib/setupSentry.js
@@ -123,7 +123,7 @@ function getTracesSampleRate(sentryTarget) {
if (flags.circleci) {
// Report very frequently on develop branch, and never on other branches
- // (Unless you do a [flags.sentry.tracesSampleRate: x.xx] override)
+ // (Unless you use a `flags = {"sentry": {"tracesSampleRate": x.xx}}` override)
if (flags.circleci.branch === 'develop') {
return 0.03;
}
@@ -238,7 +238,7 @@ function getSentryEnvironment() {
function getSentryTarget() {
if (
- getManifestFlags().sentry?.doNotForceSentryForThisTest ||
+ !getManifestFlags().sentry?.forceEnable ||
(process.env.IN_TEST && !SENTRY_DSN_DEV)
) {
return SENTRY_DSN_FAKE;
@@ -272,7 +272,7 @@ async function getMetaMetricsEnabled() {
if (
METAMASK_BUILD_TYPE === 'mmi' ||
- (flags.circleci && !flags.sentry?.doNotForceSentryForThisTest)
+ (flags.circleci && flags.sentry.forceEnable)
) {
return true;
}
diff --git a/test/e2e/set-manifest-flags.ts b/test/e2e/set-manifest-flags.ts
index e8d02a12e2cd..290e8b863a9e 100644
--- a/test/e2e/set-manifest-flags.ts
+++ b/test/e2e/set-manifest-flags.ts
@@ -1,5 +1,6 @@
import { execSync } from 'child_process';
import fs from 'fs';
+import { merge } from 'lodash';
import { ManifestFlags } from '../../app/scripts/lib/manifestFlags';
export const folder = `dist/${process.env.SELENIUM_BROWSER}`;
@@ -8,23 +9,82 @@ function parseIntOrUndefined(value: string | undefined): number | undefined {
return value ? parseInt(value, 10) : undefined;
}
-// Grab the tracesSampleRate from the git message if it's set
-function getTracesSampleRateFromGitMessage(): number | undefined {
+/**
+ * Search a string for `flags = {...}` and return ManifestFlags if it exists
+ *
+ * @param str - The string to search
+ * @param errorType - The type of error to log if parsing fails
+ * @returns The ManifestFlags object if valid, otherwise undefined
+ */
+function regexSearchForFlags(
+ str: string,
+ errorType: string,
+): ManifestFlags | undefined {
+ // Search str for `flags = {...}`
+ const flagsMatch = str.match(/flags\s*=\s*(\{.*\})/u);
+
+ if (flagsMatch) {
+ try {
+ // Get 1st capturing group from regex
+ return JSON.parse(flagsMatch[1]);
+ } catch (error) {
+ console.error(
+ `Error parsing flags from ${errorType}, ignoring flags\n`,
+ error,
+ );
+ }
+ }
+
+ return undefined;
+}
+
+/**
+ * Add flags from the GitHub PR body if they are set
+ *
+ * To use this feature, add a line to your PR body like:
+ * `flags = {"sentry": {"tracesSampleRate": 0.1}}`
+ * (must be valid JSON)
+ *
+ * @param flags - The flags object to add to
+ */
+function addFlagsFromPrBody(flags: ManifestFlags) {
+ let body;
+
+ try {
+ body = fs.readFileSync('changed-files/pr-body.txt', 'utf8');
+ } catch (error) {
+ console.debug('No pr-body.txt, ignoring flags');
+ return;
+ }
+
+ const newFlags = regexSearchForFlags(body, 'PR body');
+
+ if (newFlags) {
+ // Use lodash merge to do a deep merge (spread operator is shallow)
+ merge(flags, newFlags);
+ }
+}
+
+/**
+ * Add flags from the Git message if they are set
+ *
+ * To use this feature, add a line to your commit message like:
+ * `flags = {"sentry": {"tracesSampleRate": 0.1}}`
+ * (must be valid JSON)
+ *
+ * @param flags - The flags object to add to
+ */
+function addFlagsFromGitMessage(flags: ManifestFlags) {
const gitMessage = execSync(
`git show --format='%B' --no-patch "HEAD"`,
).toString();
- // Search gitMessage for `[flags.sentry.tracesSampleRate: 0.000 to 1.000]`
- const tracesSampleRateMatch = gitMessage.match(
- /\[flags\.sentry\.tracesSampleRate: (0*(\.\d+)?|1(\.0*)?)\]/u,
- );
+ const newFlags = regexSearchForFlags(gitMessage, 'git message');
- if (tracesSampleRateMatch) {
- // Return 1st capturing group from regex
- return parseFloat(tracesSampleRateMatch[1]);
+ if (newFlags) {
+ // Use lodash merge to do a deep merge (spread operator is shallow)
+ merge(flags, newFlags);
}
-
- return undefined;
}
// Alter the manifest with CircleCI environment variables and custom flags
@@ -41,12 +101,15 @@ export function setManifestFlags(flags: ManifestFlags = {}) {
),
};
- const tracesSampleRate = getTracesSampleRateFromGitMessage();
+ addFlagsFromPrBody(flags);
+ addFlagsFromGitMessage(flags);
- // 0 is a valid value, so must explicitly check for undefined
- if (tracesSampleRate !== undefined) {
- // Add tracesSampleRate to flags.sentry (which may or may not already exist)
- flags.sentry = { ...flags.sentry, tracesSampleRate };
+ // Set `flags.sentry.forceEnable` to true by default
+ if (flags.sentry === undefined) {
+ flags.sentry = {};
+ }
+ if (flags.sentry.forceEnable === undefined) {
+ flags.sentry.forceEnable = true;
}
}
diff --git a/test/e2e/tests/metrics/errors.spec.js b/test/e2e/tests/metrics/errors.spec.js
index fdeb4437d428..dfe77f758fcb 100644
--- a/test/e2e/tests/metrics/errors.spec.js
+++ b/test/e2e/tests/metrics/errors.spec.js
@@ -247,7 +247,7 @@ describe('Sentry errors', function () {
title: this.test.fullTitle(),
testSpecificMock: mockSentryMigratorError,
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -278,7 +278,7 @@ describe('Sentry errors', function () {
title: this.test.fullTitle(),
testSpecificMock: mockSentryTestError,
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -319,7 +319,7 @@ describe('Sentry errors', function () {
title: this.test.fullTitle(),
testSpecificMock: mockSentryMigratorError,
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -365,7 +365,7 @@ describe('Sentry errors', function () {
title: this.test.fullTitle(),
testSpecificMock: mockSentryMigratorError,
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -426,7 +426,7 @@ describe('Sentry errors', function () {
title: this.test.fullTitle(),
testSpecificMock: mockSentryInvariantMigrationError,
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -475,7 +475,7 @@ describe('Sentry errors', function () {
testSpecificMock: mockSentryTestError,
ignoredConsoleErrors: ['TestError'],
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -521,7 +521,7 @@ describe('Sentry errors', function () {
testSpecificMock: mockSentryTestError,
ignoredConsoleErrors: ['TestError'],
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -585,7 +585,7 @@ describe('Sentry errors', function () {
title: this.test.fullTitle(),
testSpecificMock: mockSentryTestError,
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -621,7 +621,7 @@ describe('Sentry errors', function () {
testSpecificMock: mockSentryTestError,
ignoredConsoleErrors: ['TestError'],
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -656,7 +656,7 @@ describe('Sentry errors', function () {
title: this.test.fullTitle(),
testSpecificMock: mockSentryTestError,
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -702,7 +702,7 @@ describe('Sentry errors', function () {
title: this.test.fullTitle(),
testSpecificMock: mockSentryTestError,
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, ganacheServer, mockedEndpoint }) => {
@@ -766,7 +766,7 @@ describe('Sentry errors', function () {
testSpecificMock: mockSentryTestError,
ignoredConsoleErrors: ['TestError'],
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -810,7 +810,7 @@ describe('Sentry errors', function () {
testSpecificMock: mockSentryTestError,
ignoredConsoleErrors: ['TestError'],
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, ganacheServer, mockedEndpoint }) => {
@@ -898,7 +898,7 @@ describe('Sentry errors', function () {
ganacheOptions,
title: this.test.fullTitle(),
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver }) => {
diff --git a/test/e2e/tests/metrics/sessions.spec.ts b/test/e2e/tests/metrics/sessions.spec.ts
index f1bdee4538fb..7c79e5510116 100644
--- a/test/e2e/tests/metrics/sessions.spec.ts
+++ b/test/e2e/tests/metrics/sessions.spec.ts
@@ -38,7 +38,7 @@ describe('Sessions', function () {
title: this.test?.fullTitle(),
testSpecificMock: mockSentrySession,
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -60,7 +60,7 @@ describe('Sessions', function () {
title: this.test?.fullTitle(),
testSpecificMock: mockSentrySession,
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
diff --git a/test/e2e/tests/metrics/traces.spec.ts b/test/e2e/tests/metrics/traces.spec.ts
index 194f36ff73b0..9166281f90e5 100644
--- a/test/e2e/tests/metrics/traces.spec.ts
+++ b/test/e2e/tests/metrics/traces.spec.ts
@@ -51,7 +51,7 @@ describe('Traces', function () {
title: this.test?.fullTitle(),
testSpecificMock: mockSentryCustomTrace,
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -73,7 +73,7 @@ describe('Traces', function () {
title: this.test?.fullTitle(),
testSpecificMock: mockSentryCustomTrace,
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -95,7 +95,7 @@ describe('Traces', function () {
title: this.test?.fullTitle(),
testSpecificMock: mockSentryAutomatedTrace,
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
@@ -117,7 +117,7 @@ describe('Traces', function () {
title: this.test?.fullTitle(),
testSpecificMock: mockSentryAutomatedTrace,
manifestFlags: {
- sentry: { doNotForceSentryForThisTest: true },
+ sentry: { forceEnable: false },
},
},
async ({ driver, mockedEndpoint }) => {
From 97758a6a10edc7e2f19b16b6496818bf9d35cd68 Mon Sep 17 00:00:00 2001
From: sahar-fehri
Date: Thu, 10 Oct 2024 12:14:44 +0200
Subject: [PATCH 27/41] feat: upgrade assets-controllers to v38.2.0 (#27629)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
Upgrade assets-controllers to v38.2.0
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27629?quickstart=1)
## **Related issues**
Fixes:
## **Manual testing steps**
1. Go to this page...
2.
3.
## **Screenshots/Recordings**
### **Before**
### **After**
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---------
Co-authored-by: MetaMask Bot
---
...ts-controllers-npm-38.2.0-40af2afaa7.patch | 35 ++++++++
lavamoat/browserify/beta/policy.json | 12 +--
lavamoat/browserify/flask/policy.json | 12 +--
lavamoat/browserify/main/policy.json | 12 +--
lavamoat/browserify/mmi/policy.json | 12 +--
package.json | 2 +-
yarn.lock | 88 +++++++++++++------
7 files changed, 107 insertions(+), 66 deletions(-)
create mode 100644 .yarn/patches/@metamask-assets-controllers-npm-38.2.0-40af2afaa7.patch
diff --git a/.yarn/patches/@metamask-assets-controllers-npm-38.2.0-40af2afaa7.patch b/.yarn/patches/@metamask-assets-controllers-npm-38.2.0-40af2afaa7.patch
new file mode 100644
index 000000000000..7a5837cd4818
--- /dev/null
+++ b/.yarn/patches/@metamask-assets-controllers-npm-38.2.0-40af2afaa7.patch
@@ -0,0 +1,35 @@
+diff --git a/dist/assetsUtil.cjs b/dist/assetsUtil.cjs
+index e90a1b6767bc8ac54b7a4d580035cf5db6861dca..a5e0f03d2541b4e3540431ef2e6e4b60fb7ae9fe 100644
+--- a/dist/assetsUtil.cjs
++++ b/dist/assetsUtil.cjs
+@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+ };
+ Object.defineProperty(exports, "__esModule", { value: true });
++function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }
+ exports.fetchTokenContractExchangeRates = exports.reduceInBatchesSerially = exports.divideIntoBatches = exports.ethersBigNumberToBN = exports.addUrlProtocolPrefix = exports.getFormattedIpfsUrl = exports.getIpfsCIDv1AndPath = exports.removeIpfsProtocolPrefix = exports.isTokenListSupportedForNetwork = exports.isTokenDetectionSupportedForNetwork = exports.SupportedTokenDetectionNetworks = exports.formatIconUrlWithProxy = exports.formatAggregatorNames = exports.hasNewCollectionFields = exports.compareNftMetadata = exports.TOKEN_PRICES_BATCH_SIZE = void 0;
+ const controller_utils_1 = require("@metamask/controller-utils");
+ const utils_1 = require("@metamask/utils");
+@@ -221,7 +222,7 @@ async function getIpfsCIDv1AndPath(ipfsUrl) {
+ const index = url.indexOf('/');
+ const cid = index !== -1 ? url.substring(0, index) : url;
+ const path = index !== -1 ? url.substring(index) : undefined;
+- const { CID } = await import("multiformats");
++ const { CID } = _interopRequireWildcard(require("multiformats"));
+ // We want to ensure that the CID is v1 (https://docs.ipfs.io/concepts/content-addressing/#identifier-formats)
+ // because most cid v0s appear to be incompatible with IPFS subdomains
+ return {
+diff --git a/dist/token-prices-service/codefi-v2.mjs b/dist/token-prices-service/codefi-v2.mjs
+index e7eaad2cfa8b233c4fd42a51f745233a1cc5c387..b89849c0caf7e5db3b53cf03dd5746b6b1433543 100644
+--- a/dist/token-prices-service/codefi-v2.mjs
++++ b/dist/token-prices-service/codefi-v2.mjs
+@@ -12,8 +12,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
+ var _CodefiTokenPricesServiceV2_tokenPricePolicy;
+ import { handleFetch } from "@metamask/controller-utils";
+ import { hexToNumber } from "@metamask/utils";
+-import $cockatiel from "cockatiel";
+-const { circuitBreaker, ConsecutiveBreaker, ExponentialBackoff, handleAll, retry, wrap, CircuitState } = $cockatiel;
++import { circuitBreaker, ConsecutiveBreaker, ExponentialBackoff, handleAll, retry, wrap, CircuitState } from "cockatiel";
+ /**
+ * The list of currencies that can be supplied as the `vsCurrency` parameter to
+ * the `/spot-prices` endpoint, in lowercase form.
diff --git a/lavamoat/browserify/beta/policy.json b/lavamoat/browserify/beta/policy.json
index e98080fc4d5f..ec02c2756185 100644
--- a/lavamoat/browserify/beta/policy.json
+++ b/lavamoat/browserify/beta/policy.json
@@ -698,8 +698,8 @@
"@ethersproject/contracts": true,
"@ethersproject/providers": true,
"@metamask/abi-utils": true,
- "@metamask/assets-controllers>@metamask/base-controller": true,
"@metamask/assets-controllers>@metamask/polling-controller": true,
+ "@metamask/base-controller": true,
"@metamask/contract-metadata": true,
"@metamask/controller-utils": true,
"@metamask/eth-query": true,
@@ -715,14 +715,6 @@
"uuid": true
}
},
- "@metamask/assets-controllers>@metamask/base-controller": {
- "globals": {
- "setTimeout": true
- },
- "packages": {
- "immer": true
- }
- },
"@metamask/assets-controllers>@metamask/polling-controller": {
"globals": {
"clearTimeout": true,
@@ -730,7 +722,7 @@
"setTimeout": true
},
"packages": {
- "@metamask/assets-controllers>@metamask/base-controller": true,
+ "@metamask/base-controller": true,
"@metamask/snaps-utils>fast-json-stable-stringify": true,
"uuid": true
}
diff --git a/lavamoat/browserify/flask/policy.json b/lavamoat/browserify/flask/policy.json
index e98080fc4d5f..ec02c2756185 100644
--- a/lavamoat/browserify/flask/policy.json
+++ b/lavamoat/browserify/flask/policy.json
@@ -698,8 +698,8 @@
"@ethersproject/contracts": true,
"@ethersproject/providers": true,
"@metamask/abi-utils": true,
- "@metamask/assets-controllers>@metamask/base-controller": true,
"@metamask/assets-controllers>@metamask/polling-controller": true,
+ "@metamask/base-controller": true,
"@metamask/contract-metadata": true,
"@metamask/controller-utils": true,
"@metamask/eth-query": true,
@@ -715,14 +715,6 @@
"uuid": true
}
},
- "@metamask/assets-controllers>@metamask/base-controller": {
- "globals": {
- "setTimeout": true
- },
- "packages": {
- "immer": true
- }
- },
"@metamask/assets-controllers>@metamask/polling-controller": {
"globals": {
"clearTimeout": true,
@@ -730,7 +722,7 @@
"setTimeout": true
},
"packages": {
- "@metamask/assets-controllers>@metamask/base-controller": true,
+ "@metamask/base-controller": true,
"@metamask/snaps-utils>fast-json-stable-stringify": true,
"uuid": true
}
diff --git a/lavamoat/browserify/main/policy.json b/lavamoat/browserify/main/policy.json
index e98080fc4d5f..ec02c2756185 100644
--- a/lavamoat/browserify/main/policy.json
+++ b/lavamoat/browserify/main/policy.json
@@ -698,8 +698,8 @@
"@ethersproject/contracts": true,
"@ethersproject/providers": true,
"@metamask/abi-utils": true,
- "@metamask/assets-controllers>@metamask/base-controller": true,
"@metamask/assets-controllers>@metamask/polling-controller": true,
+ "@metamask/base-controller": true,
"@metamask/contract-metadata": true,
"@metamask/controller-utils": true,
"@metamask/eth-query": true,
@@ -715,14 +715,6 @@
"uuid": true
}
},
- "@metamask/assets-controllers>@metamask/base-controller": {
- "globals": {
- "setTimeout": true
- },
- "packages": {
- "immer": true
- }
- },
"@metamask/assets-controllers>@metamask/polling-controller": {
"globals": {
"clearTimeout": true,
@@ -730,7 +722,7 @@
"setTimeout": true
},
"packages": {
- "@metamask/assets-controllers>@metamask/base-controller": true,
+ "@metamask/base-controller": true,
"@metamask/snaps-utils>fast-json-stable-stringify": true,
"uuid": true
}
diff --git a/lavamoat/browserify/mmi/policy.json b/lavamoat/browserify/mmi/policy.json
index 43297351bf21..7eaa06a954b0 100644
--- a/lavamoat/browserify/mmi/policy.json
+++ b/lavamoat/browserify/mmi/policy.json
@@ -790,8 +790,8 @@
"@ethersproject/contracts": true,
"@ethersproject/providers": true,
"@metamask/abi-utils": true,
- "@metamask/assets-controllers>@metamask/base-controller": true,
"@metamask/assets-controllers>@metamask/polling-controller": true,
+ "@metamask/base-controller": true,
"@metamask/contract-metadata": true,
"@metamask/controller-utils": true,
"@metamask/eth-query": true,
@@ -807,14 +807,6 @@
"uuid": true
}
},
- "@metamask/assets-controllers>@metamask/base-controller": {
- "globals": {
- "setTimeout": true
- },
- "packages": {
- "immer": true
- }
- },
"@metamask/assets-controllers>@metamask/polling-controller": {
"globals": {
"clearTimeout": true,
@@ -822,7 +814,7 @@
"setTimeout": true
},
"packages": {
- "@metamask/assets-controllers>@metamask/base-controller": true,
+ "@metamask/base-controller": true,
"@metamask/snaps-utils>fast-json-stable-stringify": true,
"uuid": true
}
diff --git a/package.json b/package.json
index 4d88e907dd2a..416b3e1b0420 100644
--- a/package.json
+++ b/package.json
@@ -302,7 +302,7 @@
"@metamask/address-book-controller": "^6.0.0",
"@metamask/announcement-controller": "^7.0.0",
"@metamask/approval-controller": "^7.0.0",
- "@metamask/assets-controllers": "^37.0.0",
+ "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A38.2.0#~/.yarn/patches/@metamask-assets-controllers-npm-38.2.0-40af2afaa7.patch",
"@metamask/base-controller": "^7.0.0",
"@metamask/bitcoin-wallet-snap": "^0.6.1",
"@metamask/browser-passworder": "^4.3.0",
diff --git a/yarn.lock b/yarn.lock
index e8cade3e2727..1e00e14c6cf8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4861,9 +4861,9 @@ __metadata:
languageName: node
linkType: hard
-"@metamask/assets-controllers@npm:^37.0.0":
- version: 37.0.0
- resolution: "@metamask/assets-controllers@npm:37.0.0"
+"@metamask/assets-controllers@npm:38.2.0":
+ version: 38.2.0
+ resolution: "@metamask/assets-controllers@npm:38.2.0"
dependencies:
"@ethereumjs/util": "npm:^8.1.0"
"@ethersproject/address": "npm:^5.7.0"
@@ -4871,12 +4871,12 @@ __metadata:
"@ethersproject/contracts": "npm:^5.7.0"
"@ethersproject/providers": "npm:^5.7.0"
"@metamask/abi-utils": "npm:^2.0.3"
- "@metamask/base-controller": "npm:^6.0.2"
+ "@metamask/base-controller": "npm:^7.0.1"
"@metamask/contract-metadata": "npm:^2.4.0"
- "@metamask/controller-utils": "npm:^11.0.2"
+ "@metamask/controller-utils": "npm:^11.3.0"
"@metamask/eth-query": "npm:^4.0.0"
"@metamask/metamask-eth-abis": "npm:^3.1.1"
- "@metamask/polling-controller": "npm:^9.0.1"
+ "@metamask/polling-controller": "npm:^10.0.1"
"@metamask/rpc-errors": "npm:^6.3.1"
"@metamask/utils": "npm:^9.1.0"
"@types/bn.js": "npm:^5.1.5"
@@ -4893,9 +4893,47 @@ __metadata:
"@metamask/accounts-controller": ^18.0.0
"@metamask/approval-controller": ^7.0.0
"@metamask/keyring-controller": ^17.0.0
- "@metamask/network-controller": ^20.0.0
+ "@metamask/network-controller": ^21.0.0
"@metamask/preferences-controller": ^13.0.0
- checksum: 10/89798930cb80a134263ce82db736feebd064fe6c999ddcf41ca86fad81cfadbb9e37d1919a6384aaf6d3aa0cb520684e7b8228da3b9bc1e70e7aea174a69c4ac
+ checksum: 10/96ae724a002289e4df97bab568e0bba4d28ef18320298b12d828fc3b58c58ebc54b9f9d659c5e6402aad82088b699e52469d897dd4356e827e35b8f8cebb4483
+ languageName: node
+ linkType: hard
+
+"@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A38.2.0#~/.yarn/patches/@metamask-assets-controllers-npm-38.2.0-40af2afaa7.patch":
+ version: 38.2.0
+ resolution: "@metamask/assets-controllers@patch:@metamask/assets-controllers@npm%3A38.2.0#~/.yarn/patches/@metamask-assets-controllers-npm-38.2.0-40af2afaa7.patch::version=38.2.0&hash=e14ff8"
+ dependencies:
+ "@ethereumjs/util": "npm:^8.1.0"
+ "@ethersproject/address": "npm:^5.7.0"
+ "@ethersproject/bignumber": "npm:^5.7.0"
+ "@ethersproject/contracts": "npm:^5.7.0"
+ "@ethersproject/providers": "npm:^5.7.0"
+ "@metamask/abi-utils": "npm:^2.0.3"
+ "@metamask/base-controller": "npm:^7.0.1"
+ "@metamask/contract-metadata": "npm:^2.4.0"
+ "@metamask/controller-utils": "npm:^11.3.0"
+ "@metamask/eth-query": "npm:^4.0.0"
+ "@metamask/metamask-eth-abis": "npm:^3.1.1"
+ "@metamask/polling-controller": "npm:^10.0.1"
+ "@metamask/rpc-errors": "npm:^6.3.1"
+ "@metamask/utils": "npm:^9.1.0"
+ "@types/bn.js": "npm:^5.1.5"
+ "@types/uuid": "npm:^8.3.0"
+ async-mutex: "npm:^0.5.0"
+ bn.js: "npm:^5.2.1"
+ cockatiel: "npm:^3.1.2"
+ immer: "npm:^9.0.6"
+ lodash: "npm:^4.17.21"
+ multiformats: "npm:^13.1.0"
+ single-call-balance-checker-abi: "npm:^1.0.0"
+ uuid: "npm:^8.3.2"
+ peerDependencies:
+ "@metamask/accounts-controller": ^18.0.0
+ "@metamask/approval-controller": ^7.0.0
+ "@metamask/keyring-controller": ^17.0.0
+ "@metamask/network-controller": ^21.0.0
+ "@metamask/preferences-controller": ^13.0.0
+ checksum: 10/0ba3673bf9c87988d6c569a14512b8c9bb97db3516debfedf24cbcf38110e99afec8d9fc50cb0b627bfbc1d1a62069298e4e27278587197f67812cb38ee2c778
languageName: node
linkType: hard
@@ -5958,6 +5996,22 @@ __metadata:
languageName: node
linkType: hard
+"@metamask/polling-controller@npm:^10.0.1":
+ version: 10.0.1
+ resolution: "@metamask/polling-controller@npm:10.0.1"
+ dependencies:
+ "@metamask/base-controller": "npm:^7.0.1"
+ "@metamask/controller-utils": "npm:^11.3.0"
+ "@metamask/utils": "npm:^9.1.0"
+ "@types/uuid": "npm:^8.3.0"
+ fast-json-stable-stringify: "npm:^2.1.0"
+ uuid: "npm:^8.3.2"
+ peerDependencies:
+ "@metamask/network-controller": ^21.0.0
+ checksum: 10/25c11e65eeccb08a2b4b7dec21ccabb4b797907edb03a1534ebacb87d0754a3ade52aad061aad8b3ac23bfc39917c0d61b9734e32bc748c210b2997410ae45a9
+ languageName: node
+ linkType: hard
+
"@metamask/polling-controller@npm:^8.0.0":
version: 8.0.0
resolution: "@metamask/polling-controller@npm:8.0.0"
@@ -5975,22 +6029,6 @@ __metadata:
languageName: node
linkType: hard
-"@metamask/polling-controller@npm:^9.0.1":
- version: 9.0.1
- resolution: "@metamask/polling-controller@npm:9.0.1"
- dependencies:
- "@metamask/base-controller": "npm:^6.0.2"
- "@metamask/controller-utils": "npm:^11.0.2"
- "@metamask/utils": "npm:^9.1.0"
- "@types/uuid": "npm:^8.3.0"
- fast-json-stable-stringify: "npm:^2.1.0"
- uuid: "npm:^8.3.2"
- peerDependencies:
- "@metamask/network-controller": ^20.0.0
- checksum: 10/e9e8c51013290a2e4b2817ba1e0915783474f6a55fe614e20acf92bf707e300bec1fa612c8019ae9afe9635d018fb5d5b106c8027446ba12767220db91cf1ee5
- languageName: node
- linkType: hard
-
"@metamask/post-message-stream@npm:^8.0.0, @metamask/post-message-stream@npm:^8.1.1":
version: 8.1.1
resolution: "@metamask/post-message-stream@npm:8.1.1"
@@ -26059,7 +26097,7 @@ __metadata:
"@metamask/announcement-controller": "npm:^7.0.0"
"@metamask/api-specs": "npm:^0.9.3"
"@metamask/approval-controller": "npm:^7.0.0"
- "@metamask/assets-controllers": "npm:^37.0.0"
+ "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A38.2.0#~/.yarn/patches/@metamask-assets-controllers-npm-38.2.0-40af2afaa7.patch"
"@metamask/auto-changelog": "npm:^2.1.0"
"@metamask/base-controller": "npm:^7.0.0"
"@metamask/bitcoin-wallet-snap": "npm:^0.6.1"
From 11b9bd4caa84c795ec940d0984741b5ec18757d1 Mon Sep 17 00:00:00 2001
From: Nidhi Kumari
Date: Thu, 10 Oct 2024 12:09:30 +0100
Subject: [PATCH 28/41] feat: Release Chain Permissions (#27561)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This PR is to remove feature flags and add e2e for Chain Permissions
## **Related issues**
Fixes:
[https://github.com/MetaMask/MetaMask-planning/issues/2713](https://github.com/MetaMask/MetaMask-planning/issues/2713)
## **Manual testing steps**
1. Run yarn start
2. Everything should work
## **Screenshots/Recordings**
### **Before**
### **After**
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---------
Co-authored-by: Jiexi Luan
Co-authored-by: Alex
Co-authored-by: David Walsh
Co-authored-by: seaona <54408225+seaona@users.noreply.github.com>
---
app/_locales/de/messages.json | 15 --
app/_locales/el/messages.json | 15 --
app/_locales/en/messages.json | 15 --
app/_locales/es/messages.json | 15 --
app/_locales/fr/messages.json | 15 --
app/_locales/hi/messages.json | 15 --
app/_locales/id/messages.json | 15 --
app/_locales/ja/messages.json | 15 --
app/_locales/ko/messages.json | 15 --
app/_locales/pt/messages.json | 15 --
app/_locales/ru/messages.json | 15 --
app/_locales/tl/messages.json | 15 --
app/_locales/tr/messages.json | 15 --
app/_locales/vi/messages.json | 15 --
app/_locales/zh_CN/messages.json | 15 --
.../handlers/add-ethereum-chain.js | 37 +--
.../handlers/add-ethereum-chain.test.js | 37 +--
.../handlers/ethereum-chain-utils.js | 41 ++-
.../handlers/switch-ethereum-chain.js | 35 +--
.../handlers/switch-ethereum-chain.test.js | 20 --
app/scripts/metamask-controller.js | 16 +-
test/e2e/accounts/common.ts | 15 +-
.../api-specs/ConfirmationRejectionRule.ts | 35 ++-
test/e2e/helpers.js | 13 +-
test/e2e/json-rpc/switchEthereumChain.spec.js | 145 ++++++++---
.../wallet_requestPermissions.spec.js | 7 +-
.../e2e/snaps/test-snap-txinsights-v2.spec.js | 31 +--
test/e2e/snaps/test-snap-txinsights.spec.js | 30 +--
.../connections/connect-with-metamask.spec.js | 79 ++++++
.../connections/edit-account-flow.spec.js | 101 ++++++++
.../connections/edit-networks-flow.spec.js | 85 +++++++
.../review-permissions-page.spec.js | 145 +++++++++++
.../review-switch-permission-page.spec.js | 154 ++++++++++++
.../dapp-interactions.spec.js | 3 +-
.../dapp-interactions/permissions.spec.js | 6 +-
test/e2e/tests/metrics/dapp-viewed.spec.js | 87 +------
.../tests/multichain/connection-page.spec.js | 219 ----------------
.../tests/network/add-custom-network.spec.js | 7 -
.../tests/network/chain-interactions.spec.js | 49 ----
.../tests/network/deprecated-networks.spec.js | 21 --
.../network/switch-custom-network.spec.js | 55 +---
.../batch-txs-per-dapp-diff-network.spec.js | 61 ++---
.../batch-txs-per-dapp-extra-tx.spec.js | 144 +++++------
.../batch-txs-per-dapp-same-network.spec.js | 62 +++--
.../request-queuing/chainid-check.spec.js | 48 ++--
.../dapp1-send-dapp2-signTypedData.spec.js | 60 ++---
.../dapp1-subscribe-network-switch.spec.js | 12 +-
...-switch-dapp2-eth-request-accounts.spec.js | 9 +-
.../dapp1-switch-dapp2-send.spec.js | 50 +---
...multi-dapp-sendTx-revokePermission.spec.js | 65 +++--
.../multiple-networks-dapps-txs.spec.js | 56 ++---
.../switchChain-sendTx.spec.js | 44 ++--
.../switchChain-watchAsset.spec.js | 36 ++-
test/e2e/tests/request-queuing/ui.spec.js | 104 ++++----
.../watchAsset-switchChain-watchAsset.spec.js | 2 -
.../permission-cell/permission-cell-status.js | 2 +-
...ission-page-container-content.component.js | 32 +--
.../permissions-connect-permission-list.js | 7 +-
.../app-header-unlocked-content.tsx | 11 +-
.../disconnect-all-modal.tsx | 13 +-
.../network-list-menu/network-list-menu.tsx | 5 +-
.../permissions-page.test.js.snap | 105 ++------
.../permissions-page/connection-list-item.js | 71 ++----
.../connection-list-item.test.js | 36 +--
.../permissions-page/permissions-page.js | 12 +-
.../review-permissions-page.tsx | 1 +
.../permissions-connect.test.tsx.snap | 236 ------------------
.../permissions-connect.component.js | 25 +-
.../permissions-connect.test.tsx | 180 -------------
ui/pages/routes/routes.component.js | 2 +-
70 files changed, 1200 insertions(+), 1989 deletions(-)
create mode 100644 test/e2e/tests/connections/connect-with-metamask.spec.js
create mode 100644 test/e2e/tests/connections/edit-account-flow.spec.js
create mode 100644 test/e2e/tests/connections/edit-networks-flow.spec.js
create mode 100644 test/e2e/tests/connections/review-permissions-page.spec.js
create mode 100644 test/e2e/tests/connections/review-switch-permission-page.spec.js
delete mode 100644 test/e2e/tests/multichain/connection-page.spec.js
delete mode 100644 ui/pages/permissions-connect/__snapshots__/permissions-connect.test.tsx.snap
delete mode 100644 ui/pages/permissions-connect/permissions-connect.test.tsx
diff --git a/app/_locales/de/messages.json b/app/_locales/de/messages.json
index bda0d4d894e7..8c91aec52887 100644
--- a/app/_locales/de/messages.json
+++ b/app/_locales/de/messages.json
@@ -1088,9 +1088,6 @@
"connectedSnapAndNoAccountDescription": {
"message": "MetaMask ist mit dieser Seite verbunden, aber es sind noch keine Konten verbunden"
},
- "connectedWith": {
- "message": "Verbunden mit"
- },
"connecting": {
"message": "Verbinden"
},
@@ -1507,14 +1504,6 @@
"disconnectAllSnapsText": {
"message": "Snaps"
},
- "disconnectAllText": {
- "message": "Wenn Sie die Verbindung zwischen $1 und $2 unterbrechen, müssen Sie die Verbindung wiederherstellen, um sie erneut zu verwenden.",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "Alle $1 trennen",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectPrompt": {
"message": "$1 trennen"
},
@@ -2835,10 +2824,6 @@
"message": "$1 bittet um Ihre Zustimmung zu:",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "Möchten Sie, dass diese Website Folgendes tut?",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "Das native Token dieses Netzwerks ist $1. Dieses Token wird für die Gas-Gebühr verwendet. ",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/_locales/el/messages.json b/app/_locales/el/messages.json
index 6010f1939602..4f29362124bd 100644
--- a/app/_locales/el/messages.json
+++ b/app/_locales/el/messages.json
@@ -1088,9 +1088,6 @@
"connectedSnapAndNoAccountDescription": {
"message": "Το MetaMask είναι συνδεδεμένο σε αυτόν τον ιστότοπο, αλλά δεν έχουν συνδεθεί ακόμα λογαριασμοί"
},
- "connectedWith": {
- "message": "Συνδέεται με"
- },
"connecting": {
"message": "Σύνδεση"
},
@@ -1507,14 +1504,6 @@
"disconnectAllSnapsText": {
"message": "Snaps"
},
- "disconnectAllText": {
- "message": "Αν αποσυνδέσετε τo $1 από τo $2, θα πρέπει να επανασυνδεθείτε για να τα χρησιμοποιήσετε ξανά.",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "Αποσύνδεση όλων των $1",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectPrompt": {
"message": "Αποσύνδεση $1"
},
@@ -2835,10 +2824,6 @@
"message": "Το $1 ζητάει την έγκρισή σας για:",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "Θέλετε αυτός ο ιστότοπος να κάνει τα εξής;",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "Το αρχικό token σε αυτό το δίκτυο είναι το $1. Είναι το token που χρησιμοποιείται για τα τέλη συναλλαγών.",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index b7345f8d4f6c..ecaedb3201d0 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -1180,9 +1180,6 @@
"connectedSnaps": {
"message": "Connected Snaps"
},
- "connectedWith": {
- "message": "Connected with"
- },
"connectedWithAccount": {
"message": "$1 accounts connected",
"description": "$1 represents account length"
@@ -1647,14 +1644,6 @@
"disconnectAllSnapsText": {
"message": "Snaps"
},
- "disconnectAllText": {
- "message": "If you disconnect your $1 from $2, you'll need to reconnect to use them again.",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "Disconnect all $1",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectMessage": {
"message": "This will disconnect you from $1",
"description": "$1 is the name of the dapp"
@@ -3053,10 +3042,6 @@
"message": "$1 is asking for your approval to:",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "Do you want this site to do the following?",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "The native token on this network is $1. It is the token used for gas fees. ",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/_locales/es/messages.json b/app/_locales/es/messages.json
index 772471fdfd65..49c523b184f6 100644
--- a/app/_locales/es/messages.json
+++ b/app/_locales/es/messages.json
@@ -1085,9 +1085,6 @@
"connectedSnapAndNoAccountDescription": {
"message": "MetaMask está conectado a este sitio, pero aún no hay cuentas conectadas"
},
- "connectedWith": {
- "message": "Conectado con"
- },
"connecting": {
"message": "Conectando"
},
@@ -1504,14 +1501,6 @@
"disconnectAllSnapsText": {
"message": "Snaps"
},
- "disconnectAllText": {
- "message": "Si desconecta su $1 de su $2, tendrá que volver a conectarlos para usarlos nuevamente.",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "Desconectar todos/as $1",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectPrompt": {
"message": "Desconectar $1"
},
@@ -2832,10 +2821,6 @@
"message": "$1 solicita su aprobación para:",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "¿Desea que este sitio haga lo siguiente?",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "El token nativo en esta red es de $1. Es el token utilizado para las tarifas de gas. ",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/_locales/fr/messages.json b/app/_locales/fr/messages.json
index 4a537a554315..0c5015f67665 100644
--- a/app/_locales/fr/messages.json
+++ b/app/_locales/fr/messages.json
@@ -1088,9 +1088,6 @@
"connectedSnapAndNoAccountDescription": {
"message": "MetaMask est connecté à ce site, mais aucun compte n’est encore connecté"
},
- "connectedWith": {
- "message": "Connecté avec"
- },
"connecting": {
"message": "Connexion…"
},
@@ -1507,14 +1504,6 @@
"disconnectAllSnapsText": {
"message": "Snaps"
},
- "disconnectAllText": {
- "message": "Si vous déconnectez vos $1 de $2, vous devrez vous reconnecter pour les utiliser à nouveau.",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "Déconnecter tous les $1",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectPrompt": {
"message": "Déconnecter $1"
},
@@ -2835,10 +2824,6 @@
"message": "$1 vous demande votre approbation pour :",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "Voulez-vous que ce site fasse ce qui suit ?",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "Le jeton natif de ce réseau est $1. C’est le jeton utilisé pour les frais de gaz. ",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/_locales/hi/messages.json b/app/_locales/hi/messages.json
index 7fb1a04cb137..274aae47e2e3 100644
--- a/app/_locales/hi/messages.json
+++ b/app/_locales/hi/messages.json
@@ -1088,9 +1088,6 @@
"connectedSnapAndNoAccountDescription": {
"message": "MetaMask इस साइट से कनेक्टेड है, लेकिन अभी तक कोई अकाउंट कनेक्ट नहीं किया गया है"
},
- "connectedWith": {
- "message": "से कनेक्ट किया गया"
- },
"connecting": {
"message": "कनेक्ट किया जा रहा है"
},
@@ -1507,14 +1504,6 @@
"disconnectAllSnapsText": {
"message": "Snaps"
},
- "disconnectAllText": {
- "message": "अगर आप अपने $1 को $2 से डिस्कनेक्ट करते हैं, तो आपको उन्हें दोबारा इस्तेमाल करने के लिए रिकनेक्ट करना होगा।",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "सभी $1 को डिस्कनेक्ट करें",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectPrompt": {
"message": "$1 डिस्कनेक्ट करें"
},
@@ -2835,10 +2824,6 @@
"message": "$1 निम्नलिखित के लिए आपका एप्रूवल मांग रहा है:",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "क्या आप चाहते हैं कि यह साइट निम्नलिखित कार्य करे?",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "इस नेटवर्क पर ओरिजिनल टोकन $1 है। यह गैस फ़ीस के लिए इस्तेमाल किया जाने वाला टोकन है।",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/_locales/id/messages.json b/app/_locales/id/messages.json
index be3ef95ad448..5f36af7a382d 100644
--- a/app/_locales/id/messages.json
+++ b/app/_locales/id/messages.json
@@ -1088,9 +1088,6 @@
"connectedSnapAndNoAccountDescription": {
"message": "MetaMask terhubung ke situs ini, tetapi belum ada akun yang terhubung"
},
- "connectedWith": {
- "message": "Terhubung dengan"
- },
"connecting": {
"message": "Menghubungkan"
},
@@ -1507,14 +1504,6 @@
"disconnectAllSnapsText": {
"message": "Snap"
},
- "disconnectAllText": {
- "message": "Jika Anda memutus koneksi $1 dari $2, Anda harus menghubungkannya kembali agar dapat menggunakannya lagi.",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "Putuskan semua koneksi $1",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectPrompt": {
"message": "Putuskan koneksi $1"
},
@@ -2835,10 +2824,6 @@
"message": "$1 meminta persetujuan Anda untuk:",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "Ingin situs ini melakukan hal berikut?",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "Token asli di jaringan ini adalah $1. Ini merupakan token yang digunakan untuk biaya gas. ",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/_locales/ja/messages.json b/app/_locales/ja/messages.json
index 1ffbc9f1e4eb..c8adf1ff5af9 100644
--- a/app/_locales/ja/messages.json
+++ b/app/_locales/ja/messages.json
@@ -1088,9 +1088,6 @@
"connectedSnapAndNoAccountDescription": {
"message": "MetaMaskはこのサイトに接続されていますが、まだアカウントは接続されていません"
},
- "connectedWith": {
- "message": "接続先"
- },
"connecting": {
"message": "接続中..."
},
@@ -1507,14 +1504,6 @@
"disconnectAllSnapsText": {
"message": "Snap"
},
- "disconnectAllText": {
- "message": "$1と$2の接続を解除した場合、再び使用するには再度接続する必要があります。",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "すべての$1の接続を解除",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectPrompt": {
"message": "$1を接続解除"
},
@@ -2835,10 +2824,6 @@
"message": "$1が次の承認を求めています:",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "このサイトに次のことを希望しますか?",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "このネットワークのネイティブトークンは$1です。ガス代にもこのトークンが使用されます。",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/_locales/ko/messages.json b/app/_locales/ko/messages.json
index a1c79024f651..5868672bce32 100644
--- a/app/_locales/ko/messages.json
+++ b/app/_locales/ko/messages.json
@@ -1088,9 +1088,6 @@
"connectedSnapAndNoAccountDescription": {
"message": "MetaMask는 이 사이트와 연결되어 있지만, 아직 연결된 계정이 없습니다"
},
- "connectedWith": {
- "message": "연결 대상:"
- },
"connecting": {
"message": "연결 중"
},
@@ -1507,14 +1504,6 @@
"disconnectAllSnapsText": {
"message": "Snap"
},
- "disconnectAllText": {
- "message": "$2에서 $1의 연결을 끊은 경우, 다시 사용하려면 다시 연결해야 합니다.",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "모든 $1 연결 해제",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectPrompt": {
"message": "$1 연결 해제"
},
@@ -2835,10 +2824,6 @@
"message": "$1에서 다음 승인을 요청합니다:",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "이 사이트가 다음을 수행하기 원하십니까?",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "이 네트워크의 네이티브 토큰은 $1입니다. 이는 가스비 지불에 사용하는 토큰입니다. ",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/_locales/pt/messages.json b/app/_locales/pt/messages.json
index 52eb392f9d94..298f4b8b8d70 100644
--- a/app/_locales/pt/messages.json
+++ b/app/_locales/pt/messages.json
@@ -1088,9 +1088,6 @@
"connectedSnapAndNoAccountDescription": {
"message": "A MetaMask está conectada a este site, mas nenhuma conta está conectada ainda"
},
- "connectedWith": {
- "message": "Conectado com"
- },
"connecting": {
"message": "Conectando"
},
@@ -1507,14 +1504,6 @@
"disconnectAllSnapsText": {
"message": "Snaps"
},
- "disconnectAllText": {
- "message": "Se desconectar $1 de $2, você precisará reconectar para usar novamente.",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "Desconectar $1",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectPrompt": {
"message": "Desconectar $1"
},
@@ -2835,10 +2824,6 @@
"message": "$1 solicita sua aprovação para:",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "Deseja que este site faça o seguinte?",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "O token nativo dessa rede é $1. Esse é o token usado para taxas de gás.",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/_locales/ru/messages.json b/app/_locales/ru/messages.json
index 9f4f15461bab..999f237f73ea 100644
--- a/app/_locales/ru/messages.json
+++ b/app/_locales/ru/messages.json
@@ -1088,9 +1088,6 @@
"connectedSnapAndNoAccountDescription": {
"message": "MetaMask подключен к этому сайту, но счета пока не подключены"
},
- "connectedWith": {
- "message": "Подключен(-а) к"
- },
"connecting": {
"message": "Подключение..."
},
@@ -1507,14 +1504,6 @@
"disconnectAllSnapsText": {
"message": "Snaps"
},
- "disconnectAllText": {
- "message": "Если вы отключите свои $1 от $2, вам придется повторно подключиться, чтобы использовать их снова.",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "Отключить все $1",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectPrompt": {
"message": "Отключить $1"
},
@@ -2835,10 +2824,6 @@
"message": "$1 запрашивает ваше одобрение на:",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "Вы хотите, чтобы этот сайт делал следующее?",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "Нативный токен этой сети — $1. Этот токен используется для внесения платы за газ. ",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/_locales/tl/messages.json b/app/_locales/tl/messages.json
index c2ffc42763d0..df021e9dfdad 100644
--- a/app/_locales/tl/messages.json
+++ b/app/_locales/tl/messages.json
@@ -1088,9 +1088,6 @@
"connectedSnapAndNoAccountDescription": {
"message": "Konektado ang MetaMask sa site na ito, ngunit wala pang mga account ang konektado"
},
- "connectedWith": {
- "message": "Nakakonekta sa"
- },
"connecting": {
"message": "Kumokonekta"
},
@@ -1507,14 +1504,6 @@
"disconnectAllSnapsText": {
"message": "Mga Snap"
},
- "disconnectAllText": {
- "message": "Kapag idiniskonekta mo ang iyong $1 mula sa $2, kailangan mong muling ikonekta para gamitin muli.",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "Idiskonekta ang lahat ng $1",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectPrompt": {
"message": "Idiskonekta $1"
},
@@ -2835,10 +2824,6 @@
"message": "Ang $1 ay humihiling ng iyong pag-apruba para:",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "Gusto mo bang gawin ng site na ito ang mga sumusunod?",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "Ang native token sa network na ito ay $1. Ito ang token na ginagamit para sa mga gas fee. ",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/_locales/tr/messages.json b/app/_locales/tr/messages.json
index 676896deaaae..ce36a61ca716 100644
--- a/app/_locales/tr/messages.json
+++ b/app/_locales/tr/messages.json
@@ -1088,9 +1088,6 @@
"connectedSnapAndNoAccountDescription": {
"message": "MetaMask bu siteye bağlı ancak henüz bağlı hesap yok"
},
- "connectedWith": {
- "message": "Şununla bağlanıldı:"
- },
"connecting": {
"message": "Bağlanıyor"
},
@@ -1507,14 +1504,6 @@
"disconnectAllSnapsText": {
"message": "Snap'ler"
},
- "disconnectAllText": {
- "message": "$1 ile $2 bağlantısını keserseniz onları tekrar kullanmak için tekrar bağlamanız gerekir.",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "Tüm $1 bağlantısını kes",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectPrompt": {
"message": "$1 bağlantısını kes"
},
@@ -2835,10 +2824,6 @@
"message": "$1 sizden şunun için onay istiyor:",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "Bu sitenin aşağıdakileri yapmasına izin vermek istiyor musunuz?",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "Bu ağdaki yerli token $1. Bu, gaz ücretleri için kullanılan tokendir. ",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/_locales/vi/messages.json b/app/_locales/vi/messages.json
index 442478665c00..5766a1789d24 100644
--- a/app/_locales/vi/messages.json
+++ b/app/_locales/vi/messages.json
@@ -1088,9 +1088,6 @@
"connectedSnapAndNoAccountDescription": {
"message": "MetaMask được kết nối với trang web này, nhưng chưa có tài khoản nào được kết nối"
},
- "connectedWith": {
- "message": "Đã kết nối với"
- },
"connecting": {
"message": "Đang kết nối"
},
@@ -1507,14 +1504,6 @@
"disconnectAllSnapsText": {
"message": "Snap"
},
- "disconnectAllText": {
- "message": "Nếu bạn ngắt kết nối $1 khỏi $2, bạn sẽ cần kết nối lại để sử dụng lại.",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "Ngắt kết nối tất cả $1",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectPrompt": {
"message": "Ngắt kết nối $1"
},
@@ -2835,10 +2824,6 @@
"message": "$1 đang yêu cầu sự chấp thuận của bạn cho:",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "Bạn có muốn trang web này thực hiện những điều sau không?",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "Token gốc của mạng này là $1. Token này được dùng làm phí gas.",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/_locales/zh_CN/messages.json b/app/_locales/zh_CN/messages.json
index 9f33ef4a6b35..a5e2b1175862 100644
--- a/app/_locales/zh_CN/messages.json
+++ b/app/_locales/zh_CN/messages.json
@@ -1088,9 +1088,6 @@
"connectedSnapAndNoAccountDescription": {
"message": "MetaMask 已连接到此网站,但尚未连接任何账户"
},
- "connectedWith": {
- "message": "已连接"
- },
"connecting": {
"message": "连接中……"
},
@@ -1507,14 +1504,6 @@
"disconnectAllSnapsText": {
"message": "Snap"
},
- "disconnectAllText": {
- "message": "如果您将 $1 与 $2 断开连接,则需要重新连接才能再次使用。",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`, $2 represents the website hostname"
- },
- "disconnectAllTitle": {
- "message": "断开连接所有 $1",
- "description": "$1 will map to `disconnectAllAccountsText` or `disconnectAllSnapsText`"
- },
"disconnectPrompt": {
"message": "断开连接 $1"
},
@@ -2835,10 +2824,6 @@
"message": "$1 请求您的批准,以便:",
"description": "$1 represents dapp name"
},
- "nativePermissionRequestDescription": {
- "message": "您希望此网站执行以下操作吗?",
- "description": "Description below header used on Permission Connect screen for native permissions."
- },
"nativeToken": {
"message": "此网络上的原生代币为 $1。它是用于燃料费的代币。 ",
"description": "$1 represents the name of the native token on the current network"
diff --git a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js
index e224cb4a2b38..2f4727fdab36 100644
--- a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js
+++ b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.js
@@ -23,7 +23,6 @@ const addEthereumChain = {
getCurrentChainIdForDomain: true,
getCaveat: true,
requestPermittedChainsPermission: true,
- getChainPermissionsFeatureFlag: true,
grantPermittedChainsPermissionIncremental: true,
},
};
@@ -46,7 +45,6 @@ async function addEthereumChainHandler(
getCurrentChainIdForDomain,
getCaveat,
requestPermittedChainsPermission,
- getChainPermissionsFeatureFlag,
grantPermittedChainsPermissionIncremental,
},
) {
@@ -67,9 +65,6 @@ async function addEthereumChainHandler(
const { origin } = req;
const currentChainIdForDomain = getCurrentChainIdForDomain(origin);
- const currentNetworkConfiguration = getNetworkConfigurationByChainId(
- currentChainIdForDomain,
- );
const existingNetwork = getNetworkConfigurationByChainId(chainId);
if (
@@ -198,30 +193,14 @@ async function addEthereumChainHandler(
const { networkClientId } =
updatedNetwork.rpcEndpoints[updatedNetwork.defaultRpcEndpointIndex];
- const requestData = {
- toNetworkConfiguration: updatedNetwork,
- fromNetworkConfiguration: currentNetworkConfiguration,
- };
-
- return switchChain(
- res,
- end,
- origin,
- chainId,
- requestData,
- networkClientId,
- approvalFlowId,
- {
- isAddFlow: true,
- getChainPermissionsFeatureFlag,
- setActiveNetwork,
- requestUserApproval,
- getCaveat,
- requestPermittedChainsPermission,
- endApprovalFlow,
- grantPermittedChainsPermissionIncremental,
- },
- );
+ return switchChain(res, end, chainId, networkClientId, approvalFlowId, {
+ isAddFlow: true,
+ setActiveNetwork,
+ endApprovalFlow,
+ getCaveat,
+ requestPermittedChainsPermission,
+ grantPermittedChainsPermissionIncremental,
+ });
} else if (approvalFlowId) {
endApprovalFlow({ id: approvalFlowId });
}
diff --git a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.test.js b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.test.js
index f6be2deb6f08..945953cff562 100644
--- a/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.test.js
+++ b/app/scripts/lib/rpc-method-middleware/handlers/add-ethereum-chain.test.js
@@ -54,14 +54,8 @@ const createMockNonInfuraConfiguration = () => ({
describe('addEthereumChainHandler', () => {
const addEthereumChainHandler = addEthereumChain.implementation;
-
- const makeMocks = ({
- permissionedChainIds = [],
- permissionsFeatureFlagIsActive,
- overrides = {},
- } = {}) => {
+ const makeMocks = ({ permissionedChainIds = [], overrides = {} } = {}) => {
return {
- getChainPermissionsFeatureFlag: () => permissionsFeatureFlagIsActive,
getCurrentChainIdForDomain: jest
.fn()
.mockReturnValue(NON_INFURA_CHAIN_ID),
@@ -92,9 +86,7 @@ describe('addEthereumChainHandler', () => {
describe('with `endowment:permitted-chains` permissioning inactive', () => {
it('creates a new network configuration for the given chainid and switches to it if none exists', async () => {
- const mocks = makeMocks({
- permissionsFeatureFlagIsActive: false,
- });
+ const mocks = makeMocks();
await addEthereumChainHandler(
{
origin: 'example.com',
@@ -118,8 +110,7 @@ describe('addEthereumChainHandler', () => {
mocks,
);
- // called twice, once for the add and once for the switch
- expect(mocks.requestUserApproval).toHaveBeenCalledTimes(2);
+ expect(mocks.requestUserApproval).toHaveBeenCalledTimes(1);
expect(mocks.addNetwork).toHaveBeenCalledTimes(1);
expect(mocks.addNetwork).toHaveBeenCalledWith({
blockExplorerUrls: ['https://optimistic.etherscan.io'],
@@ -141,9 +132,7 @@ describe('addEthereumChainHandler', () => {
});
it('creates a new networkConfiguration when called without "blockExplorerUrls" property', async () => {
- const mocks = makeMocks({
- permissionsFeatureFlagIsActive: false,
- });
+ const mocks = makeMocks();
await addEthereumChainHandler(
{
origin: 'example.com',
@@ -172,7 +161,6 @@ describe('addEthereumChainHandler', () => {
describe('if a networkConfiguration for the given chainId already exists', () => {
it('updates the existing networkConfiguration with the new rpc url if it doesnt already exist', async () => {
const mocks = makeMocks({
- permissionsFeatureFlagIsActive: false,
overrides: {
getNetworkConfigurationByChainId: jest
.fn()
@@ -258,7 +246,6 @@ describe('addEthereumChainHandler', () => {
};
const mocks = makeMocks({
- permissionsFeatureFlagIsActive: false,
overrides: {
getNetworkConfigurationByChainId: jest
.fn()
@@ -305,7 +292,6 @@ describe('addEthereumChainHandler', () => {
const existingNetwork = createMockMainnetConfiguration();
const mocks = makeMocks({
- permissionsFeatureFlagIsActive: false,
overrides: {
// Start on sepolia
getCurrentChainIdForDomain: jest
@@ -349,9 +335,7 @@ describe('addEthereumChainHandler', () => {
});
it('should return error for invalid chainId', async () => {
- const mocks = makeMocks({
- permissionsFeatureFlagIsActive: false,
- });
+ const mocks = makeMocks();
const mockEnd = jest.fn();
await addEthereumChainHandler(
@@ -380,7 +364,6 @@ describe('addEthereumChainHandler', () => {
const mocks = makeMocks({
permissionedChainIds: [],
- permissionsFeatureFlagIsActive: true,
overrides: {
getCurrentChainIdForDomain: jest
.fn()
@@ -427,7 +410,6 @@ describe('addEthereumChainHandler', () => {
it('create a new networkConfiguration and switches to it without requesting permissions, if the requested chainId has `endowment:permitted-chains` permission granted for requesting origin', async () => {
const mocks = makeMocks({
permissionedChainIds: [CHAIN_IDS.MAINNET],
- permissionsFeatureFlagIsActive: true,
overrides: {
getCurrentChainIdForDomain: jest
.fn()
@@ -465,7 +447,6 @@ describe('addEthereumChainHandler', () => {
it('create a new networkConfiguration, requests permissions and switches to it, if the requested chainId does not have permittedChains permission granted for requesting origin', async () => {
const mocks = makeMocks({
- permissionsFeatureFlagIsActive: true,
permissionedChainIds: [],
overrides: {
getNetworkConfigurationByChainId: jest
@@ -516,7 +497,6 @@ describe('addEthereumChainHandler', () => {
createMockOptimismConfiguration().chainId,
CHAIN_IDS.MAINNET,
],
- permissionsFeatureFlagIsActive: true,
overrides: {
getCurrentChainIdForDomain: jest
.fn()
@@ -562,9 +542,7 @@ describe('addEthereumChainHandler', () => {
});
it('should return an error if an unexpected parameter is provided', async () => {
- const mocks = makeMocks({
- permissionsFeatureFlagIsActive: false,
- });
+ const mocks = makeMocks();
const mockEnd = jest.fn();
const unexpectedParam = 'unexpected';
@@ -604,7 +582,6 @@ describe('addEthereumChainHandler', () => {
it('should handle errors during the switch network permission request', async () => {
const mockError = new Error('Permission request failed');
const mocks = makeMocks({
- permissionsFeatureFlagIsActive: true,
permissionedChainIds: [],
overrides: {
getCurrentChainIdForDomain: jest
@@ -649,7 +626,6 @@ describe('addEthereumChainHandler', () => {
it('should return an error if nativeCurrency.symbol does not match an existing network with the same chainId', async () => {
const mocks = makeMocks({
permissionedChainIds: [CHAIN_IDS.MAINNET],
- permissionsFeatureFlagIsActive: true,
overrides: {
getNetworkConfigurationByChainId: jest
.fn()
@@ -691,7 +667,6 @@ describe('addEthereumChainHandler', () => {
const CURRENT_RPC_CONFIG = createMockNonInfuraConfiguration();
const mocks = makeMocks({
- permissionsFeatureFlagIsActive: false,
overrides: {
getCurrentChainIdForDomain: jest
.fn()
diff --git a/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.js b/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.js
index 57d14eb6e6b8..080fef549564 100644
--- a/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.js
+++ b/app/scripts/lib/rpc-method-middleware/handlers/ethereum-chain-utils.js
@@ -1,5 +1,4 @@
import { errorCodes, ethErrors } from 'eth-rpc-errors';
-import { ApprovalType } from '@metamask/controller-utils';
import {
isPrefixedFormattedHexString,
isSafeChainId,
@@ -156,46 +155,34 @@ export function validateAddEthereumChainParams(params, end) {
export async function switchChain(
res,
end,
- origin,
chainId,
- requestData,
networkClientId,
approvalFlowId,
{
isAddFlow,
- getChainPermissionsFeatureFlag,
setActiveNetwork,
endApprovalFlow,
- requestUserApproval,
getCaveat,
requestPermittedChainsPermission,
grantPermittedChainsPermissionIncremental,
},
) {
try {
- if (getChainPermissionsFeatureFlag()) {
- const { value: permissionedChainIds } =
- getCaveat({
- target: PermissionNames.permittedChains,
- caveatType: CaveatTypes.restrictNetworkSwitching,
- }) ?? {};
-
- if (
- permissionedChainIds === undefined ||
- !permissionedChainIds.includes(chainId)
- ) {
- if (isAddFlow) {
- await grantPermittedChainsPermissionIncremental([chainId]);
- } else {
- await requestPermittedChainsPermission([chainId]);
- }
+ const { value: permissionedChainIds } =
+ getCaveat({
+ target: PermissionNames.permittedChains,
+ caveatType: CaveatTypes.restrictNetworkSwitching,
+ }) ?? {};
+
+ if (
+ permissionedChainIds === undefined ||
+ !permissionedChainIds.includes(chainId)
+ ) {
+ if (isAddFlow) {
+ await grantPermittedChainsPermissionIncremental([chainId]);
+ } else {
+ await requestPermittedChainsPermission([chainId]);
}
- } else {
- await requestUserApproval({
- origin,
- type: ApprovalType.SwitchEthereumChain,
- requestData,
- });
}
await setActiveNetwork(networkClientId);
diff --git a/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js b/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js
index 847cdf8abe24..f43973e4ba57 100644
--- a/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js
+++ b/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.js
@@ -14,8 +14,7 @@ const switchEthereumChain = {
getCaveat: true,
requestPermittedChainsPermission: true,
getCurrentChainIdForDomain: true,
- requestUserApproval: true,
- getChainPermissionsFeatureFlag: true,
+ grantPermittedChainsPermissionIncremental: true,
},
};
@@ -32,8 +31,7 @@ async function switchEthereumChainHandler(
requestPermittedChainsPermission,
getCaveat,
getCurrentChainIdForDomain,
- requestUserApproval,
- getChainPermissionsFeatureFlag,
+ grantPermittedChainsPermissionIncremental,
},
) {
let chainId;
@@ -66,27 +64,10 @@ async function switchEthereumChainHandler(
);
}
- const requestData = {
- toNetworkConfiguration: networkConfigurationForRequestedChainId,
- fromNetworkConfiguration: getNetworkConfigurationByChainId(
- currentChainIdForOrigin,
- ),
- };
-
- return switchChain(
- res,
- end,
- origin,
- chainId,
- requestData,
- networkClientIdToSwitchTo,
- null,
- {
- getChainPermissionsFeatureFlag,
- setActiveNetwork,
- requestUserApproval,
- getCaveat,
- requestPermittedChainsPermission,
- },
- );
+ return switchChain(res, end, chainId, networkClientIdToSwitchTo, null, {
+ setActiveNetwork,
+ getCaveat,
+ requestPermittedChainsPermission,
+ grantPermittedChainsPermissionIncremental,
+ });
}
diff --git a/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.test.js b/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.test.js
index 30a9f9aa8f8e..be612fbc7d8e 100644
--- a/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.test.js
+++ b/app/scripts/lib/rpc-method-middleware/handlers/switch-ethereum-chain.test.js
@@ -6,10 +6,6 @@ import switchEthereumChain from './switch-ethereum-chain';
const NON_INFURA_CHAIN_ID = '0x123456789';
-const mockRequestUserApproval = ({ requestData }) => {
- return Promise.resolve(requestData.toNetworkConfiguration);
-};
-
const createMockMainnetConfiguration = () => ({
chainId: CHAIN_IDS.MAINNET,
defaultRpcEndpointIndex: 0,
@@ -33,7 +29,6 @@ const createMockLineaMainnetConfiguration = () => ({
describe('switchEthereumChainHandler', () => {
const makeMocks = ({
permissionedChainIds = [],
- permissionsFeatureFlagIsActive = false,
overrides = {},
mockedGetNetworkConfigurationByChainIdReturnValue = createMockMainnetConfiguration(),
mockedGetCurrentChainIdForDomainReturnValue = NON_INFURA_CHAIN_ID,
@@ -42,15 +37,11 @@ describe('switchEthereumChainHandler', () => {
mockGetCaveat.mockReturnValue({ value: permissionedChainIds });
return {
- getChainPermissionsFeatureFlag: () => permissionsFeatureFlagIsActive,
getCurrentChainIdForDomain: jest
.fn()
.mockReturnValue(mockedGetCurrentChainIdForDomainReturnValue),
setNetworkClientIdForDomain: jest.fn(),
setActiveNetwork: jest.fn(),
- requestUserApproval: jest
- .fn()
- .mockImplementation(mockRequestUserApproval),
requestPermittedChainsPermission: jest.fn(),
getCaveat: mockGetCaveat,
getNetworkConfigurationByChainId: jest
@@ -65,11 +56,8 @@ describe('switchEthereumChainHandler', () => {
});
describe('with permittedChains permissioning inactive', () => {
- const permissionsFeatureFlagIsActive = false;
-
it('should call setActiveNetwork when switching to a built-in infura network', async () => {
const mocks = makeMocks({
- permissionsFeatureFlagIsActive,
overrides: {
getNetworkConfigurationByChainId: jest
.fn()
@@ -95,7 +83,6 @@ describe('switchEthereumChainHandler', () => {
it('should call setActiveNetwork when switching to a built-in infura network, when chainId from request is lower case', async () => {
const mocks = makeMocks({
- permissionsFeatureFlagIsActive,
overrides: {
getNetworkConfigurationByChainId: jest
.fn()
@@ -121,7 +108,6 @@ describe('switchEthereumChainHandler', () => {
it('should call setActiveNetwork when switching to a built-in infura network, when chainId from request is upper case', async () => {
const mocks = makeMocks({
- permissionsFeatureFlagIsActive,
overrides: {
getNetworkConfigurationByChainId: jest
.fn()
@@ -147,7 +133,6 @@ describe('switchEthereumChainHandler', () => {
it('should call setActiveNetwork when switching to a custom network', async () => {
const mocks = makeMocks({
- permissionsFeatureFlagIsActive,
overrides: {
getCurrentChainIdForDomain: jest
.fn()
@@ -209,14 +194,11 @@ describe('switchEthereumChainHandler', () => {
});
describe('with permittedChains permissioning active', () => {
- const permissionsFeatureFlagIsActive = true;
-
it('should call requestPermittedChainsPermission and setActiveNetwork when chainId is not in `endowment:permitted-chains`', async () => {
const mockrequestPermittedChainsPermission = jest
.fn()
.mockResolvedValue();
const mocks = makeMocks({
- permissionsFeatureFlagIsActive,
overrides: {
requestPermittedChainsPermission:
mockrequestPermittedChainsPermission,
@@ -246,7 +228,6 @@ describe('switchEthereumChainHandler', () => {
it('should call setActiveNetwork without calling requestPermittedChainsPermission when requested chainId is in `endowment:permitted-chains`', async () => {
const mocks = makeMocks({
- permissionsFeatureFlagIsActive,
permissionedChainIds: [CHAIN_IDS.MAINNET],
});
const switchEthereumChainHandler = switchEthereumChain.implementation;
@@ -274,7 +255,6 @@ describe('switchEthereumChainHandler', () => {
.fn()
.mockRejectedValue(mockError);
const mocks = makeMocks({
- permissionsFeatureFlagIsActive,
overrides: {
requestPermittedChainsPermission:
mockrequestPermittedChainsPermission,
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index a5b110fadec2..cd899c57e179 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -232,6 +232,8 @@ import { getCurrentChainId } from '../../ui/selectors';
// eslint-disable-next-line import/no-restricted-paths
import { getProviderConfig } from '../../ui/ducks/metamask/metamask';
import { endTrace, trace } from '../../shared/lib/trace';
+// eslint-disable-next-line import/no-restricted-paths
+import { isSnapId } from '../../ui/helpers/utils/snaps';
import { BalancesController as MultichainBalancesController } from './lib/accounts/BalancesController';
import {
///: BEGIN:ONLY_INCLUDE_IF(build-mmi)
@@ -5745,7 +5747,7 @@ export default class MetamaskController extends EventEmitter {
{ origin },
{
eth_accounts: {},
- ...(process.env.CHAIN_PERMISSIONS && {
+ ...(!isSnapId(origin) && {
[PermissionNames.permittedChains]: {},
}),
},
@@ -5780,10 +5782,12 @@ export default class MetamaskController extends EventEmitter {
this.permissionController.requestPermissions(
{ origin },
{
- ...(process.env.CHAIN_PERMISSIONS &&
- requestedPermissions[RestrictedMethods.eth_accounts] && {
- [PermissionNames.permittedChains]: {},
- }),
+ ...(requestedPermissions[PermissionNames.eth_accounts] && {
+ [PermissionNames.permittedChains]: {},
+ }),
+ ...(requestedPermissions[PermissionNames.permittedChains] && {
+ [PermissionNames.eth_accounts]: {},
+ }),
...requestedPermissions,
},
),
@@ -5819,8 +5823,6 @@ export default class MetamaskController extends EventEmitter {
return undefined;
},
- getChainPermissionsFeatureFlag: () =>
- Boolean(process.env.CHAIN_PERMISSIONS),
// network configuration-related
setActiveNetwork: async (networkClientId) => {
await this.networkController.setActiveNetwork(networkClientId);
diff --git a/test/e2e/accounts/common.ts b/test/e2e/accounts/common.ts
index 60e0ea378b75..eda4ef5fbf6f 100644
--- a/test/e2e/accounts/common.ts
+++ b/test/e2e/accounts/common.ts
@@ -13,7 +13,7 @@ import {
regularDelayMs,
} from '../helpers';
import { Driver } from '../webdriver/driver';
-import { TEST_SNAPS_SIMPLE_KEYRING_WEBSITE_URL } from '../constants';
+import { DAPP_URL, TEST_SNAPS_SIMPLE_KEYRING_WEBSITE_URL } from '../constants';
import { retry } from '../../../development/lib/retry';
/**
@@ -201,16 +201,12 @@ export async function connectAccountToTestDapp(driver: Driver) {
await driver.delay(regularDelayMs);
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
- await driver.clickElement({
- text: 'Confirm',
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
+
+ await driver.switchToWindowWithUrl(DAPP_URL);
}
export async function disconnectFromTestDapp(driver: Driver) {
@@ -225,7 +221,6 @@ export async function disconnectFromTestDapp(driver: Driver) {
text: '127.0.0.1:8080',
tag: 'p',
});
- await driver.clickElement('[data-testid="account-list-item-menu-button"]');
await driver.clickElement({ text: 'Disconnect', tag: 'button' });
await driver.clickElement('[data-testid ="disconnect-all"]');
}
diff --git a/test/e2e/api-specs/ConfirmationRejectionRule.ts b/test/e2e/api-specs/ConfirmationRejectionRule.ts
index 503d0358c63c..3e37dcd07fd7 100644
--- a/test/e2e/api-specs/ConfirmationRejectionRule.ts
+++ b/test/e2e/api-specs/ConfirmationRejectionRule.ts
@@ -69,10 +69,24 @@ export class ConfirmationsRejectRule implements Rule {
await this.driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await this.driver.findClickableElements({
- text: 'Next',
+ text: 'Connect',
tag: 'button',
});
+ const editButtons = await this.driver.findElements(
+ '[data-testid="edit"]',
+ );
+ await editButtons[1].click();
+
+ await this.driver.clickElement({
+ text: 'Localhost 8545',
+ tag: 'p',
+ });
+
+ await this.driver.clickElement(
+ '[data-testid="connect-more-chains-button"]',
+ );
+
const screenshotTwo = await this.driver.driver.takeScreenshot();
call.attachments.push({
type: 'image',
@@ -80,15 +94,26 @@ export class ConfirmationsRejectRule implements Rule {
});
await this.driver.clickElement({
- text: 'Next',
+ text: 'Connect',
tag: 'button',
});
- await this.driver.clickElement({
- text: 'Confirm',
- tag: 'button',
+ await switchToOrOpenDapp(this.driver);
+
+ const switchEthereumChainRequest = JSON.stringify({
+ jsonrpc: '2.0',
+ method: 'wallet_switchEthereumChain',
+ params: [
+ {
+ chainId: '0x539', // 1337
+ },
+ ],
});
+ await this.driver.executeScript(
+ `window.ethereum.request(${switchEthereumChainRequest})`,
+ );
+
await switchToOrOpenDapp(this.driver);
}
} catch (e) {
diff --git a/test/e2e/helpers.js b/test/e2e/helpers.js
index cf337b84e8f5..643dcefa35ae 100644
--- a/test/e2e/helpers.js
+++ b/test/e2e/helpers.js
@@ -755,12 +755,19 @@ const connectToDapp = async (driver) => {
});
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+
+ const editButtons = await driver.findElements('[data-testid="edit"]');
+ await editButtons[1].click();
+
await driver.clickElement({
- text: 'Next',
- tag: 'button',
+ text: 'Localhost 8545',
+ tag: 'p',
});
+
+ await driver.clickElement('[data-testid="connect-more-chains-button"]');
+
await driver.clickElementAndWaitForWindowToClose({
- text: 'Confirm',
+ text: 'Connect',
tag: 'button',
});
await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
diff --git a/test/e2e/json-rpc/switchEthereumChain.spec.js b/test/e2e/json-rpc/switchEthereumChain.spec.js
index 75715b6ff00b..fba06db48131 100644
--- a/test/e2e/json-rpc/switchEthereumChain.spec.js
+++ b/test/e2e/json-rpc/switchEthereumChain.spec.js
@@ -7,6 +7,7 @@ const {
DAPP_ONE_URL,
unlockWallet,
switchToNotificationWindow,
+ WINDOW_TITLES,
} = require('../helpers');
const FixtureBuilder = require('../fixture-builder');
const { isManifestV3 } = require('../../../shared/modules/mv3.utils');
@@ -17,7 +18,6 @@ describe('Switch Ethereum Chain for two dapps', function () {
{
dapp: true,
fixtures: new FixtureBuilder()
- .withPermissionControllerConnectedToTwoTestDapps()
.withNetworkControllerDoubleGanache()
.build(),
dappOptions: { numberOfDapps: 2 },
@@ -74,10 +74,10 @@ describe('Switch Ethereum Chain for two dapps', function () {
// Confirm switchEthereumChain
await switchToNotificationWindow(driver, 4);
await driver.findClickableElements({
- text: 'Switch network',
+ text: 'Confirm',
tag: 'button',
});
- await driver.clickElement({ text: 'Switch network', tag: 'button' });
+ await driver.clickElement({ text: 'Confirm', tag: 'button' });
// Switch to Dapp One
await driver.switchToWindow(dappOne);
@@ -107,7 +107,6 @@ describe('Switch Ethereum Chain for two dapps', function () {
{
dapp: true,
fixtures: new FixtureBuilder()
- .withPermissionControllerConnectedToTwoTestDapps()
.withNetworkControllerDoubleGanache()
.build(),
dappOptions: { numberOfDapps: 2 },
@@ -145,24 +144,39 @@ describe('Switch Ethereum Chain for two dapps', function () {
);
// open two dapps
- const dappOne = await openDapp(driver, undefined, DAPP_URL);
+ await openDapp(driver, undefined, DAPP_URL);
await openDapp(driver, undefined, DAPP_ONE_URL);
+ await driver.findClickableElement({ text: 'Connect', tag: 'button' });
+ await driver.clickElement('#connectButton');
+
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
+ tag: 'button',
+ });
+
+ await driver.switchToWindowWithUrl(DAPP_ONE_URL);
+
// Initiate send transaction on Dapp two
await driver.clickElement('#sendButton');
- await driver.delay(2000);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+ await driver.findClickableElements({
+ text: 'Confirm',
+ tag: 'button',
+ });
+
+ // Switch to Dapp One
+ await driver.switchToWindowWithUrl(DAPP_URL);
// Switch Ethereum chain request
const switchEthereumChainRequest = JSON.stringify({
jsonrpc: '2.0',
method: 'wallet_switchEthereumChain',
- params: [{ chainId: '0x53a' }],
+ params: [{ chainId: '0x539' }],
});
- // Switch to Dapp One
- await driver.switchToWindow(dappOne);
- assert.equal(await driver.getCurrentUrl(), `${DAPP_URL}/`);
-
// Initiate switchEthereumChain on Dapp One
await driver.executeScript(
`window.ethereum.request(${switchEthereumChainRequest})`,
@@ -186,10 +200,10 @@ describe('Switch Ethereum Chain for two dapps', function () {
await switchToNotificationWindow(driver, 4);
await driver.findClickableElements({
- text: 'Switch network',
+ text: 'Confirm',
tag: 'button',
});
- await driver.clickElement({ text: 'Switch network', tag: 'button' });
+ await driver.clickElement({ text: 'Confirm', tag: 'button' });
},
);
});
@@ -199,7 +213,6 @@ describe('Switch Ethereum Chain for two dapps', function () {
{
dapp: true,
fixtures: new FixtureBuilder()
- .withPermissionControllerConnectedToTwoTestDapps()
.withNetworkControllerDoubleGanache()
.build(),
dappOptions: { numberOfDapps: 2 },
@@ -237,14 +250,43 @@ describe('Switch Ethereum Chain for two dapps', function () {
);
// open two dapps
+ const dappTwo = await openDapp(driver, undefined, DAPP_ONE_URL);
const dappOne = await openDapp(driver, undefined, DAPP_URL);
- await openDapp(driver, undefined, DAPP_ONE_URL);
+
+ // Connect Dapp One
+ await driver.findClickableElement({ text: 'Connect', tag: 'button' });
+ await driver.clickElement('#connectButton');
+
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
+ tag: 'button',
+ });
+
+ // Switch and connect Dapp Two
+
+ await driver.switchToWindow(dappTwo);
+ assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`);
+
+ await driver.findClickableElement({ text: 'Connect', tag: 'button' });
+ await driver.clickElement('#connectButton');
+
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
+ tag: 'button',
+ });
+
+ await driver.switchToWindow(dappTwo);
+ assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`);
// switchEthereumChain request
const switchEthereumChainRequest = JSON.stringify({
jsonrpc: '2.0',
method: 'wallet_switchEthereumChain',
- params: [{ chainId: '0x53a' }],
+ params: [{ chainId: '0x539' }],
});
// Initiate switchEthereumChain on Dapp Two
@@ -253,13 +295,13 @@ describe('Switch Ethereum Chain for two dapps', function () {
);
// Switch to notification of switchEthereumChain
- await switchToNotificationWindow(driver, 4);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await driver.findClickableElements({
- text: 'Switch network',
+ text: 'Confirm',
tag: 'button',
});
- // Switch to dapp one
+ // Switch back to dapp one
await driver.switchToWindow(dappOne);
assert.equal(await driver.getCurrentUrl(), `${DAPP_URL}/`);
@@ -268,15 +310,16 @@ describe('Switch Ethereum Chain for two dapps', function () {
await driver.delay(2000);
// Switch to notification that should still be switchEthereumChain request but with a warning.
- await switchToNotificationWindow(driver, 4);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.findElement({
- span: 'span',
- text: 'Switching networks will cancel all pending confirmations',
- });
+ // THIS IS BROKEN
+ // await driver.findElement({
+ // span: 'span',
+ // text: 'Switching networks will cancel all pending confirmations',
+ // });
// Confirm switchEthereumChain with queued pending tx
- await driver.clickElement({ text: 'Switch network', tag: 'button' });
+ await driver.clickElement({ text: 'Confirm', tag: 'button' });
// Window handles should only be expanded mm, dapp one, dapp 2, and the offscreen document
// if this is an MV3 build(3 or 4 total)
@@ -294,7 +337,6 @@ describe('Switch Ethereum Chain for two dapps', function () {
{
dapp: true,
fixtures: new FixtureBuilder()
- .withPermissionControllerConnectedToTwoTestDapps()
.withNetworkControllerDoubleGanache()
.build(),
dappOptions: { numberOfDapps: 2 },
@@ -332,14 +374,42 @@ describe('Switch Ethereum Chain for two dapps', function () {
);
// open two dapps
+ const dappTwo = await openDapp(driver, undefined, DAPP_ONE_URL);
const dappOne = await openDapp(driver, undefined, DAPP_URL);
- await openDapp(driver, undefined, DAPP_ONE_URL);
+
+ // Connect Dapp One
+ await driver.findClickableElement({ text: 'Connect', tag: 'button' });
+ await driver.clickElement('#connectButton');
+
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
+ tag: 'button',
+ });
+
+ // Switch and connect Dapp Two
+ await driver.switchToWindow(dappTwo);
+ assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`);
+
+ await driver.findClickableElement({ text: 'Connect', tag: 'button' });
+ await driver.clickElement('#connectButton');
+
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
+ tag: 'button',
+ });
+
+ await driver.switchToWindow(dappTwo);
+ assert.equal(await driver.getCurrentUrl(), `${DAPP_ONE_URL}/`);
// switchEthereumChain request
const switchEthereumChainRequest = JSON.stringify({
jsonrpc: '2.0',
method: 'wallet_switchEthereumChain',
- params: [{ chainId: '0x53a' }],
+ params: [{ chainId: '0x539' }],
});
// Initiate switchEthereumChain on Dapp Two
@@ -348,13 +418,13 @@ describe('Switch Ethereum Chain for two dapps', function () {
);
// Switch to notification of switchEthereumChain
- await switchToNotificationWindow(driver, 4);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await driver.findClickableElements({
- text: 'Switch network',
+ text: 'Confirm',
tag: 'button',
});
- // Switch to dapp one
+ // Switch back to dapp one
await driver.switchToWindow(dappOne);
assert.equal(await driver.getCurrentUrl(), `${DAPP_URL}/`);
@@ -363,12 +433,13 @@ describe('Switch Ethereum Chain for two dapps', function () {
await driver.delay(2000);
// Switch to notification that should still be switchEthereumChain request but with an warning.
- await switchToNotificationWindow(driver, 4);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.findElement({
- span: 'span',
- text: 'Switching networks will cancel all pending confirmations',
- });
+ // THIS IS BROKEN
+ // await driver.findElement({
+ // span: 'span',
+ // text: 'Switching networks will cancel all pending confirmations',
+ // });
// Cancel switchEthereumChain with queued pending tx
await driver.clickElement({ text: 'Cancel', tag: 'button' });
@@ -377,7 +448,7 @@ describe('Switch Ethereum Chain for two dapps', function () {
await driver.delay(1000);
// Switch to new pending tx notification
- await switchToNotificationWindow(driver, 4);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await driver.findElement({
text: 'Sending ETH',
tag: 'span',
diff --git a/test/e2e/json-rpc/wallet_requestPermissions.spec.js b/test/e2e/json-rpc/wallet_requestPermissions.spec.js
index 917e30ca12fc..5484fdf73d80 100644
--- a/test/e2e/json-rpc/wallet_requestPermissions.spec.js
+++ b/test/e2e/json-rpc/wallet_requestPermissions.spec.js
@@ -38,12 +38,7 @@ describe('wallet_requestPermissions', function () {
await switchToNotificationWindow(driver);
await driver.clickElement({
- text: 'Next',
- tag: 'button',
- });
-
- await driver.clickElement({
- text: 'Confirm',
+ text: 'Connect',
tag: 'button',
});
diff --git a/test/e2e/snaps/test-snap-txinsights-v2.spec.js b/test/e2e/snaps/test-snap-txinsights-v2.spec.js
index 0b43dca40ffc..5fb56687de96 100644
--- a/test/e2e/snaps/test-snap-txinsights-v2.spec.js
+++ b/test/e2e/snaps/test-snap-txinsights-v2.spec.js
@@ -2,7 +2,6 @@ const {
defaultGanacheOptions,
withFixtures,
unlockWallet,
- switchToNotificationWindow,
WINDOW_TITLES,
} = require('../helpers');
const FixtureBuilder = require('../fixture-builder');
@@ -37,22 +36,18 @@ describe('Test Snap TxInsights-v2', function () {
await driver.clickElement('#connecttransaction-insights');
// switch to metamask extension and click connect
- await switchToNotificationWindow(driver);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await driver.clickElement({
text: 'Connect',
tag: 'button',
});
- await driver.waitForSelector({ text: 'Confirm' });
-
await driver.clickElement({
text: 'Confirm',
tag: 'button',
});
- await driver.waitForSelector({ text: 'OK' });
-
- await driver.clickElement({
+ await driver.clickElementAndWaitForWindowToClose({
text: 'OK',
tag: 'button',
});
@@ -62,17 +57,9 @@ describe('Test Snap TxInsights-v2', function () {
await driver.clickElement('#getAccounts');
// switch back to MetaMask window and deal with dialogs
- await switchToNotificationWindow(driver);
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- });
- await driver.waitForSelector({
- text: 'Confirm',
- tag: 'button',
- });
- await driver.clickElement({
- text: 'Confirm',
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
tag: 'button',
});
@@ -82,7 +69,7 @@ describe('Test Snap TxInsights-v2', function () {
// switch back to MetaMask window and switch to tx insights pane
await driver.delay(2000);
- await switchToNotificationWindow(driver);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await driver.findClickableElement({
text: 'Confirm',
@@ -140,12 +127,6 @@ describe('Test Snap TxInsights-v2', function () {
tag: 'button',
text: 'Activity',
});
-
- // wait for transaction confirmation
- await driver.waitForSelector({
- css: '.transaction-status-label',
- text: 'Confirmed',
- });
},
);
});
diff --git a/test/e2e/snaps/test-snap-txinsights.spec.js b/test/e2e/snaps/test-snap-txinsights.spec.js
index ff93a2ea910b..7f6b7a3bec46 100644
--- a/test/e2e/snaps/test-snap-txinsights.spec.js
+++ b/test/e2e/snaps/test-snap-txinsights.spec.js
@@ -2,7 +2,6 @@ const {
defaultGanacheOptions,
withFixtures,
unlockWallet,
- switchToNotificationWindow,
WINDOW_TITLES,
} = require('../helpers');
const FixtureBuilder = require('../fixture-builder');
@@ -37,22 +36,18 @@ describe('Test Snap TxInsights', function () {
await driver.clickElement('#connecttransaction-insights');
// switch to metamask extension and click connect
- await switchToNotificationWindow(driver, 2);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await driver.clickElement({
text: 'Connect',
tag: 'button',
});
- await driver.waitForSelector({ text: 'Confirm' });
-
await driver.clickElement({
text: 'Confirm',
tag: 'button',
});
- await driver.waitForSelector({ text: 'OK' });
-
- await driver.clickElement({
+ await driver.clickElementAndWaitForWindowToClose({
text: 'OK',
tag: 'button',
});
@@ -62,17 +57,9 @@ describe('Test Snap TxInsights', function () {
await driver.clickElement('#getAccounts');
// switch back to MetaMask window and deal with dialogs
- await switchToNotificationWindow(driver, 2);
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- });
- await driver.waitForSelector({
- text: 'Confirm',
- tag: 'button',
- });
- await driver.clickElement({
- text: 'Confirm',
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
tag: 'button',
});
@@ -82,11 +69,8 @@ describe('Test Snap TxInsights', function () {
// switch back to MetaMask window and switch to tx insights pane
await driver.delay(2000);
- await switchToNotificationWindow(driver, 2);
- await driver.waitForSelector({
- text: 'Insights Example Snap',
- tag: 'button',
- });
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+
await driver.clickElement({
text: 'Insights Example Snap',
tag: 'button',
diff --git a/test/e2e/tests/connections/connect-with-metamask.spec.js b/test/e2e/tests/connections/connect-with-metamask.spec.js
new file mode 100644
index 000000000000..5611b40346db
--- /dev/null
+++ b/test/e2e/tests/connections/connect-with-metamask.spec.js
@@ -0,0 +1,79 @@
+const { strict: assert } = require('assert');
+const {
+ withFixtures,
+ WINDOW_TITLES,
+ logInWithBalanceValidation,
+ defaultGanacheOptions,
+ openDapp,
+} = require('../../helpers');
+const FixtureBuilder = require('../../fixture-builder');
+
+describe('Connections page', function () {
+ it('should render new connections flow', async function () {
+ await withFixtures(
+ {
+ dapp: true,
+ fixtures: new FixtureBuilder().build(),
+ title: this.test.fullTitle(),
+ ganacheOptions: defaultGanacheOptions,
+ },
+ async ({ driver, ganacheServer }) => {
+ await logInWithBalanceValidation(driver, ganacheServer);
+ await openDapp(driver);
+ // Connect to dapp
+ await driver.clickElement({
+ text: 'Connect',
+ tag: 'button',
+ });
+
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+
+ // should render new connections page
+ const newConnectionPage = await driver.waitForSelector({
+ tag: 'h2',
+ text: 'Connect with MetaMask',
+ });
+ assert.ok(newConnectionPage, 'Connection Page is defined');
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
+ tag: 'button',
+ });
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
+
+ // It should render connected status for button if dapp is connected
+ const getConnectedStatus = await driver.waitForSelector({
+ css: '#connectButton',
+ text: 'Connected',
+ });
+ assert.ok(getConnectedStatus, 'Account is connected to Dapp');
+
+ // Switch to extension Tab
+ await driver.switchToWindowWithTitle(
+ WINDOW_TITLES.ExtensionInFullScreenView,
+ );
+ await driver.clickElement(
+ '[data-testid ="account-options-menu-button"]',
+ );
+ await driver.clickElement({ text: 'All Permissions', tag: 'div' });
+ await driver.clickElementAndWaitToDisappear({
+ text: 'Got it',
+ tag: 'button',
+ });
+ await driver.clickElement({
+ text: '127.0.0.1:8080',
+ tag: 'p',
+ });
+ const connectionsPageAccountInfo = await driver.isElementPresent({
+ text: 'See your accounts and suggest transactions',
+ tag: 'p',
+ });
+ assert.ok(connectionsPageAccountInfo, 'Connections Page is defined');
+ const connectionsPageNetworkInfo = await driver.isElementPresent({
+ text: 'Use your enabled networks',
+ tag: 'p',
+ });
+ assert.ok(connectionsPageNetworkInfo, 'Connections Page is defined');
+ },
+ );
+ });
+});
diff --git a/test/e2e/tests/connections/edit-account-flow.spec.js b/test/e2e/tests/connections/edit-account-flow.spec.js
new file mode 100644
index 000000000000..7b05f439714c
--- /dev/null
+++ b/test/e2e/tests/connections/edit-account-flow.spec.js
@@ -0,0 +1,101 @@
+const { strict: assert } = require('assert');
+const {
+ withFixtures,
+ WINDOW_TITLES,
+ connectToDapp,
+ logInWithBalanceValidation,
+ locateAccountBalanceDOM,
+ defaultGanacheOptions,
+} = require('../../helpers');
+const FixtureBuilder = require('../../fixture-builder');
+
+const accountLabel2 = '2nd custom name';
+const accountLabel3 = '3rd custom name';
+describe('Edit Accounts Flow', function () {
+ it('should be able to edit accounts', async function () {
+ await withFixtures(
+ {
+ dapp: true,
+ fixtures: new FixtureBuilder().build(),
+ title: this.test.fullTitle(),
+ ganacheOptions: defaultGanacheOptions,
+ },
+ async ({ driver, ganacheServer }) => {
+ await logInWithBalanceValidation(driver, ganacheServer);
+ await connectToDapp(driver);
+
+ // It should render connected status for button if dapp is connected
+ const getConnectedStatus = await driver.waitForSelector({
+ css: '#connectButton',
+ text: 'Connected',
+ });
+ assert.ok(getConnectedStatus, 'Account is connected to Dapp');
+
+ // Switch to extension Tab
+ await driver.switchToWindowWithTitle(
+ WINDOW_TITLES.ExtensionInFullScreenView,
+ );
+ await driver.clickElement('[data-testid="account-menu-icon"]');
+ await driver.clickElement(
+ '[data-testid="multichain-account-menu-popover-action-button"]',
+ );
+ await driver.clickElement(
+ '[data-testid="multichain-account-menu-popover-add-account"]',
+ );
+ await driver.fill('[placeholder="Account 2"]', accountLabel2);
+ await driver.clickElement({ text: 'Add account', tag: 'button' });
+ await driver.clickElement('[data-testid="account-menu-icon"]');
+ await driver.clickElement(
+ '[data-testid="multichain-account-menu-popover-action-button"]',
+ );
+ await driver.clickElement(
+ '[data-testid="multichain-account-menu-popover-add-account"]',
+ );
+ await driver.fill('[placeholder="Account 3"]', accountLabel3);
+ await driver.clickElement({ text: 'Add account', tag: 'button' });
+ await locateAccountBalanceDOM(driver);
+ await driver.clickElement(
+ '[data-testid ="account-options-menu-button"]',
+ );
+ await driver.clickElement({ text: 'All Permissions', tag: 'div' });
+ await driver.clickElementAndWaitToDisappear({
+ text: 'Got it',
+ tag: 'button',
+ });
+ await driver.clickElement({
+ text: '127.0.0.1:8080',
+ tag: 'p',
+ });
+ const connectionsPageAccountInfo = await driver.isElementPresent({
+ text: 'See your accounts and suggest transactions',
+ tag: 'p',
+ });
+ assert.ok(connectionsPageAccountInfo, 'Connections Page is defined');
+ const editButtons = await driver.findElements('[data-testid="edit"]');
+
+ // Ensure there are edit buttons
+ assert.ok(editButtons.length > 0, 'Edit buttons are available');
+
+ // Click the first (0th) edit button
+ await editButtons[0].click();
+
+ await driver.clickElement({
+ text: '2nd custom name',
+ tag: 'button',
+ });
+ await driver.clickElement({
+ text: '3rd custom name',
+ tag: 'button',
+ });
+ await driver.clickElement(
+ '[data-testid="connect-more-accounts-button"]',
+ );
+ const updatedAccountInfo = await driver.isElementPresent({
+ text: '3 accounts connected',
+ tag: 'span',
+ });
+ assert.ok(updatedAccountInfo, 'Accounts List Updated');
+ },
+ );
+ });
+});
diff --git a/test/e2e/tests/connections/edit-networks-flow.spec.js b/test/e2e/tests/connections/edit-networks-flow.spec.js
new file mode 100644
index 000000000000..e14e1ae325d5
--- /dev/null
+++ b/test/e2e/tests/connections/edit-networks-flow.spec.js
@@ -0,0 +1,85 @@
+const { strict: assert } = require('assert');
+const {
+ withFixtures,
+ WINDOW_TITLES,
+ connectToDapp,
+ logInWithBalanceValidation,
+ locateAccountBalanceDOM,
+ defaultGanacheOptions,
+} = require('../../helpers');
+const FixtureBuilder = require('../../fixture-builder');
+
+async function switchToNetworkByName(driver, networkName) {
+ await driver.clickElement('.mm-picker-network');
+ await driver.clickElement(`[data-testid="${networkName}"]`);
+}
+
+describe('Edit Networks Flow', function () {
+ it('should be able to edit networks', async function () {
+ await withFixtures(
+ {
+ dapp: true,
+ fixtures: new FixtureBuilder().build(),
+ title: this.test.fullTitle(),
+ ganacheOptions: defaultGanacheOptions,
+ },
+ async ({ driver, ganacheServer }) => {
+ await logInWithBalanceValidation(driver, ganacheServer);
+ await connectToDapp(driver);
+
+ // It should render connected status for button if dapp is connected
+ const getConnectedStatus = await driver.waitForSelector({
+ css: '#connectButton',
+ text: 'Connected',
+ });
+ assert.ok(getConnectedStatus, 'Account is connected to Dapp');
+
+ // Switch to extension Tab
+ await driver.switchToWindowWithTitle(
+ WINDOW_TITLES.ExtensionInFullScreenView,
+ );
+ await driver.clickElement('[data-testid="network-display"]');
+ await driver.clickElement('.mm-modal-content__dialog .toggle-button');
+ await driver.clickElement(
+ '.mm-modal-content__dialog button[aria-label="Close"]',
+ );
+
+ // Switch to first network, whose send transaction was just confirmed
+ await switchToNetworkByName(driver, 'Localhost 8545');
+ await locateAccountBalanceDOM(driver);
+ await driver.clickElement(
+ '[data-testid ="account-options-menu-button"]',
+ );
+ await driver.clickElement({ text: 'All Permissions', tag: 'div' });
+ await driver.clickElementAndWaitToDisappear({
+ text: 'Got it',
+ tag: 'button',
+ });
+ await driver.clickElement({
+ text: '127.0.0.1:8080',
+ tag: 'p',
+ });
+ const editButtons = await driver.findElements('[data-testid="edit"]');
+
+ // Ensure there are edit buttons
+ assert.ok(editButtons.length > 0, 'Edit buttons are available');
+
+ // Click the first (0th) edit button
+ await editButtons[1].click();
+
+ // Disconnect Mainnet
+ await driver.clickElement({
+ text: 'Ethereum Mainnet',
+ tag: 'p',
+ });
+
+ await driver.clickElement('[data-testid="connect-more-chains-button"]');
+ const updatedNetworkInfo = await driver.isElementPresent({
+ text: '2 networks connected',
+ tag: 'span',
+ });
+ assert.ok(updatedNetworkInfo, 'Networks List Updated');
+ },
+ );
+ });
+});
diff --git a/test/e2e/tests/connections/review-permissions-page.spec.js b/test/e2e/tests/connections/review-permissions-page.spec.js
new file mode 100644
index 000000000000..d411a343b2c9
--- /dev/null
+++ b/test/e2e/tests/connections/review-permissions-page.spec.js
@@ -0,0 +1,145 @@
+const { strict: assert } = require('assert');
+const {
+ withFixtures,
+ WINDOW_TITLES,
+ connectToDapp,
+ logInWithBalanceValidation,
+ defaultGanacheOptions,
+} = require('../../helpers');
+const FixtureBuilder = require('../../fixture-builder');
+
+describe('Review Permissions page', function () {
+ it('should show connections page', async function () {
+ await withFixtures(
+ {
+ dapp: true,
+ fixtures: new FixtureBuilder().build(),
+ title: this.test.fullTitle(),
+ ganacheOptions: defaultGanacheOptions,
+ },
+ async ({ driver, ganacheServer }) => {
+ await logInWithBalanceValidation(driver, ganacheServer);
+ await connectToDapp(driver);
+
+ // It should render connected status for button if dapp is connected
+ const getConnectedStatus = await driver.waitForSelector({
+ css: '#connectButton',
+ text: 'Connected',
+ });
+ assert.ok(getConnectedStatus, 'Account is connected to Dapp');
+
+ // Switch to extension Tab
+ await driver.switchToWindowWithTitle(
+ WINDOW_TITLES.ExtensionInFullScreenView,
+ );
+ await driver.clickElement(
+ '[data-testid ="account-options-menu-button"]',
+ );
+ await driver.clickElement({ text: 'All Permissions', tag: 'div' });
+ await driver.clickElementAndWaitToDisappear({
+ text: 'Got it',
+ tag: 'button',
+ });
+ await driver.clickElement({
+ text: '127.0.0.1:8080',
+ tag: 'p',
+ });
+ const reviewPermissionsAccountInfo = await driver.isElementPresent({
+ text: 'See your accounts and suggest transactions',
+ tag: 'p',
+ });
+ assert.ok(
+ reviewPermissionsAccountInfo,
+ 'Review Permissions Page is defined',
+ );
+ const reviewPermissionsNetworkInfo = await driver.isElementPresent({
+ text: 'Use your enabled networks',
+ tag: 'p',
+ });
+ assert.ok(
+ reviewPermissionsNetworkInfo,
+ 'Review Permissions Page is defined',
+ );
+ },
+ );
+ });
+ it('should disconnect when click on Disconnect button in connections page', async function () {
+ await withFixtures(
+ {
+ dapp: true,
+ fixtures: new FixtureBuilder().build(),
+ title: this.test.fullTitle(),
+ ganacheOptions: defaultGanacheOptions,
+ },
+ async ({ driver, ganacheServer }) => {
+ await logInWithBalanceValidation(driver, ganacheServer);
+ await connectToDapp(driver);
+
+ // It should render connected status for button if dapp is connected
+ const getConnectedStatus = await driver.waitForSelector({
+ css: '#connectButton',
+ text: 'Connected',
+ });
+ assert.ok(getConnectedStatus, 'Account is connected to Dapp');
+
+ // Switch to extension Tab
+ await driver.switchToWindowWithTitle(
+ WINDOW_TITLES.ExtensionInFullScreenView,
+ );
+ await driver.clickElement(
+ '[data-testid ="account-options-menu-button"]',
+ );
+ await driver.clickElement({ text: 'All Permissions', tag: 'div' });
+ await driver.clickElementAndWaitToDisappear({
+ text: 'Got it',
+ tag: 'button',
+ });
+ await driver.clickElement({
+ text: '127.0.0.1:8080',
+ tag: 'p',
+ });
+ const reviewPermissionsAccountInfo = await driver.isElementPresent({
+ text: 'See your accounts and suggest transactions',
+ tag: 'p',
+ });
+ assert.ok(
+ reviewPermissionsAccountInfo,
+ 'Accounts are defined for Review Permissions Page',
+ );
+ const reviewPermissionsNetworkInfo = await driver.isElementPresent({
+ text: 'Use your enabled networks',
+ tag: 'p',
+ });
+ assert.ok(
+ reviewPermissionsNetworkInfo,
+ 'Networks are defined for Review Permissions Page',
+ );
+ await driver.clickElement({ text: 'Disconnect', tag: 'button' });
+ await driver.clickElement('[data-testid ="disconnect-all"]');
+ const noAccountConnected = await driver.isElementPresent({
+ text: 'MetaMask isn’t connected to this site',
+ tag: 'p',
+ });
+ assert.ok(
+ noAccountConnected,
+ 'Account disconected from connections page',
+ );
+
+ // Switch back to Dapp
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
+
+ // Button should show Connect text if dapp is not connected
+
+ const getConnectStatus = await driver.waitForSelector({
+ css: '#connectButton',
+ text: 'Connect',
+ });
+
+ assert.ok(
+ getConnectStatus,
+ 'Account is not connected to Dapp and button has text connect',
+ );
+ },
+ );
+ });
+});
diff --git a/test/e2e/tests/connections/review-switch-permission-page.spec.js b/test/e2e/tests/connections/review-switch-permission-page.spec.js
new file mode 100644
index 000000000000..5fe3d6d19526
--- /dev/null
+++ b/test/e2e/tests/connections/review-switch-permission-page.spec.js
@@ -0,0 +1,154 @@
+const { strict: assert } = require('assert');
+const FixtureBuilder = require('../../fixture-builder');
+const {
+ withFixtures,
+ openDapp,
+ unlockWallet,
+ DAPP_URL,
+ regularDelayMs,
+ WINDOW_TITLES,
+ defaultGanacheOptions,
+ switchToNotificationWindow,
+} = require('../../helpers');
+const { PAGES } = require('../../webdriver/driver');
+
+describe('Permissions Page when Dapp Switch to an enabled and non permissioned network', function () {
+ it('should switch to the chain when dapp tries to switch network to an enabled network after showing updated permissions page', async function () {
+ const port = 8546;
+ const chainId = 1338;
+ await withFixtures(
+ {
+ dapp: true,
+ fixtures: new FixtureBuilder()
+ .withNetworkControllerDoubleGanache()
+ .withPreferencesControllerUseRequestQueueEnabled()
+ .withSelectedNetworkControllerPerDomain()
+ .build(),
+ ganacheOptions: {
+ ...defaultGanacheOptions,
+ concurrent: [
+ {
+ port,
+ chainId,
+ ganacheOptions2: defaultGanacheOptions,
+ },
+ ],
+ },
+ title: this.test.fullTitle(),
+ },
+ async ({ driver }) => {
+ await unlockWallet(driver);
+
+ // Navigate to extension home screen
+ await driver.navigate(PAGES.HOME);
+
+ // Open Dapp One
+ await openDapp(driver, undefined, DAPP_URL);
+
+ await driver.delay(regularDelayMs);
+
+ const chainIdRequest = JSON.stringify({
+ method: 'eth_chainId',
+ });
+
+ const chainIdBeforeConnect = await driver.executeScript(
+ `return window.ethereum.request(${chainIdRequest})`,
+ );
+
+ assert.equal(chainIdBeforeConnect, '0x539'); // 1337
+
+ await driver.switchToWindowWithTitle(
+ WINDOW_TITLES.ExtensionInFullScreenView,
+ );
+
+ // Network Selector
+ await driver.clickElement('[data-testid="network-display"]');
+
+ // Switch to second network
+ await driver.clickElement({
+ text: 'Ethereum Mainnet',
+ css: 'p',
+ });
+
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
+
+ const chainIdBeforeConnectAfterManualSwitch =
+ await driver.executeScript(
+ `return window.ethereum.request(${chainIdRequest})`,
+ );
+
+ // before connecting the chainId should change with the wallet
+ assert.equal(chainIdBeforeConnectAfterManualSwitch, '0x1');
+
+ // Connect to dapp
+ await driver.findClickableElement({ text: 'Connect', tag: 'button' });
+ await driver.clickElement('#connectButton');
+
+ await driver.delay(regularDelayMs);
+
+ await switchToNotificationWindow(driver);
+
+ await driver.clickElement({
+ text: 'Connect',
+ tag: 'button',
+ });
+
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
+
+ const chainIdAfterConnect = await driver.executeScript(
+ `return window.ethereum.request(${chainIdRequest})`,
+ );
+
+ // should still be on the same chainId as the wallet after connecting
+ assert.equal(chainIdAfterConnect, '0x1');
+
+ const switchEthereumChainRequest = JSON.stringify({
+ jsonrpc: '2.0',
+ method: 'wallet_switchEthereumChain',
+ params: [{ chainId: '0x539' }],
+ });
+
+ await driver.executeScript(
+ `window.ethereum.request(${switchEthereumChainRequest})`,
+ );
+
+ await switchToNotificationWindow(driver);
+ await driver.findClickableElements({
+ text: 'Confirm',
+ tag: 'button',
+ });
+
+ await driver.clickElement({ text: 'Confirm', tag: 'button' });
+
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
+
+ const chainIdAfterDappSwitch = await driver.executeScript(
+ `return window.ethereum.request(${chainIdRequest})`,
+ );
+
+ // should be on the new chainId that was requested
+ assert.equal(chainIdAfterDappSwitch, '0x539'); // 1337
+
+ await driver.switchToWindowWithTitle(
+ WINDOW_TITLES.ExtensionInFullScreenView,
+ );
+
+ // Network Selector
+ await driver.clickElement('[data-testid="network-display"]');
+
+ // Switch network
+ await driver.clickElement({
+ text: 'Localhost 8546',
+ css: 'p',
+ });
+
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
+
+ const chainIdAfterManualSwitch = await driver.executeScript(
+ `return window.ethereum.request(${chainIdRequest})`,
+ );
+ assert.equal(chainIdAfterManualSwitch, '0x539');
+ },
+ );
+ });
+});
diff --git a/test/e2e/tests/dapp-interactions/dapp-interactions.spec.js b/test/e2e/tests/dapp-interactions/dapp-interactions.spec.js
index bd2b4a6b1aef..b992925ffc7a 100644
--- a/test/e2e/tests/dapp-interactions/dapp-interactions.spec.js
+++ b/test/e2e/tests/dapp-interactions/dapp-interactions.spec.js
@@ -65,8 +65,7 @@ describe('Dapp interactions', function () {
navigate: false,
});
- await driver.clickElement({ text: 'Next', tag: 'button' });
- await driver.clickElement({ text: 'Confirm', tag: 'button' });
+ await driver.clickElement({ text: 'Connect', tag: 'button' });
await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
await driver.waitForSelector({
css: '#accounts',
diff --git a/test/e2e/tests/dapp-interactions/permissions.spec.js b/test/e2e/tests/dapp-interactions/permissions.spec.js
index 029a0a0661bc..adf3b809a656 100644
--- a/test/e2e/tests/dapp-interactions/permissions.spec.js
+++ b/test/e2e/tests/dapp-interactions/permissions.spec.js
@@ -36,11 +36,7 @@ describe('Permissions', function () {
windowHandles,
);
await driver.clickElement({
- text: 'Next',
- tag: 'button',
- });
- await driver.clickElement({
- text: 'Confirm',
+ text: 'Connect',
tag: 'button',
});
diff --git a/test/e2e/tests/metrics/dapp-viewed.spec.js b/test/e2e/tests/metrics/dapp-viewed.spec.js
index 78214685777e..668f93e65dc5 100644
--- a/test/e2e/tests/metrics/dapp-viewed.spec.js
+++ b/test/e2e/tests/metrics/dapp-viewed.spec.js
@@ -69,22 +69,6 @@ async function mockPermissionApprovedEndpoint(mockServer) {
});
}
-async function createTwoAccounts(driver) {
- await driver.clickElement('[data-testid="account-menu-icon"]');
- await driver.clickElement(
- '[data-testid="multichain-account-menu-popover-action-button"]',
- );
- await driver.clickElement(
- '[data-testid="multichain-account-menu-popover-add-account"]',
- );
- await driver.fill('[placeholder="Account 2"]', '2nd account');
- await driver.clickElement({ text: 'Add account', tag: 'button' });
- await driver.findElement({
- css: '[data-testid="account-menu-icon"]',
- text: '2nd account',
- });
-}
-
const waitForDappConnected = async (driver) => {
await driver.waitForSelector({
css: '#accounts',
@@ -273,57 +257,6 @@ describe('Dapp viewed Event @no-mmi', function () {
);
});
- it('is sent when connecting dapp with two accounts', async function () {
- async function mockSegment(mockServer) {
- return [await mockedDappViewedEndpointFirstVisit(mockServer)];
- }
- await withFixtures(
- {
- dapp: true,
- fixtures: new FixtureBuilder()
- .withMetaMetricsController({
- metaMetricsId: validFakeMetricsId,
- participateInMetaMetrics: true,
- })
- .build(),
- title: this.test.fullTitle(),
- ganacheOptions: defaultGanacheOptions,
- testSpecificMock: mockSegment,
- },
- async ({ driver, mockedEndpoint: mockedEndpoints, ganacheServer }) => {
- await logInWithBalanceValidation(driver, ganacheServer);
- // create 2nd account
- await createTwoAccounts(driver);
- // Connect to dapp with two accounts
- await openDapp(driver);
- await driver.clickElement({
- text: 'Connect',
- tag: 'button',
- });
- await driver.waitUntilXWindowHandles(3);
- await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.clickElement(
- '[data-testid="choose-account-list-operate-all-check-box"]',
- );
-
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- });
- await driver.clickElement({
- text: 'Confirm',
- tag: 'button',
- });
-
- const events = await getEventPayloads(driver, mockedEndpoints);
- const dappViewedEventProperties = events[0].properties;
- assert.equal(dappViewedEventProperties.is_first_visit, true);
- assert.equal(dappViewedEventProperties.number_of_accounts, 2);
- assert.equal(dappViewedEventProperties.number_of_accounts_connected, 2);
- },
- );
- });
-
it('is sent when reconnect to a dapp that has been connected before', async function () {
async function mockSegment(mockServer) {
return [
@@ -372,28 +305,20 @@ describe('Dapp viewed Event @no-mmi', function () {
text: '127.0.0.1:8080',
tag: 'p',
});
- await driver.clickElement(
- '[data-testid ="account-list-item-menu-button"]',
- );
await driver.clickElement({
text: 'Disconnect',
tag: 'button',
});
await driver.clickElement('[data-testid ="disconnect-all"]');
- await driver.clickElement('button[aria-label="Back"]');
- await driver.clickElement('button[aria-label="Back"]');
// validate dapp is not connected
- await driver.clickElement(
- '[data-testid ="account-options-menu-button"]',
- );
- await driver.clickElement({
- text: 'All Permissions',
- tag: 'div',
- });
- await driver.findElement({
- text: 'Nothing to see here',
+ const noAccountConnected = await driver.isElementPresent({
+ text: 'MetaMask isn’t connected to this site',
tag: 'p',
});
+ assert.ok(
+ noAccountConnected,
+ 'Account disconected from connections page',
+ );
// reconnect again
await connectToDapp(driver);
const events = await getEventPayloads(driver, mockedEndpoints);
diff --git a/test/e2e/tests/multichain/connection-page.spec.js b/test/e2e/tests/multichain/connection-page.spec.js
deleted file mode 100644
index 122a83e718fa..000000000000
--- a/test/e2e/tests/multichain/connection-page.spec.js
+++ /dev/null
@@ -1,219 +0,0 @@
-const { strict: assert } = require('assert');
-const {
- withFixtures,
- WINDOW_TITLES,
- connectToDapp,
- logInWithBalanceValidation,
- locateAccountBalanceDOM,
- defaultGanacheOptions,
-} = require('../../helpers');
-const FixtureBuilder = require('../../fixture-builder');
-
-const accountLabel2 = '2nd custom name';
-const accountLabel3 = '3rd custom name';
-
-describe('Connections page', function () {
- it('should disconnect when click on Disconnect button in connections page', async function () {
- await withFixtures(
- {
- dapp: true,
- fixtures: new FixtureBuilder().build(),
- title: this.test.fullTitle(),
- ganacheOptions: defaultGanacheOptions,
- },
- async ({ driver, ganacheServer }) => {
- await logInWithBalanceValidation(driver, ganacheServer);
- await connectToDapp(driver);
-
- // It should render connected status for button if dapp is connected
- const getConnectedStatus = await driver.waitForSelector({
- css: '#connectButton',
- text: 'Connected',
- });
- assert.ok(getConnectedStatus, 'Account is connected to Dapp');
-
- // Switch to extension Tab
- await driver.switchToWindowWithTitle(
- WINDOW_TITLES.ExtensionInFullScreenView,
- );
- await driver.clickElement(
- '[data-testid ="account-options-menu-button"]',
- );
- await driver.clickElement({ text: 'All Permissions', tag: 'div' });
- await driver.clickElementAndWaitToDisappear({
- text: 'Got it',
- tag: 'button',
- });
- await driver.clickElement({
- text: '127.0.0.1:8080',
- tag: 'p',
- });
- await driver.clickElement('[data-testid ="connections-page"]');
- const connectionsPage = await driver.isElementPresent({
- text: '127.0.0.1:8080',
- tag: 'span',
- });
- assert.ok(connectionsPage, 'Connections Page is defined');
- await driver.clickElement(
- '[data-testid ="account-list-item-menu-button"]',
- );
- await driver.clickElement({ text: 'Disconnect', tag: 'button' });
- await driver.clickElement('[data-testid ="disconnect-all"]');
- await driver.clickElement('button[aria-label="Back"]');
- await driver.clickElement('button[aria-label="Back"]');
- // validate dapp is not connected
- await driver.clickElement(
- '[data-testid ="account-options-menu-button"]',
- );
- await driver.clickElement({ text: 'All Permissions', tag: 'div' });
- const noAccountConnected = await driver.isElementPresent({
- text: 'Nothing to see here',
- tag: 'p',
- });
- assert.ok(
- noAccountConnected,
- 'Account disconected from connections page',
- );
-
- // Switch back to Dapp
- await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
-
- // Button should show Connect text if dapp is not connected
-
- const getConnectStatus = await driver.waitForSelector({
- css: '#connectButton',
- text: 'Connect',
- });
-
- assert.ok(
- getConnectStatus,
- 'Account is not connected to Dapp and button has text connect',
- );
- },
- );
- });
-
- it('should connect more accounts when already connected to a dapp', async function () {
- await withFixtures(
- {
- dapp: true,
- fixtures: new FixtureBuilder().build(),
- title: this.test.fullTitle(),
- ganacheOptions: defaultGanacheOptions,
- },
- async ({ driver, ganacheServer }) => {
- await logInWithBalanceValidation(driver, ganacheServer);
- await connectToDapp(driver);
-
- const account = await driver.findElement('#accounts');
- const accountAddress = await account.getText();
-
- // Dapp should contain single connected account address
- assert.strictEqual(
- accountAddress,
- '0x5cfe73b6021e818b776b421b1c4db2474086a7e1',
- );
- // disconnect dapp in fullscreen view
- await driver.switchToWindowWithTitle(
- WINDOW_TITLES.ExtensionInFullScreenView,
- );
-
- // Add two new accounts with custom label
- await driver.clickElement('[data-testid="account-menu-icon"]');
- await driver.clickElement(
- '[data-testid="multichain-account-menu-popover-action-button"]',
- );
- await driver.clickElement(
- '[data-testid="multichain-account-menu-popover-add-account"]',
- );
- await driver.fill('[placeholder="Account 2"]', accountLabel2);
- await driver.clickElement({ text: 'Add account', tag: 'button' });
- await driver.clickElement('[data-testid="account-menu-icon"]');
- await driver.clickElement(
- '[data-testid="multichain-account-menu-popover-action-button"]',
- );
- await driver.clickElement(
- '[data-testid="multichain-account-menu-popover-add-account"]',
- );
- await driver.fill('[placeholder="Account 3"]', accountLabel3);
- await driver.clickElement({ text: 'Add account', tag: 'button' });
- await locateAccountBalanceDOM(driver);
- await driver.clickElement(
- '[data-testid ="account-options-menu-button"]',
- );
- await driver.clickElement({ text: 'All Permissions', tag: 'div' });
- await driver.clickElementAndWaitToDisappear({
- text: 'Got it',
- tag: 'button',
- });
- await driver.clickElement({
- text: '127.0.0.1:8080',
- tag: 'p',
- });
-
- // Connect only second account and keep third account unconnected
- await driver.clickElement({
- text: 'Connect more accounts',
- tag: 'button',
- });
- await driver.clickElement({
- text: '2nd custom name',
- tag: 'button',
- });
- await driver.clickElement(
- '[data-testid ="connect-more-accounts-button"]',
- );
- const newAccountConnected = await driver.isElementPresent({
- text: '2nd custom name',
- tag: 'button',
- });
-
- assert.ok(newAccountConnected, 'Connected More Account Successfully');
- // Switch back to Dapp
- await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
- // Find the span element that contains the account addresses
- const accounts = await driver.findElement('#accounts');
- const accountAddresses = await accounts.getText();
-
- // Dapp should contain both the connected account addresses
- assert.strictEqual(
- accountAddresses,
- '0x09781764c08de8ca82e156bbf156a3ca217c7950,0x5cfe73b6021e818b776b421b1c4db2474086a7e1',
- );
- },
- );
- });
-
- // Skipped until issue where firefox connecting to dapp is resolved.
- // it('shows that the account is connected to the dapp', async function () {
- // await withFixtures(
- // {
- // dapp: true,
- // fixtures: new FixtureBuilder().build(),
- // title: this.test.fullTitle(),
- // ganacheOptions: defaultGanacheOptions,
- // },
- // async ({ driver, ganacheServer }) => {
- // const ACCOUNT = '0x5CfE73b6021E818B776b421B1c4Db2474086a7e1';
- // const SHORTENED_ACCOUNT = shortenAddress(ACCOUNT);
- // await logInWithBalanceValidation(driver, ganacheServer);
- // await openDappConnectionsPage(driver);
- // // Verify that there are no connected accounts
- // await driver.assertElementNotPresent(
- // '[data-testid="account-list-address"]',
- // );
-
- // await connectToDapp(driver);
- // await openDappConnectionsPage(driver);
-
- // const account = await driver.findElement(
- // '[data-testid="account-list-address"]',
- // );
- // const accountAddress = await account.getText();
-
- // // Dapp should contain single connected account address
- // assert.strictEqual(accountAddress, SHORTENED_ACCOUNT);
- // },
- // );
- // });
-});
diff --git a/test/e2e/tests/network/add-custom-network.spec.js b/test/e2e/tests/network/add-custom-network.spec.js
index 70325cb5155b..dc8f38e1168c 100644
--- a/test/e2e/tests/network/add-custom-network.spec.js
+++ b/test/e2e/tests/network/add-custom-network.spec.js
@@ -369,13 +369,6 @@ describe('Custom network', function () {
tag: 'button',
text: 'Approve',
});
-
- const switchNetworkBtn = await driver.findElement({
- tag: 'button',
- text: 'Switch network',
- });
-
- await switchNetworkBtn.click();
},
);
});
diff --git a/test/e2e/tests/network/chain-interactions.spec.js b/test/e2e/tests/network/chain-interactions.spec.js
index ba774ffecdb1..5b831ab1ba54 100644
--- a/test/e2e/tests/network/chain-interactions.spec.js
+++ b/test/e2e/tests/network/chain-interactions.spec.js
@@ -1,4 +1,3 @@
-const { strict: assert } = require('assert');
const {
generateGanacheOptions,
withFixtures,
@@ -14,53 +13,6 @@ describe('Chain Interactions', function () {
const ganacheOptions = generateGanacheOptions({
concurrent: [{ port, chainId }],
});
- it('should add the Ganache test chain and not switch the network', async function () {
- await withFixtures(
- {
- dapp: true,
- fixtures: new FixtureBuilder().build(),
- ganacheOptions,
- title: this.test.fullTitle(),
- },
- async ({ driver }) => {
- await logInWithBalanceValidation(driver);
-
- // trigger add chain confirmation
- await openDapp(driver);
- await driver.clickElement('#addEthereumChain');
-
- await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
-
- // verify chain details
- const [networkName, networkUrl, chainIdElement] =
- await driver.findElements('.definition-list dd');
- assert.equal(await networkName.getText(), `Localhost ${port}`);
- assert.equal(await networkUrl.getText(), `http://127.0.0.1:${port}`);
- assert.equal(await chainIdElement.getText(), chainId.toString());
-
- // approve add chain, cancel switch chain
- await driver.clickElement({ text: 'Approve', tag: 'button' });
- await driver.clickElement({ text: 'Cancel', tag: 'button' });
-
- await driver.switchToWindowWithTitle(
- WINDOW_TITLES.ExtensionInFullScreenView,
- );
-
- // verify networks
- await driver.findElement({
- css: '[data-testid="network-display"]',
- text: 'Localhost 8545',
- });
-
- await driver.clickElement('[data-testid="network-display"]');
- const ganacheChain = await driver.findElements({
- text: `Localhost ${port}`,
- tag: 'p',
- });
- assert.ok(ganacheChain.length, 1);
- },
- );
- });
it('should add the Ganache chain and switch the network', async function () {
await withFixtures(
@@ -81,7 +33,6 @@ describe('Chain Interactions', function () {
// approve and switch chain
await driver.clickElement({ text: 'Approve', tag: 'button' });
- await driver.clickElement({ text: 'Switch network', tag: 'button' });
// switch to extension
await driver.switchToWindowWithTitle(
diff --git a/test/e2e/tests/network/deprecated-networks.spec.js b/test/e2e/tests/network/deprecated-networks.spec.js
index 29587f53afff..26c2388e4b51 100644
--- a/test/e2e/tests/network/deprecated-networks.spec.js
+++ b/test/e2e/tests/network/deprecated-networks.spec.js
@@ -92,13 +92,6 @@ describe('Deprecated networks', function () {
text: 'Approve',
});
- const switchNetworkBtn = await driver.findElement({
- tag: 'button',
- text: 'Switch network',
- });
-
- await switchNetworkBtn.click();
-
await driver.waitUntilXWindowHandles(2);
await driver.switchToWindow(extension);
const deprecationWarningText =
@@ -178,13 +171,6 @@ describe('Deprecated networks', function () {
text: 'Approve',
});
- const switchNetworkBtn = await driver.findElement({
- tag: 'button',
- text: 'Switch network',
- });
-
- await switchNetworkBtn.click();
-
await driver.waitUntilXWindowHandles(2);
await driver.switchToWindow(extension);
const deprecationWarningText =
@@ -264,13 +250,6 @@ describe('Deprecated networks', function () {
text: 'Approve',
});
- const switchNetworkBtn = await driver.findElement({
- tag: 'button',
- text: 'Switch network',
- });
-
- await switchNetworkBtn.click();
-
await driver.waitUntilXWindowHandles(2);
await driver.switchToWindow(extension);
const deprecationWarningText = 'This network is deprecated';
diff --git a/test/e2e/tests/network/switch-custom-network.spec.js b/test/e2e/tests/network/switch-custom-network.spec.js
index 694a8f309f01..09dedc3a62da 100644
--- a/test/e2e/tests/network/switch-custom-network.spec.js
+++ b/test/e2e/tests/network/switch-custom-network.spec.js
@@ -1,4 +1,3 @@
-const { strict: assert } = require('assert');
const FixtureBuilder = require('../../fixture-builder');
const {
withFixtures,
@@ -30,9 +29,6 @@ describe('Switch ethereum chain', function () {
async ({ driver }) => {
await unlockWallet(driver);
- const windowHandles = await driver.getAllWindowHandles();
- const extension = windowHandles[0];
-
await openDapp(driver);
await driver.clickElement({
@@ -40,62 +36,21 @@ describe('Switch ethereum chain', function () {
text: 'Add Localhost 8546',
});
- await driver.waitUntilXWindowHandles(3);
-
- await driver.switchToWindowWithTitle(
- WINDOW_TITLES.Dialog,
- windowHandles,
- );
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.clickElement({
+ await driver.clickElementAndWaitForWindowToClose({
tag: 'button',
text: 'Approve',
});
- await driver.findElement({
- tag: 'h3',
- text: 'Allow this site to switch the network?',
- });
-
- // Don't switch to network now, because we will click the 'Switch to Localhost 8546' button below
- await driver.clickElement({
- tag: 'button',
- text: 'Cancel',
- });
-
- await driver.waitUntilXWindowHandles(2);
-
- await driver.switchToWindowWithTitle('E2E Test Dapp', windowHandles);
- await driver.clickElement({
- tag: 'button',
- text: 'Switch to Localhost 8546',
- });
-
- await driver.waitUntilXWindowHandles(3);
-
await driver.switchToWindowWithTitle(
- WINDOW_TITLES.Dialog,
- windowHandles,
+ WINDOW_TITLES.ExtensionInFullScreenView,
);
- await driver.clickElement({
- tag: 'button',
- text: 'Switch network',
- });
-
- await driver.waitUntilXWindowHandles(2);
-
- await driver.switchToWindow(extension);
-
- const currentNetworkName = await driver.findElement({
- tag: 'span',
+ await driver.findElement({
+ css: '[data-testid="network-display"]',
text: 'Localhost 8546',
});
-
- assert.ok(
- Boolean(currentNetworkName),
- 'Failed to switch to custom network',
- );
},
);
});
diff --git a/test/e2e/tests/request-queuing/batch-txs-per-dapp-diff-network.spec.js b/test/e2e/tests/request-queuing/batch-txs-per-dapp-diff-network.spec.js
index c2a86226d0c4..deb189404fa8 100644
--- a/test/e2e/tests/request-queuing/batch-txs-per-dapp-diff-network.spec.js
+++ b/test/e2e/tests/request-queuing/batch-txs-per-dapp-diff-network.spec.js
@@ -6,11 +6,9 @@ const {
unlockWallet,
DAPP_URL,
DAPP_ONE_URL,
- regularDelayMs,
WINDOW_TITLES,
defaultGanacheOptions,
largeDelayMs,
- switchToNotificationWindow,
} = require('../../helpers');
const { PAGES } = require('../../webdriver/driver');
@@ -49,23 +47,13 @@ describe('Request Queuing for Multiple Dapps and Txs on different networks', fun
await openDapp(driver, undefined, DAPP_URL);
// Connect to dapp 1
- await driver.findClickableElement({ text: 'Connect', tag: 'button' });
- await driver.clickElement('#connectButton');
+ await driver.clickElement({ text: 'Connect', tag: 'button' });
- await driver.delay(regularDelayMs);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await switchToNotificationWindow(driver);
-
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
-
- await driver.clickElement({
- text: 'Confirm',
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
await driver.switchToWindowWithTitle(
@@ -89,23 +77,13 @@ describe('Request Queuing for Multiple Dapps and Txs on different networks', fun
await openDapp(driver, undefined, DAPP_ONE_URL);
// Connect to dapp 2
- await driver.findClickableElement({ text: 'Connect', tag: 'button' });
- await driver.clickElement('#connectButton');
-
- await driver.delay(regularDelayMs);
+ await driver.clickElement({ text: 'Connect', tag: 'button' });
- await switchToNotificationWindow(driver, 4);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.clickElement({
- text: 'Next',
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
-
- await driver.clickElement({
- text: 'Confirm',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
// Dapp one send tx
@@ -122,30 +100,29 @@ describe('Request Queuing for Multiple Dapps and Txs on different networks', fun
await driver.clickElement('#sendButton');
await driver.clickElement('#sendButton');
- await switchToNotificationWindow(driver, 4);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.findElement(
+ await driver.waitForSelector(
By.xpath("//div[normalize-space(.)='1 of 2']"),
);
- // Check correct network on confirm tx.
- await driver.findElement({
- css: '[data-testid="network-display"]',
- text: 'Localhost 8545',
- });
-
// Reject All Transactions
await driver.clickElement('.page-container__footer-secondary a');
- await driver.clickElement({ text: 'Reject all', tag: 'button' }); // TODO: Do we want to confirm here?
+ // TODO: Do we want to confirm here?
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Reject all',
+ tag: 'button',
+ });
// Wait for confirmation to close
- await driver.waitUntilXWindowHandles(3);
+ // TODO: find a better way to handle different dialog ids
+ await driver.delay(2000);
// Wait for new confirmations queued from second dapp to open
- await switchToNotificationWindow(driver, 4);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.findElement(
+ await driver.waitForSelector(
By.xpath("//div[normalize-space(.)='1 of 2']"),
);
diff --git a/test/e2e/tests/request-queuing/batch-txs-per-dapp-extra-tx.spec.js b/test/e2e/tests/request-queuing/batch-txs-per-dapp-extra-tx.spec.js
index 994afd5b4f31..265b28d0f56d 100644
--- a/test/e2e/tests/request-queuing/batch-txs-per-dapp-extra-tx.spec.js
+++ b/test/e2e/tests/request-queuing/batch-txs-per-dapp-extra-tx.spec.js
@@ -1,16 +1,14 @@
-const { strict: assert } = require('assert');
+const { By } = require('selenium-webdriver');
const FixtureBuilder = require('../../fixture-builder');
const {
- withFixtures,
- openDapp,
- unlockWallet,
- DAPP_URL,
DAPP_ONE_URL,
- regularDelayMs,
- WINDOW_TITLES,
+ DAPP_URL,
defaultGanacheOptions,
largeDelayMs,
- switchToNotificationWindow,
+ openDapp,
+ unlockWallet,
+ WINDOW_TITLES,
+ withFixtures,
} = require('../../helpers');
const { PAGES } = require('../../webdriver/driver');
@@ -52,39 +50,35 @@ describe('Request Queuing for Multiple Dapps and Txs on different networks', fun
await driver.findClickableElement({ text: 'Connect', tag: 'button' });
await driver.clickElement('#connectButton');
- await driver.delay(regularDelayMs);
-
- await switchToNotificationWindow(driver);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await driver.clickElement({
- text: 'Next',
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
- await driver.clickElement({
- text: 'Confirm',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
+ await driver.switchToWindowWithUrl(DAPP_URL);
+
+ const switchEthereumChainRequest = JSON.stringify({
+ jsonrpc: '2.0',
+ method: 'wallet_switchEthereumChain',
+ params: [{ chainId: '0x53a' }],
});
- await driver.switchToWindowWithTitle(
- WINDOW_TITLES.ExtensionInFullScreenView,
+ // Ensure Dapp One is on Localhost 8546
+ await driver.executeScript(
+ `window.ethereum.request(${switchEthereumChainRequest})`,
);
- // Network Selector
- await driver.clickElement('[data-testid="network-display"]');
+ // Should auto switch without prompt since already approved via connect
- // Switch to second network
- await driver.clickElement({
- text: 'Localhost 8546',
- css: 'p',
- });
+ await driver.switchToWindowWithTitle(
+ WINDOW_TITLES.ExtensionInFullScreenView,
+ );
// Wait for the first dapp's connect confirmation to disappear
await driver.waitUntilXWindowHandles(2);
- // TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them.
// Open Dapp Two
await openDapp(driver, undefined, DAPP_ONE_URL);
@@ -92,79 +86,71 @@ describe('Request Queuing for Multiple Dapps and Txs on different networks', fun
await driver.findClickableElement({ text: 'Connect', tag: 'button' });
await driver.clickElement('#connectButton');
- await driver.delay(regularDelayMs);
-
- await switchToNotificationWindow(driver, 4);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await driver.clickElement({
- text: 'Next',
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
-
- await driver.clickElement({
- text: 'Confirm',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
// Dapp 1 send 2 tx
await driver.switchToWindowWithUrl(DAPP_URL);
- await driver.delay(largeDelayMs);
+ await driver.findElement({
+ css: '[id="chainId"]',
+ text: '0x53a',
+ });
await driver.clickElement('#sendButton');
await driver.clickElement('#sendButton');
- await driver.delay(largeDelayMs);
+ await driver.waitUntilXWindowHandles(4);
// Dapp 2 send 2 tx
await driver.switchToWindowWithUrl(DAPP_ONE_URL);
- await driver.delay(largeDelayMs);
+ await driver.findElement({
+ css: '[id="chainId"]',
+ text: '0x53a',
+ });
await driver.clickElement('#sendButton');
await driver.clickElement('#sendButton');
-
+ // We cannot wait for the dialog, since it is already opened from before
await driver.delay(largeDelayMs);
- // Dapp 1 send 1 tx
+ // Dapp 1 send 1 tx
await driver.switchToWindowWithUrl(DAPP_URL);
- await driver.delay(largeDelayMs);
+ await driver.findElement({
+ css: '[id="chainId"]',
+ text: '0x53a',
+ });
await driver.clickElement('#sendButton');
+ // We cannot switch directly, as the dialog is sometimes closed and re-opened
+ await driver.delay(largeDelayMs);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await switchToNotificationWindow(driver, 4);
-
- let navigationElement = await driver.findElement(
- '.confirm-page-container-navigation',
+ await driver.waitForSelector(
+ By.xpath("//div[normalize-space(.)='1 of 2']"),
);
- let navigationText = await navigationElement.getText();
-
- assert.equal(navigationText.includes('1 of 2'), true);
-
- // Check correct network on confirm tx.
- await driver.findElement({
- css: '[data-testid="network-display"]',
- text: 'Localhost 8545',
- });
-
// Reject All Transactions
await driver.clickElement('.page-container__footer-secondary a');
- await driver.clickElement({ text: 'Reject all', tag: 'button' }); // TODO: Do we want to confirm here?
+ // TODO: Do we want to confirm here?
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Reject all',
+ tag: 'button',
+ });
- // Wait for confirmations to close and transactions from the second dapp to open
- // Large delays to wait for confirmation spam opening/closing bug.
- await driver.delay(5000);
+ await driver.switchToWindowWithUrl(DAPP_URL);
// Wait for new confirmations queued from second dapp to open
- await switchToNotificationWindow(driver, 4);
+ // We need a big delay to make sure dialog is not invalidated
+ // TODO: find a better way to handle different dialog ids
+ await driver.delay(2000);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- navigationElement = await driver.findElement(
- '.confirm-page-container-navigation',
+ await driver.waitForSelector(
+ By.xpath("//div[normalize-space(.)='1 of 2']"),
);
- navigationText = await navigationElement.getText();
-
- assert.equal(navigationText.includes('1 of 2'), true);
-
// Check correct network on confirm tx.
await driver.findElement({
css: '[data-testid="network-display"]',
@@ -174,19 +160,17 @@ describe('Request Queuing for Multiple Dapps and Txs on different networks', fun
// Reject All Transactions
await driver.clickElement('.page-container__footer-secondary a');
- await driver.clickElement({ text: 'Reject all', tag: 'button' });
-
- // Wait for confirmation to close
- await driver.waitUntilXWindowHandles(3);
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Reject all',
+ tag: 'button',
+ });
// Wait for new confirmations queued from second dapp to open
- await switchToNotificationWindow(driver, 4);
-
- // Check correct network on confirm tx.
- await driver.findElement({
- css: '[data-testid="network-display"]',
- text: 'Localhost 8545',
- });
+ // We need a big delay to make sure dialog is not invalidated
+ // TODO: find a better way to handle different dialog ids
+ await driver.delay(2000);
+ await driver.switchToWindowWithUrl(DAPP_URL);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
},
);
});
diff --git a/test/e2e/tests/request-queuing/batch-txs-per-dapp-same-network.spec.js b/test/e2e/tests/request-queuing/batch-txs-per-dapp-same-network.spec.js
index d2d7cdf122c0..bd52558ec67f 100644
--- a/test/e2e/tests/request-queuing/batch-txs-per-dapp-same-network.spec.js
+++ b/test/e2e/tests/request-queuing/batch-txs-per-dapp-same-network.spec.js
@@ -22,10 +22,10 @@ describe('Request Queuing for Multiple Dapps and Txs on same networks', function
{
dapp: true,
fixtures: new FixtureBuilder()
- .withNetworkControllerDoubleGanache()
+ .withNetworkControllerTripleGanache()
.withPreferencesControllerUseRequestQueueEnabled()
.build(),
- dappOptions: { numberOfDapps: 2 },
+ dappOptions: { numberOfDapps: 3 },
ganacheOptions: {
...defaultGanacheOptions,
concurrent: [
@@ -34,6 +34,11 @@ describe('Request Queuing for Multiple Dapps and Txs on same networks', function
chainId,
ganacheOptions2: defaultGanacheOptions,
},
+ {
+ port: 7777,
+ chainId: 1000,
+ ganacheOptions2: defaultGanacheOptions,
+ },
],
},
title: this.test.fullTitle(),
@@ -57,17 +62,25 @@ describe('Request Queuing for Multiple Dapps and Txs on same networks', function
await switchToNotificationWindow(driver);
await driver.clickElement({
- text: 'Next',
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
- await driver.clickElement({
- text: 'Confirm',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
+ await driver.switchToWindowWithUrl(DAPP_URL);
+
+ let switchEthereumChainRequest = JSON.stringify({
+ jsonrpc: '2.0',
+ method: 'wallet_switchEthereumChain',
+ params: [{ chainId: '0x3e8' }],
});
+ // Ensure Dapp One is on Localhost 7777
+ await driver.executeScript(
+ `window.ethereum.request(${switchEthereumChainRequest})`,
+ );
+
+ // Should auto switch without prompt since already approved via connect
+
await driver.switchToWindowWithTitle(
WINDOW_TITLES.ExtensionInFullScreenView,
);
@@ -88,18 +101,26 @@ describe('Request Queuing for Multiple Dapps and Txs on same networks', function
await switchToNotificationWindow(driver, 4);
await driver.clickElement({
- text: 'Next',
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
- await driver.clickElement({
- text: 'Confirm',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
+ await driver.switchToWindowWithUrl(DAPP_ONE_URL);
+
+ switchEthereumChainRequest = JSON.stringify({
+ jsonrpc: '2.0',
+ method: 'wallet_switchEthereumChain',
+ params: [{ chainId: '0x53a' }],
});
- // Dapp one send tx
+ // Ensure Dapp Two is on Localhost 8545
+ await driver.executeScript(
+ `window.ethereum.request(${switchEthereumChainRequest})`,
+ );
+
+ // Should auto switch without prompt since already approved via connect
+
+ // Dapp one send two tx
await driver.switchToWindowWithUrl(DAPP_URL);
await driver.delay(largeDelayMs);
await driver.clickElement('#sendButton');
@@ -107,7 +128,7 @@ describe('Request Queuing for Multiple Dapps and Txs on same networks', function
await driver.delay(largeDelayMs);
- // Dapp two send tx
+ // Dapp two send two tx
await driver.switchToWindowWithUrl(DAPP_ONE_URL);
await driver.delay(largeDelayMs);
await driver.clickElement('#sendButton');
@@ -126,7 +147,7 @@ describe('Request Queuing for Multiple Dapps and Txs on same networks', function
// Check correct network on confirm tx.
await driver.findElement({
css: '[data-testid="network-display"]',
- text: 'Localhost 8545',
+ text: 'Localhost 7777',
});
// Reject All Transactions
@@ -135,10 +156,11 @@ describe('Request Queuing for Multiple Dapps and Txs on same networks', function
await driver.clickElement({ text: 'Reject all', tag: 'button' }); // TODO: Do we want to confirm here?
// Wait for confirmation to close
- await driver.waitUntilXWindowHandles(3);
+ await driver.waitUntilXWindowHandles(4);
// Wait for new confirmations queued from second dapp to open
- await switchToNotificationWindow(driver, 4);
+ await driver.delay(largeDelayMs);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
navigationElement = await driver.findElement(
'.confirm-page-container-navigation',
@@ -151,7 +173,7 @@ describe('Request Queuing for Multiple Dapps and Txs on same networks', function
// Check correct network on confirm tx.
await driver.findElement({
css: '[data-testid="network-display"]',
- text: 'Localhost 8545',
+ text: 'Localhost 8546',
});
},
);
diff --git a/test/e2e/tests/request-queuing/chainid-check.spec.js b/test/e2e/tests/request-queuing/chainid-check.spec.js
index 850051d39c6a..1579a8ae5aa4 100644
--- a/test/e2e/tests/request-queuing/chainid-check.spec.js
+++ b/test/e2e/tests/request-queuing/chainid-check.spec.js
@@ -90,15 +90,8 @@ describe('Request Queueing chainId proxy sync', function () {
await switchToNotificationWindow(driver);
await driver.clickElement({
- text: 'Next',
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
-
- await driver.clickElement({
- text: 'Confirm',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
@@ -122,11 +115,11 @@ describe('Request Queueing chainId proxy sync', function () {
await switchToNotificationWindow(driver);
await driver.findClickableElements({
- text: 'Switch network',
+ text: 'Confirm',
tag: 'button',
});
- await driver.clickElement({ text: 'Switch network', tag: 'button' });
+ await driver.clickElement({ text: 'Confirm', tag: 'button' });
await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
@@ -240,23 +233,13 @@ describe('Request Queueing chainId proxy sync', function () {
assert.equal(chainIdBeforeConnectAfterManualSwitch, '0x1');
// Connect to dapp
- await driver.findClickableElement({ text: 'Connect', tag: 'button' });
- await driver.clickElement('#connectButton');
-
- await driver.delay(regularDelayMs);
-
- await switchToNotificationWindow(driver);
+ await driver.clickElement({ text: 'Connect', tag: 'button' });
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.clickElement({
- text: 'Confirm',
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
@@ -267,6 +250,10 @@ describe('Request Queueing chainId proxy sync', function () {
// should still be on the same chainId as the wallet after connecting
assert.equal(chainIdAfterConnect, '0x1');
+ await driver.waitForSelector({
+ css: '[id="chainId"]',
+ text: '0x1',
+ });
const switchEthereumChainRequest = JSON.stringify({
jsonrpc: '2.0',
@@ -278,14 +265,13 @@ describe('Request Queueing chainId proxy sync', function () {
`window.ethereum.request(${switchEthereumChainRequest})`,
);
- await switchToNotificationWindow(driver);
- await driver.findClickableElements({
- text: 'Switch network',
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Confirm',
tag: 'button',
});
- await driver.clickElement({ text: 'Switch network', tag: 'button' });
-
await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
const chainIdAfterDappSwitch = await driver.executeScript(
@@ -295,6 +281,10 @@ describe('Request Queueing chainId proxy sync', function () {
// should be on the new chainId that was requested
assert.equal(chainIdAfterDappSwitch, '0x539'); // 1337
+ await driver.waitForSelector({
+ css: '[id="chainId"]',
+ text: '0x539',
+ });
await driver.switchToWindowWithTitle(
WINDOW_TITLES.ExtensionInFullScreenView,
);
diff --git a/test/e2e/tests/request-queuing/dapp1-send-dapp2-signTypedData.spec.js b/test/e2e/tests/request-queuing/dapp1-send-dapp2-signTypedData.spec.js
index 8f6bf4c616d0..d52d45701563 100644
--- a/test/e2e/tests/request-queuing/dapp1-send-dapp2-signTypedData.spec.js
+++ b/test/e2e/tests/request-queuing/dapp1-send-dapp2-signTypedData.spec.js
@@ -45,10 +45,9 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () {
await unlockWallet(driver);
await tempToggleSettingRedesignedConfirmations(driver);
- // Open Dapp One
+ // Open and connect Dapp One
await openDapp(driver, undefined, DAPP_URL);
- // Connect to dapp
await driver.findClickableElement({ text: 'Connect', tag: 'button' });
await driver.clickElement('#connectButton');
@@ -57,25 +56,14 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () {
await driver.waitUntilXWindowHandles(3);
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.clickElement({
- text: 'Next',
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
-
- await driver.clickElement({
- text: 'Confirm',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
-
- await driver.waitUntilXWindowHandles(2);
await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
-
- // Open Dapp Two
+ // Open and connect to Dapp Two
await openDapp(driver, undefined, DAPP_ONE_URL);
- // Connect to dapp 2
await driver.findClickableElement({ text: 'Connect', tag: 'button' });
await driver.clickElement('#connectButton');
@@ -85,21 +73,35 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () {
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await driver.clickElement({
- text: 'Next',
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
- await driver.clickElement({
- text: 'Confirm',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
+ // Switch Dapp Two to Localhost 8546
+ await driver.switchToWindowWithUrl(DAPP_ONE_URL);
+ let switchEthereumChainRequest = JSON.stringify({
+ jsonrpc: '2.0',
+ method: 'wallet_switchEthereumChain',
+ params: [{ chainId: '0x53a' }],
});
+ // Initiate switchEthereumChain on Dapp one
+ await driver.executeScript(
+ `window.ethereum.request(${switchEthereumChainRequest})`,
+ );
+
+ await driver.findElement({
+ css: '[id="chainId"]',
+ text: '0x53a',
+ });
+
+ // Should auto switch without prompt since already approved via connect
+
+ // Switch back to Dapp One
await driver.switchToWindowWithUrl(DAPP_URL);
// switch chain for Dapp One
- const switchEthereumChainRequest = JSON.stringify({
+ switchEthereumChainRequest = JSON.stringify({
jsonrpc: '2.0',
method: 'wallet_switchEthereumChain',
params: [{ chainId: '0x3e8' }],
@@ -109,11 +111,11 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () {
await driver.executeScript(
`window.ethereum.request(${switchEthereumChainRequest})`,
);
-
- await driver.waitUntilXWindowHandles(4);
- await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
-
- await driver.clickElement({ text: 'Switch network', tag: 'button' });
+ await driver.findElement({
+ css: '[id="chainId"]',
+ text: '0x3e8',
+ });
+ // Should auto switch without prompt since already approved via connect
await driver.switchToWindowWithUrl(DAPP_URL);
@@ -143,7 +145,7 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () {
// Check correct network on the signTypedData confirmation.
await driver.findElement({
css: '[data-testid="signature-request-network-display"]',
- text: 'Localhost 8545',
+ text: 'Localhost 8546',
});
},
);
diff --git a/test/e2e/tests/request-queuing/dapp1-subscribe-network-switch.spec.js b/test/e2e/tests/request-queuing/dapp1-subscribe-network-switch.spec.js
index cbfb2b23a9a7..53c763d8891f 100644
--- a/test/e2e/tests/request-queuing/dapp1-subscribe-network-switch.spec.js
+++ b/test/e2e/tests/request-queuing/dapp1-subscribe-network-switch.spec.js
@@ -49,20 +49,10 @@ describe('Request Queueing', function () {
await switchToNotificationWindow(driver);
await driver.clickElement({
- text: 'Next',
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
- await driver.clickElement({
- text: 'Confirm',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
-
- // Wait for Connecting notification to close.
- await driver.waitUntilXWindowHandles(2);
-
// Navigate to test dapp
await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
diff --git a/test/e2e/tests/request-queuing/dapp1-switch-dapp2-eth-request-accounts.spec.js b/test/e2e/tests/request-queuing/dapp1-switch-dapp2-eth-request-accounts.spec.js
index a68884de4a4c..7a212533de4b 100644
--- a/test/e2e/tests/request-queuing/dapp1-switch-dapp2-eth-request-accounts.spec.js
+++ b/test/e2e/tests/request-queuing/dapp1-switch-dapp2-eth-request-accounts.spec.js
@@ -89,15 +89,8 @@ describe('Request Queuing Dapp 1 Send Tx -> Dapp 2 Request Accounts Tx', functio
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await driver.clickElement({
- text: 'Next',
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
-
- await driver.clickElement({
- text: 'Confirm',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
await driver.switchToWindowWithUrl(DAPP_ONE_URL);
diff --git a/test/e2e/tests/request-queuing/dapp1-switch-dapp2-send.spec.js b/test/e2e/tests/request-queuing/dapp1-switch-dapp2-send.spec.js
index 567ddf0f619d..c330596c48f3 100644
--- a/test/e2e/tests/request-queuing/dapp1-switch-dapp2-send.spec.js
+++ b/test/e2e/tests/request-queuing/dapp1-switch-dapp2-send.spec.js
@@ -51,16 +51,9 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () {
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
-
await driver.clickElementAndWaitForWindowToClose({
- text: 'Confirm',
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
await driver.switchToWindowWithTitle(
@@ -86,16 +79,9 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () {
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
-
await driver.clickElementAndWaitForWindowToClose({
- text: 'Confirm',
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
await driver.switchToWindowWithUrl(DAPP_URL);
@@ -104,7 +90,7 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () {
const switchEthereumChainRequest = JSON.stringify({
jsonrpc: '2.0',
method: 'wallet_switchEthereumChain',
- params: [{ chainId: '0x3e8' }],
+ params: [{ chainId: '0x539' }],
});
// Initiate switchEthereumChain on Dapp Two
@@ -114,8 +100,8 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () {
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await driver.findElement({
- text: 'Allow this site to switch the network?',
- tag: 'h3',
+ text: 'Use your enabled networks',
+ tag: 'p',
});
await driver.switchToWindowWithUrl(DAPP_ONE_URL);
@@ -124,7 +110,7 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () {
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.clickElement({ text: 'Switch network', tag: 'button' });
+ await driver.clickElement({ text: 'Confirm', tag: 'button' });
await driver.switchToWindowWithUrl(DAPP_ONE_URL);
@@ -207,16 +193,9 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () {
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
-
await driver.clickElementAndWaitForWindowToClose({
- text: 'Confirm',
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
await driver.switchToWindowWithTitle(
@@ -242,16 +221,9 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () {
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
-
await driver.clickElementAndWaitForWindowToClose({
- text: 'Confirm',
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
await driver.switchToWindowWithUrl(DAPP_URL);
@@ -260,7 +232,7 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () {
const switchEthereumChainRequest = JSON.stringify({
jsonrpc: '2.0',
method: 'wallet_switchEthereumChain',
- params: [{ chainId: '0x3e8' }],
+ params: [{ chainId: '0x539' }],
});
// Initiate switchEthereumChain on Dapp Two
@@ -270,8 +242,8 @@ describe('Request Queuing Dapp 1, Switch Tx -> Dapp 2 Send Tx', function () {
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await driver.findElement({
- text: 'Allow this site to switch the network?',
- tag: 'h3',
+ text: 'Use your enabled networks',
+ tag: 'p',
});
await driver.switchToWindowWithUrl(DAPP_ONE_URL);
diff --git a/test/e2e/tests/request-queuing/multi-dapp-sendTx-revokePermission.spec.js b/test/e2e/tests/request-queuing/multi-dapp-sendTx-revokePermission.spec.js
index 7821a005774d..d32e96e29571 100644
--- a/test/e2e/tests/request-queuing/multi-dapp-sendTx-revokePermission.spec.js
+++ b/test/e2e/tests/request-queuing/multi-dapp-sendTx-revokePermission.spec.js
@@ -5,11 +5,8 @@ const {
unlockWallet,
DAPP_URL,
DAPP_ONE_URL,
- regularDelayMs,
WINDOW_TITLES,
defaultGanacheOptions,
- largeDelayMs,
- switchToNotificationWindow,
} = require('../../helpers');
const { PAGES } = require('../../webdriver/driver');
@@ -48,23 +45,13 @@ describe('Request Queuing for Multiple Dapps and Txs on different networks revok
await openDapp(driver, undefined, DAPP_URL);
// Connect to dapp 1
- await driver.findClickableElement({ text: 'Connect', tag: 'button' });
- await driver.clickElement('#connectButton');
+ await driver.clickElement({ text: 'Connect', tag: 'button' });
- await driver.delay(regularDelayMs);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await switchToNotificationWindow(driver);
-
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
-
- await driver.clickElement({
- text: 'Confirm',
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
await driver.switchToWindowWithTitle(
@@ -88,28 +75,21 @@ describe('Request Queuing for Multiple Dapps and Txs on different networks revok
await openDapp(driver, undefined, DAPP_ONE_URL);
// Connect to dapp 2
- await driver.findClickableElement({ text: 'Connect', tag: 'button' });
- await driver.clickElement('#connectButton');
+ await driver.clickElement({ text: 'Connect', tag: 'button' });
- await driver.delay(regularDelayMs);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await switchToNotificationWindow(driver, 4);
-
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
-
- await driver.clickElement({
- text: 'Confirm',
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
// Dapp 1 send tx
await driver.switchToWindowWithUrl(DAPP_URL);
- await driver.delay(largeDelayMs);
+ await driver.findElement({
+ css: '[id="chainId"]',
+ text: '0x1',
+ });
await driver.clickElement('#sendButton');
await driver.waitUntilXWindowHandles(4);
@@ -117,18 +97,31 @@ describe('Request Queuing for Multiple Dapps and Txs on different networks revok
// Dapp 2 send tx
await driver.switchToWindowWithUrl(DAPP_ONE_URL);
- await driver.delay(largeDelayMs);
+ await driver.findElement({
+ css: '[id="chainId"]',
+ text: '0x53a',
+ });
await driver.clickElement('#sendButton');
+ await driver.waitUntilXWindowHandles(4);
// Dapp 1 revokePermissions
await driver.switchToWindowWithUrl(DAPP_URL);
- await driver.clickElement('#revokeAccountsPermission');
+ await driver.findElement({
+ css: '[id="chainId"]',
+ text: '0x1',
+ });
+ await driver.assertElementNotPresent({
+ css: '[id="chainId"]',
+ text: '0x53a',
+ });
// Confirmation will close then reopen
- await driver.waitUntilXWindowHandles(3);
+ await driver.clickElement('#revokeAccountsPermission');
+ // TODO: find a better way to handle different dialog ids
+ await driver.delay(3000);
// Check correct network on confirm tx.
- await switchToNotificationWindow(driver, 4);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await driver.findElement({
css: '[data-testid="network-display"]',
diff --git a/test/e2e/tests/request-queuing/multiple-networks-dapps-txs.spec.js b/test/e2e/tests/request-queuing/multiple-networks-dapps-txs.spec.js
index 6eb0b9d14f85..38fe1d7204d2 100644
--- a/test/e2e/tests/request-queuing/multiple-networks-dapps-txs.spec.js
+++ b/test/e2e/tests/request-queuing/multiple-networks-dapps-txs.spec.js
@@ -5,11 +5,9 @@ const {
unlockWallet,
DAPP_URL,
DAPP_ONE_URL,
- regularDelayMs,
WINDOW_TITLES,
defaultGanacheOptions,
largeDelayMs,
- switchToNotificationWindow,
} = require('../../helpers');
const { PAGES } = require('../../webdriver/driver');
@@ -48,23 +46,13 @@ describe('Request Queuing for Multiple Dapps and Txs on different networks.', fu
await openDapp(driver, undefined, DAPP_URL);
// Connect to dapp 1
- await driver.findClickableElement({ text: 'Connect', tag: 'button' });
- await driver.clickElement('#connectButton');
+ await driver.clickElement({ text: 'Connect', tag: 'button' });
- await driver.delay(regularDelayMs);
-
- await switchToNotificationWindow(driver);
-
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.clickElement({
- text: 'Confirm',
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
await driver.switchToWindowWithTitle(
@@ -80,31 +68,18 @@ describe('Request Queuing for Multiple Dapps and Txs on different networks.', fu
css: 'p',
});
- // Wait for the first dapp's connect confirmation to disappear
- await driver.waitUntilXWindowHandles(2);
-
// TODO: Request Queuing bug when opening both dapps at the same time will have them stuck on the same network, with will be incorrect for one of them.
// Open Dapp Two
await openDapp(driver, undefined, DAPP_ONE_URL);
// Connect to dapp 2
- await driver.findClickableElement({ text: 'Connect', tag: 'button' });
- await driver.clickElement('#connectButton');
-
- await driver.delay(regularDelayMs);
+ await driver.clickElement({ text: 'Connect', tag: 'button' });
- await switchToNotificationWindow(driver, 4);
-
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.clickElement({
- text: 'Confirm',
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
// Dapp one send tx
@@ -112,7 +87,7 @@ describe('Request Queuing for Multiple Dapps and Txs on different networks.', fu
await driver.delay(largeDelayMs);
await driver.clickElement('#sendButton');
- await driver.delay(largeDelayMs);
+ await driver.waitUntilXWindowHandles(4);
// Dapp two send tx
await driver.switchToWindowWithUrl(DAPP_ONE_URL);
@@ -128,14 +103,6 @@ describe('Request Queuing for Multiple Dapps and Txs on different networks.', fu
await driver.waitUntilXWindowHandles(4);
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.delay(largeDelayMs);
-
- // Find correct network on confirm tx
- await driver.findElement({
- text: 'Localhost 8545',
- tag: 'span',
- });
-
// Reject Transaction
await driver.findClickableElement({ text: 'Reject', tag: 'button' });
await driver.clickElement(
@@ -161,6 +128,11 @@ describe('Request Queuing for Multiple Dapps and Txs on different networks.', fu
// Click Unconfirmed Tx
await driver.clickElement('.transaction-list-item--unconfirmed');
+ await driver.assertElementNotPresent({
+ tag: 'p',
+ text: 'Network switched to Localhost 8546',
+ });
+
// Confirm Tx
await driver.clickElement('[data-testid="page-container-footer-next"]');
diff --git a/test/e2e/tests/request-queuing/switchChain-sendTx.spec.js b/test/e2e/tests/request-queuing/switchChain-sendTx.spec.js
index a86229e2cdb1..df33600413e1 100644
--- a/test/e2e/tests/request-queuing/switchChain-sendTx.spec.js
+++ b/test/e2e/tests/request-queuing/switchChain-sendTx.spec.js
@@ -3,9 +3,7 @@ const {
withFixtures,
openDapp,
unlockWallet,
- DAPP_URL,
WINDOW_TITLES,
- switchToNotificationWindow,
defaultGanacheOptions,
} = require('../../helpers');
@@ -18,7 +16,6 @@ describe('Request Queuing SwitchChain -> SendTx', function () {
dapp: true,
fixtures: new FixtureBuilder()
.withNetworkControllerDoubleGanache()
- .withPermissionControllerConnectedToTestDapp()
.withPreferencesControllerUseRequestQueueEnabled()
.build(),
ganacheOptions: {
@@ -37,14 +34,30 @@ describe('Request Queuing SwitchChain -> SendTx', function () {
async ({ driver }) => {
await unlockWallet(driver);
- await openDapp(driver, undefined, DAPP_URL);
+ await openDapp(driver);
+
+ await driver.findClickableElement({ text: 'Connect', tag: 'button' });
+ await driver.clickElement('#connectButton');
+
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
+ tag: 'button',
+ });
+
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
// Switch Ethereum Chain
- await driver.findClickableElement('#switchEthereumChain');
- await driver.clickElement('#switchEthereumChain');
+ const switchEthereumChainRequest = JSON.stringify({
+ jsonrpc: '2.0',
+ method: 'wallet_switchEthereumChain',
+ params: [{ chainId: '0x539' }],
+ });
- // Keep notification confirmation on screen
- await driver.waitUntilXWindowHandles(3);
+ await driver.executeScript(
+ `window.ethereum.request(${switchEthereumChainRequest})`,
+ );
// Navigate back to test dapp
await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
@@ -52,22 +65,23 @@ describe('Request Queuing SwitchChain -> SendTx', function () {
// Dapp Send Button
await driver.clickElement('#sendButton');
- await switchToNotificationWindow(driver, 3);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
// Persist Switch Ethereum Chain notifcation
await driver.findClickableElements({
- text: 'Switch network',
+ text: 'Confirm',
tag: 'button',
});
+ // THIS IS BROKEN
// Find the cancel pending txs on the Switch Ethereum Chain notification.
- await driver.findElement({
- text: 'Switching networks will cancel all pending confirmations',
- tag: 'span',
- });
+ // await driver.findElement({
+ // text: 'Switching networks will cancel all pending confirmations',
+ // tag: 'span',
+ // });
// Confirm Switch Network
- await driver.clickElement({ text: 'Switch network', tag: 'button' });
+ await driver.clickElement({ text: 'Confirm', tag: 'button' });
// No confirmations, tx should be cleared
await driver.waitUntilXWindowHandles(2);
diff --git a/test/e2e/tests/request-queuing/switchChain-watchAsset.spec.js b/test/e2e/tests/request-queuing/switchChain-watchAsset.spec.js
index b84b76868303..308a9c36914b 100644
--- a/test/e2e/tests/request-queuing/switchChain-watchAsset.spec.js
+++ b/test/e2e/tests/request-queuing/switchChain-watchAsset.spec.js
@@ -8,6 +8,7 @@ const {
withFixtures,
} = require('../../helpers');
const { SMART_CONTRACTS } = require('../../seeder/smart-contracts');
+const { DAPP_URL } = require('../../constants');
describe('Request Queue SwitchChain -> WatchAsset', function () {
const smartContract = SMART_CONTRACTS.HST;
@@ -20,7 +21,6 @@ describe('Request Queue SwitchChain -> WatchAsset', function () {
fixtures: new FixtureBuilder()
.withNetworkControllerDoubleGanache()
.withPreferencesControllerUseRequestQueueEnabled()
- .withPermissionControllerConnectedToTestDapp()
.build(),
ganacheOptions: {
...defaultGanacheOptions,
@@ -42,17 +42,35 @@ describe('Request Queue SwitchChain -> WatchAsset', function () {
);
await logInWithBalanceValidation(driver, ganacheServer);
- await openDapp(driver, contractAddress);
+ await openDapp(driver, contractAddress, DAPP_URL);
+
+ await driver.findClickableElement({ text: 'Connect', tag: 'button' });
+ await driver.clickElement('#connectButton');
+
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+
+ await driver.clickElementAndWaitForWindowToClose({
+ text: 'Connect',
+ tag: 'button',
+ });
+
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.TestDApp);
// Switch Ethereum Chain
- await driver.clickElement('#switchEthereumChain');
+ const switchEthereumChainRequest = JSON.stringify({
+ jsonrpc: '2.0',
+ method: 'wallet_switchEthereumChain',
+ params: [{ chainId: '0x539' }],
+ });
- await driver.waitUntilXWindowHandles(3);
+ await driver.executeScript(
+ `window.ethereum.request(${switchEthereumChainRequest})`,
+ );
- await switchToNotificationWindow(driver);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
await driver.findElement({
- text: 'Allow this site to switch the network?',
- tag: 'h3',
+ text: 'Use your enabled networks',
+ tag: 'p',
});
// Switch back to test dapp
@@ -68,10 +86,10 @@ describe('Request Queue SwitchChain -> WatchAsset', function () {
// Confirm Switch Network
await driver.findClickableElement({
- text: 'Switch network',
+ text: 'Confirm',
tag: 'button',
});
- await driver.clickElement({ text: 'Switch network', tag: 'button' });
+ await driver.clickElement({ text: 'Confirm', tag: 'button' });
await driver.waitUntilXWindowHandles(2);
},
diff --git a/test/e2e/tests/request-queuing/ui.spec.js b/test/e2e/tests/request-queuing/ui.spec.js
index 482b18e0e4f5..b857d4307d5b 100644
--- a/test/e2e/tests/request-queuing/ui.spec.js
+++ b/test/e2e/tests/request-queuing/ui.spec.js
@@ -1,5 +1,5 @@
const { strict: assert } = require('assert');
-const { Browser, until } = require('selenium-webdriver');
+const { Browser } = require('selenium-webdriver');
const { CHAIN_IDS } = require('../../../../shared/constants/network');
const FixtureBuilder = require('../../fixture-builder');
const {
@@ -16,6 +16,10 @@ const {
DAPP_TWO_URL,
} = require('../../helpers');
const { PAGES } = require('../../webdriver/driver');
+const {
+ PermissionNames,
+} = require('../../../../app/scripts/controllers/permissions');
+const { CaveatTypes } = require('../../../../shared/constants/permissions');
// Window handle adjustments will need to be made for Non-MV3 Firefox
// due to OffscreenDocument. Additionally Firefox continually bombs
@@ -29,21 +33,12 @@ async function openDappAndSwitchChain(driver, dappUrl, chainId) {
await openDapp(driver, undefined, dappUrl);
// Connect to the dapp
- await driver.findClickableElement({ text: 'Connect', tag: 'button' });
- await driver.clickElement('#connectButton');
- await driver.delay(regularDelayMs);
-
+ await driver.clickElement({ text: 'Connect', tag: 'button' });
await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.clickElement({
- text: 'Next',
- tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
- });
await driver.clickElementAndWaitForWindowToClose({
- text: 'Confirm',
+ text: 'Connect',
tag: 'button',
- css: '[data-testid="page-container-footer-next"]',
});
// Switch back to the dapp
@@ -52,6 +47,25 @@ async function openDappAndSwitchChain(driver, dappUrl, chainId) {
// Switch chains if necessary
if (chainId) {
await driver.delay(veryLargeDelayMs);
+ const getPermissionsRequest = JSON.stringify({
+ method: 'wallet_getPermissions',
+ });
+ const getPermissionsResult = await driver.executeScript(
+ `return window.ethereum.request(${getPermissionsRequest})`,
+ );
+
+ const permittedChains =
+ getPermissionsResult
+ ?.find(
+ (permission) =>
+ permission.parentCapability === PermissionNames.permittedChains,
+ )
+ ?.caveats.find(
+ (caveat) => caveat.type === CaveatTypes.restrictNetworkSwitching,
+ )?.value || [];
+
+ const isAlreadyPermitted = permittedChains.includes(chainId);
+
const switchChainRequest = JSON.stringify({
method: 'wallet_switchEthereumChain',
params: [{ chainId }],
@@ -61,18 +75,20 @@ async function openDappAndSwitchChain(driver, dappUrl, chainId) {
`window.ethereum.request(${switchChainRequest})`,
);
- await driver.delay(veryLargeDelayMs);
- await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
+ if (!isAlreadyPermitted) {
+ await driver.delay(veryLargeDelayMs);
+ await driver.switchToWindowWithTitle(WINDOW_TITLES.Dialog);
- await driver.findClickableElement(
- '[data-testid="confirmation-submit-button"]',
- );
- await driver.clickElementAndWaitForWindowToClose(
- '[data-testid="confirmation-submit-button"]',
- );
+ await driver.findClickableElement(
+ '[data-testid="page-container-footer-next"]',
+ );
+ await driver.clickElementAndWaitForWindowToClose(
+ '[data-testid="page-container-footer-next"]',
+ );
- // Switch back to the dapp
- await driver.switchToWindowWithUrl(dappUrl);
+ // Switch back to the dapp
+ await driver.switchToWindowWithUrl(dappUrl);
+ }
}
}
@@ -183,7 +199,6 @@ describe('Request-queue UI changes', function () {
fixtures: new FixtureBuilder()
.withNetworkControllerDoubleGanache()
.withPreferencesControllerUseRequestQueueEnabled()
- .withSelectedNetworkControllerPerDomain()
.build(),
ganacheOptions: {
...defaultGanacheOptions,
@@ -205,7 +220,7 @@ describe('Request-queue UI changes', function () {
await driver.navigate(PAGES.HOME);
// Open the first dapp
- await openDappAndSwitchChain(driver, DAPP_URL);
+ await openDappAndSwitchChain(driver, DAPP_URL, '0x539');
// Open the second dapp and switch chains
await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x53a');
@@ -249,7 +264,6 @@ describe('Request-queue UI changes', function () {
fixtures: new FixtureBuilder()
.withNetworkControllerTripleGanache()
.withPreferencesControllerUseRequestQueueEnabled()
- .withSelectedNetworkControllerPerDomain()
.build(),
ganacheOptions: {
...defaultGanacheOptions,
@@ -278,7 +292,7 @@ describe('Request-queue UI changes', function () {
await driver.navigate(PAGES.HOME);
// Open the first dapp
- await openDappAndSwitchChain(driver, DAPP_URL);
+ await openDappAndSwitchChain(driver, DAPP_URL, '0x539');
// Open the second dapp and switch chains
await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x53a');
@@ -377,7 +391,6 @@ describe('Request-queue UI changes', function () {
preferences: { showTestNetworks: true },
})
.withPreferencesControllerUseRequestQueueEnabled()
- .withSelectedNetworkControllerPerDomain()
.build(),
ganacheOptions: {
...defaultGanacheOptions,
@@ -399,7 +412,7 @@ describe('Request-queue UI changes', function () {
await driver.navigate(PAGES.HOME);
// Open the first dapp
- await openDappAndSwitchChain(driver, DAPP_URL);
+ await openDappAndSwitchChain(driver, DAPP_URL, '0x539');
// Open the second dapp and switch chains
await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1');
@@ -451,7 +464,6 @@ describe('Request-queue UI changes', function () {
dapp: true,
fixtures: new FixtureBuilder()
.withPreferencesControllerUseRequestQueueEnabled()
- .withSelectedNetworkControllerPerDomain()
.build(),
ganacheOptions: defaultGanacheOptions,
title: this.test.fullTitle(),
@@ -462,15 +474,13 @@ describe('Request-queue UI changes', function () {
await unlockWallet(driver);
// Open the first dapp which starts on chain '0x539
- await openDappAndSwitchChain(driver, DAPP_URL);
+ await openDappAndSwitchChain(driver, DAPP_URL, '0x539');
// Ensure the dapp starts on the correct network
- await driver.wait(
- until.elementTextContains(
- await driver.findElement('#chainId'),
- '0x539',
- ),
- );
+ await driver.waitForSelector({
+ css: '[id="chainId"]',
+ text: '0x539',
+ });
// Open the popup with shimmed activeTabOrigin
await openPopupWithActiveTabOrigin(driver, DAPP_URL);
@@ -482,12 +492,10 @@ describe('Request-queue UI changes', function () {
await driver.switchToWindowWithUrl(DAPP_URL);
// Check to make sure the dapp network changed
- await driver.wait(
- until.elementTextContains(
- await driver.findElement('#chainId'),
- '0x1',
- ),
- );
+ await driver.waitForSelector({
+ css: '[id="chainId"]',
+ text: '0x1',
+ });
},
);
});
@@ -501,7 +509,6 @@ describe('Request-queue UI changes', function () {
fixtures: new FixtureBuilder()
.withNetworkControllerDoubleGanache()
.withPreferencesControllerUseRequestQueueEnabled()
- .withSelectedNetworkControllerPerDomain()
.build(),
ganacheOptions: {
...defaultGanacheOptions,
@@ -521,7 +528,7 @@ describe('Request-queue UI changes', function () {
await unlockWallet(driver);
// Open the first dapp which starts on chain '0x539
- await openDappAndSwitchChain(driver, DAPP_URL);
+ await openDappAndSwitchChain(driver, DAPP_URL, '0x539');
// Open tab 2, switch to Ethereum Mainnet
await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1');
@@ -554,7 +561,6 @@ describe('Request-queue UI changes', function () {
fixtures: new FixtureBuilder()
.withNetworkControllerDoubleGanache()
.withPreferencesControllerUseRequestQueueEnabled()
- .withSelectedNetworkControllerPerDomain()
.build(),
ganacheOptions: {
...defaultGanacheOptions,
@@ -574,7 +580,7 @@ describe('Request-queue UI changes', function () {
await unlockWallet(driver);
// Open the first dapp which starts on chain '0x539
- await openDappAndSwitchChain(driver, DAPP_URL);
+ await openDappAndSwitchChain(driver, DAPP_URL, '0x539');
// Open tab 2, switch to Ethereum Mainnet
await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1');
@@ -626,7 +632,6 @@ describe('Request-queue UI changes', function () {
fixtures: new FixtureBuilder()
.withNetworkControllerDoubleGanache()
.withPreferencesControllerUseRequestQueueEnabled()
- .withSelectedNetworkControllerPerDomain()
.build(),
ganacheOptions: {
...defaultGanacheOptions,
@@ -652,7 +657,7 @@ describe('Request-queue UI changes', function () {
await driver.navigate(PAGES.HOME);
// Open the first dapp
- await openDappAndSwitchChain(driver, DAPP_URL);
+ await openDappAndSwitchChain(driver, DAPP_URL, '0x539');
// Open the second dapp and switch chains
await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1');
@@ -697,7 +702,6 @@ describe('Request-queue UI changes', function () {
fixtures: new FixtureBuilder()
.withNetworkControllerDoubleGanache()
.withPreferencesControllerUseRequestQueueEnabled()
- .withSelectedNetworkControllerPerDomain()
.build(),
ganacheOptions: {
...defaultGanacheOptions,
@@ -722,7 +726,7 @@ describe('Request-queue UI changes', function () {
await driver.navigate(PAGES.HOME);
// Open the first dapp
- await openDappAndSwitchChain(driver, DAPP_URL);
+ await openDappAndSwitchChain(driver, DAPP_URL, '0x539');
// Open the second dapp and switch chains
await openDappAndSwitchChain(driver, DAPP_ONE_URL, '0x1');
diff --git a/test/e2e/tests/request-queuing/watchAsset-switchChain-watchAsset.spec.js b/test/e2e/tests/request-queuing/watchAsset-switchChain-watchAsset.spec.js
index 3c183b5a50a7..1c1baa17fb5a 100644
--- a/test/e2e/tests/request-queuing/watchAsset-switchChain-watchAsset.spec.js
+++ b/test/e2e/tests/request-queuing/watchAsset-switchChain-watchAsset.spec.js
@@ -94,8 +94,6 @@ describe('Request Queue WatchAsset -> SwitchChain -> WatchAsset', function () {
await switchToNotificationWindow(driver);
- await driver.clickElement({ text: 'Switch network', tag: 'button' });
-
await driver.waitUntilXWindowHandles(2);
/**
diff --git a/ui/components/app/permission-cell/permission-cell-status.js b/ui/components/app/permission-cell/permission-cell-status.js
index 5b0cf8f25b56..7dcf32a3b2ee 100644
--- a/ui/components/app/permission-cell/permission-cell-status.js
+++ b/ui/components/app/permission-cell/permission-cell-status.js
@@ -49,7 +49,7 @@ export const PermissionCellStatus = ({
const renderAccountsGroup = () => (
<>
- {process.env.CHAIN_PERMISSIONS ? (
+ {networks.length > 0 ? (
- {process.env.CHAIN_PERMISSIONS
- ? t('reviewPermissions')
- : t('permissions')}
+ {t('reviewPermissions')}
- {process.env.CHAIN_PERMISSIONS
- ? t('nativeNetworkPermissionRequestDescription', [
-
- {getURLHost(subjectMetadata.origin)}
- ,
- ])
- : t('nativePermissionRequestDescription', [
-
- {subjectMetadata.origin}
- ,
- ])}
+ {t('nativeNetworkPermissionRequestDescription', [
+
+ {getURLHost(subjectMetadata.origin)}
+ ,
+ ])}
caveat.type === CaveatTypes.restrictNetworkSwitching,
- )?.value;
-
return (
);
}
diff --git a/ui/components/multichain/app-header/app-header-unlocked-content.tsx b/ui/components/multichain/app-header/app-header-unlocked-content.tsx
index 57e0c2f2c5fc..69ffca3f71c3 100644
--- a/ui/components/multichain/app-header/app-header-unlocked-content.tsx
+++ b/ui/components/multichain/app-header/app-header-unlocked-content.tsx
@@ -55,10 +55,7 @@ import { MetaMetricsContext } from '../../../contexts/metametrics';
import { useCopyToClipboard } from '../../../hooks/useCopyToClipboard';
import { MINUTE } from '../../../../shared/constants/time';
import { NotificationsTagCounter } from '../notifications-tag-counter';
-import {
- CONNECTIONS,
- REVIEW_PERMISSIONS,
-} from '../../../helpers/constants/routes';
+import { REVIEW_PERMISSIONS } from '../../../helpers/constants/routes';
import { MultichainNetwork } from '../../../selectors/multichain';
type AppHeaderUnlockedContentProps = {
@@ -122,11 +119,7 @@ export const AppHeaderUnlockedContent = ({
};
const handleConnectionsRoute = () => {
- if (process.env.CHAIN_PERMISSIONS) {
- history.push(`${REVIEW_PERMISSIONS}/${encodeURIComponent(origin)}`);
- } else {
- history.push(`${CONNECTIONS}/${encodeURIComponent(origin)}`);
- }
+ history.push(`${REVIEW_PERMISSIONS}/${encodeURIComponent(origin)}`);
};
return (
diff --git a/ui/components/multichain/disconnect-all-modal/disconnect-all-modal.tsx b/ui/components/multichain/disconnect-all-modal/disconnect-all-modal.tsx
index 17f5357a2fbd..62ca0ed8093a 100644
--- a/ui/components/multichain/disconnect-all-modal/disconnect-all-modal.tsx
+++ b/ui/components/multichain/disconnect-all-modal/disconnect-all-modal.tsx
@@ -19,7 +19,6 @@ export enum DisconnectType {
}
export const DisconnectAllModal = ({
- type,
hostname,
onClick,
onClose,
@@ -35,17 +34,9 @@ export const DisconnectAllModal = ({
-
- {process.env.CHAIN_PERMISSIONS
- ? t('disconnect')
- : t('disconnectAllTitle', [t(type)])}
-
+ {t('disconnect')}
- {process.env.CHAIN_PERMISSIONS ? (
- {t('disconnectAllDescription', [hostname])}
- ) : (
- {t('disconnectAllText', [t(type), hostname])}
- )}
+ {{t('disconnectAllDescription', [hostname])} }
void }) => {
dispatch(setActiveNetwork(networkClientId));
dispatch(toggleNetworkMenu());
- if (
- process.env.CHAIN_PERMISSIONS &&
- permittedAccountAddresses.length > 0
- ) {
+ if (permittedAccountAddresses.length > 0) {
grantPermittedChain(selectedTabOrigin, network.chainId);
if (!permittedChainIds.includes(network.chainId)) {
dispatch(showPermittedNetworkToast());
diff --git a/ui/components/multichain/pages/permissions-page/__snapshots__/permissions-page.test.js.snap b/ui/components/multichain/pages/permissions-page/__snapshots__/permissions-page.test.js.snap
index 69054c8eaa43..66dbd90aeea2 100644
--- a/ui/components/multichain/pages/permissions-page/__snapshots__/permissions-page.test.js.snap
+++ b/ui/components/multichain/pages/permissions-page/__snapshots__/permissions-page.test.js.snap
@@ -55,32 +55,14 @@ exports[`All Connections render renders correctly 1`] = `
style="align-self: center;"
>
- Connected with
+ 1
+
+ accounts
+ •
+ 0
+
+ networks
-
Alerts""
- data-tooltipped=""
- style="display: inline;"
- >
-
-
{
const t = useI18nContext();
@@ -39,32 +34,6 @@ export const ConnectionListItem = ({ connection, onClick }) => {
getPermittedChainsForSelectedTab(state, connection.origin),
);
- const renderListItem = process.env.CHAIN_PERMISSIONS ? (
-
- ) : (
-
- }
- >
-
-
- );
-
return (
{
avatarSize={IconSize.Md}
/>
) : (
- <>{renderListItem}>
+
)}
{
alignItems={AlignItems.center}
gap={1}
>
- {process.env.CHAIN_PERMISSIONS ? (
-
- {connection.addresses.length} {t('accountsSmallCase')}
- •
- {connectedNetworks.length} {t('networksSmallCase')}
-
- ) : (
- <>
-
- {t('connectedWith')}
-
-
-
- >
- )}
+
+ {connection.addresses.length} {t('accountsSmallCase')}
+ •
+ {connectedNetworks.length} {t('networksSmallCase')}
+
)}
diff --git a/ui/components/multichain/pages/permissions-page/connection-list-item.test.js b/ui/components/multichain/pages/permissions-page/connection-list-item.test.js
index 7e9205517cd5..ffec0e4a3b28 100644
--- a/ui/components/multichain/pages/permissions-page/connection-list-item.test.js
+++ b/ui/components/multichain/pages/permissions-page/connection-list-item.test.js
@@ -37,6 +37,10 @@ describe('ConnectionListItem', () => {
iconUrl: 'https://metamask.github.io/test-dapp/metamask-fox.svg',
networkIconUrl: 'https://metamask.github.io/test-dapp/metamask-fox.svg',
networkName: 'Test Dapp Network',
+ addresses: [
+ '0xaaaF07C80ce267F3132cE7e6048B66E6E669365B',
+ '0xbbbD671F1Fcc94bCF0ebC6Ec4790Da35E8d5e1E1',
+ ],
};
const { getByText, getByTestId } = renderWithProvider(
@@ -70,36 +74,4 @@ describe('ConnectionListItem', () => {
fireEvent.click(getByTestId('connection-list-item'));
expect(onClickMock).toHaveBeenCalledTimes(1);
});
-
- it('renders badgewrapper correctly for non-Snap connection', () => {
- const onClickMock = jest.fn();
- const mockConnection2 = {
- extensionId: null,
- iconUrl: 'https://metamask.github.io/test-dapp/metamask-fox.svg',
- name: 'MM Test Dapp',
- origin: 'https://metamask.github.io',
- subjectType: 'website',
- addresses: ['0x0836f5ed6b62baf60706fe3adc0ff0fd1df833da'],
- addressToNameMap: {
- '0x0836f5ed6b62baf60706fe3adc0ff0fd1df833da':
- 'Unreasonably long account name',
- },
- networkIconUrl: './images/eth_logo.svg',
- networkName: 'Ethereum Mainnet',
- };
- const { getByTestId } = renderWithProvider(
-
,
- store,
- );
-
- expect(
- getByTestId('connection-list-item__avatar-network-badge'),
- ).toBeInTheDocument();
-
- expect(
- document
- .querySelector('.mm-avatar-network__network-image')
- .getAttribute('src'),
- ).toBe(mockConnection2.networkIconUrl);
- });
});
diff --git a/ui/components/multichain/pages/permissions-page/permissions-page.js b/ui/components/multichain/pages/permissions-page/permissions-page.js
index 2b5a99fc55f5..491e041d7ac5 100644
--- a/ui/components/multichain/pages/permissions-page/permissions-page.js
+++ b/ui/components/multichain/pages/permissions-page/permissions-page.js
@@ -23,7 +23,6 @@ import {
TextVariant,
} from '../../../../helpers/constants/design-system';
import {
- CONNECTIONS,
DEFAULT_ROUTE,
REVIEW_PERMISSIONS,
} from '../../../../helpers/constants/routes';
@@ -34,6 +33,7 @@ import {
} from '../../../../selectors';
import { ProductTour } from '../../product-tour-popover';
import { hidePermissionsTour } from '../../../../store/actions';
+import { isSnapId } from '../../../../helpers/utils/snaps';
import { ConnectionListItem } from './connection-list-item';
export const PermissionsPage = () => {
@@ -54,16 +54,14 @@ export const PermissionsPage = () => {
const handleConnectionClick = (connection) => {
const hostName = connection.origin;
const safeEncodedHost = encodeURIComponent(hostName);
- if (process.env.CHAIN_PERMISSIONS) {
- history.push(`${REVIEW_PERMISSIONS}/${safeEncodedHost}`);
- } else {
- history.push(`${CONNECTIONS}/${safeEncodedHost}`);
- }
+
+ history.push(`${REVIEW_PERMISSIONS}/${safeEncodedHost}`);
};
const renderConnectionsList = (connectionList) =>
Object.entries(connectionList).map(([itemKey, connection]) => {
- return (
+ const isSnap = isSnapId(connection.origin);
+ return isSnap ? null : (
{
startIconName={IconName.Logout}
danger
onClick={() => setShowDisconnectAllModal(true)}
+ data-test-id="disconnect-all"
>
{t('disconnect')}
diff --git a/ui/pages/permissions-connect/__snapshots__/permissions-connect.test.tsx.snap b/ui/pages/permissions-connect/__snapshots__/permissions-connect.test.tsx.snap
deleted file mode 100644
index 3115caf5af16..000000000000
--- a/ui/pages/permissions-connect/__snapshots__/permissions-connect.test.tsx.snap
+++ /dev/null
@@ -1,236 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`PermissionApprovalContainer ConnectPath renders correctly 1`] = `
-
-
-
-
-
-
-
- metamask.io
-
-
- https://metamask.io
-
-
-
-
-
-
-
- Connect with MetaMask
-
-
- Select the account(s) to use on this site
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Account 1 (0xd5e09...81111)
-
-
-
-
-
-
-
-
-
-
-
-
-
-`;
diff --git a/ui/pages/permissions-connect/permissions-connect.component.js b/ui/pages/permissions-connect/permissions-connect.component.js
index 09befa7218cd..417a82777b36 100644
--- a/ui/pages/permissions-connect/permissions-connect.component.js
+++ b/ui/pages/permissions-connect/permissions-connect.component.js
@@ -19,6 +19,7 @@ import {
// TODO: Remove restricted import
// eslint-disable-next-line import/no-restricted-paths
import { PermissionNames } from '../../../app/scripts/controllers/permissions';
+import { isSnapId } from '../../helpers/utils/snaps';
import ChooseAccount from './choose-account';
import PermissionsRedirect from './redirect';
import SnapsConnect from './snaps/snaps-connect';
@@ -328,6 +329,8 @@ export default class PermissionConnect extends Component {
snapsInstallPrivacyWarningShown,
} = this.state;
+ const isRequestingSnap = isSnapId(permissionsRequest?.metadata?.origin);
+
return (
{!hideTopBar && this.renderTopBar(permissionsRequestId)}
@@ -339,17 +342,7 @@ export default class PermissionConnect extends Component {
path={connectPath}
exact
render={() =>
- process.env.CHAIN_PERMISSIONS ? (
-
- this.cancelPermissionsRequest(requestId)
- }
- activeTabOrigin={this.state.origin}
- request={permissionsRequest}
- permissionsRequestId={permissionsRequestId}
- approveConnection={this.approveConnection}
- />
- ) : (
+ isRequestingSnap ? (
+ ) : (
+
+ this.cancelPermissionsRequest(requestId)
+ }
+ activeTabOrigin={this.state.origin}
+ request={permissionsRequest}
+ permissionsRequestId={permissionsRequestId}
+ approveConnection={this.approveConnection}
+ />
)
}
/>
diff --git a/ui/pages/permissions-connect/permissions-connect.test.tsx b/ui/pages/permissions-connect/permissions-connect.test.tsx
deleted file mode 100644
index 05b1120cf5d8..000000000000
--- a/ui/pages/permissions-connect/permissions-connect.test.tsx
+++ /dev/null
@@ -1,180 +0,0 @@
-import React from 'react';
-import configureStore from 'redux-mock-store';
-import thunk from 'redux-thunk';
-
-import { ApprovalType } from '@metamask/controller-utils';
-import { BtcAccountType } from '@metamask/keyring-api';
-import { fireEvent } from '@testing-library/react';
-// TODO: Remove restricted import
-// eslint-disable-next-line import/no-restricted-paths
-import messages from '../../../app/_locales/en/messages.json';
-import { renderWithProvider } from '../../../test/lib/render-helpers';
-import mockState from '../../../test/data/mock-state.json';
-import { CONNECT_ROUTE } from '../../helpers/constants/routes';
-import { createMockInternalAccount } from '../../../test/jest/mocks';
-import { shortenAddress } from '../../helpers/utils/util';
-import PermissionApprovalContainer from './permissions-connect.container';
-
-const mockPermissionRequestId = '0cbc1f26-8772-4512-8ad7-f547d6e8b72c';
-
-jest.mock('../../store/actions', () => {
- return {
- ...jest.requireActual('../../store/actions'),
- getRequestAccountTabIds: jest.fn().mockReturnValue({
- type: 'SET_REQUEST_ACCOUNT_TABS',
- payload: {},
- }),
- };
-});
-
-const mockAccount = createMockInternalAccount({ name: 'Account 1' });
-const mockBtcAccount = createMockInternalAccount({
- name: 'BTC Account',
- address: 'bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq',
- type: BtcAccountType.P2wpkh,
-});
-
-const defaultProps = {
- history: {
- location: {
- pathname: `${CONNECT_ROUTE}/${mockPermissionRequestId}`,
- },
- },
- location: {
- pathname: `${CONNECT_ROUTE}/${mockPermissionRequestId}`,
- },
- match: {
- params: {
- id: mockPermissionRequestId,
- },
- },
-};
-
-const render = (
- props = defaultProps,
- type: ApprovalType = ApprovalType.WalletRequestPermissions,
-) => {
- let pendingPermission;
- if (type === ApprovalType.WalletRequestPermissions) {
- pendingPermission = {
- id: mockPermissionRequestId,
- origin: 'https://metamask.io',
- type: ApprovalType.WalletRequestPermissions,
- time: 1721376328642,
- requestData: {
- metadata: {
- id: mockPermissionRequestId,
- origin: 'https://metamask.io',
- },
- permissions: {
- eth_accounts: {},
- },
- },
- requestState: null,
- expectsResult: false,
- };
- }
-
- const state = {
- ...mockState,
- metamask: {
- ...mockState.metamask,
- internalAccounts: {
- accounts: {
- [mockAccount.id]: mockAccount,
- [mockBtcAccount.id]: mockBtcAccount,
- },
- selectedAccount: mockAccount.id,
- },
- keyrings: [
- {
- type: 'HD Key Tree',
- accounts: [mockAccount.address],
- },
- {
- type: 'Snap Keyring',
- accounts: [mockBtcAccount.address],
- },
- ],
- accounts: {
- [mockAccount.address]: {
- address: mockAccount.address,
- balance: '0x0',
- },
- },
- balances: {
- [mockBtcAccount.id]: {},
- },
- pendingApprovals: {
- [mockPermissionRequestId]: pendingPermission,
- },
- },
- };
- const middlewares = [thunk];
- const mockStore = configureStore(middlewares);
- const store = mockStore(state);
-
- return {
- render: renderWithProvider(
- ,
- store,
- `${CONNECT_ROUTE}/${mockPermissionRequestId}`,
- ),
- store,
- };
-};
-
-describe('PermissionApprovalContainer', () => {
- describe('ConnectPath', () => {
- it('renders correctly', () => {
- const {
- render: { container, getByText },
- } = render();
- expect(getByText(messages.next.message)).toBeInTheDocument();
- expect(getByText(messages.cancel.message)).toBeInTheDocument();
- expect(container).toMatchSnapshot();
- });
-
- it('renders the list without BTC accounts', async () => {
- const {
- render: { getByText, queryByText },
- } = render();
- expect(
- getByText(
- `${mockAccount.metadata.name} (${shortenAddress(
- mockAccount.address,
- )})`,
- ),
- ).toBeInTheDocument();
- expect(
- queryByText(
- `${mockBtcAccount.metadata.name} (${shortenAddress(
- mockBtcAccount.address,
- )})`,
- ),
- ).not.toBeInTheDocument();
- });
- });
-
- describe('Add new account', () => {
- it('displays the correct account number', async () => {
- const {
- render: { getByText },
- store,
- } = render();
- fireEvent.click(getByText(messages.newAccount.message));
-
- const dispatchedActions = store.getActions();
-
- expect(dispatchedActions).toHaveLength(2); // first action is 'SET_REQUEST_ACCOUNT_TABS'
- expect(dispatchedActions[1]).toStrictEqual({
- type: 'UI_MODAL_OPEN',
- payload: {
- name: 'NEW_ACCOUNT',
- onCreateNewAccount: expect.any(Function),
- newAccountNumber: 2,
- },
- });
- });
- });
-});
diff --git a/ui/pages/routes/routes.component.js b/ui/pages/routes/routes.component.js
index 1fdbad27ed67..25c41ca37c82 100644
--- a/ui/pages/routes/routes.component.js
+++ b/ui/pages/routes/routes.component.js
@@ -787,7 +787,7 @@ export default class Routes extends Component {
/>
) : null}
- {process.env.CHAIN_PERMISSIONS && isPermittedNetworkToastOpen ? (
+ {isPermittedNetworkToastOpen ? (
Date: Thu, 10 Oct 2024 14:16:41 +0200
Subject: [PATCH 29/41] chore: bump profile-sync-controller to 0.9.7 (#27749)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
This PR bumps `@metamask/profile-sync-controller` to version `0.9.7`.
This version fixes an account sync bug where we would save imported
accounts in user storage.
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27749?quickstart=1)
## **Related issues**
Fixes: https://consensyssoftware.atlassian.net/browse/NOTIFY-1215
## **Manual testing steps**
1. Create a new SRP
2. Add new accounts, rename some
3. Uninstall extension and reinstall
4. Import your previously created SRP
5. All your previously created accounts and respective names should be
there!
## **Screenshots/Recordings**
### **Before**
### **After**
## **Pre-merge author checklist**
- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
package.json | 2 +-
yarn.lock | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/package.json b/package.json
index 416b3e1b0420..d3f7cf42a1dc 100644
--- a/package.json
+++ b/package.json
@@ -344,7 +344,7 @@
"@metamask/post-message-stream": "^8.0.0",
"@metamask/ppom-validator": "0.34.0",
"@metamask/preinstalled-example-snap": "^0.1.0",
- "@metamask/profile-sync-controller": "^0.9.6",
+ "@metamask/profile-sync-controller": "^0.9.7",
"@metamask/providers": "^14.0.2",
"@metamask/queued-request-controller": "^2.0.0",
"@metamask/rate-limit-controller": "^6.0.0",
diff --git a/yarn.lock b/yarn.lock
index 1e00e14c6cf8..4b5ad861cc3d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6066,9 +6066,9 @@ __metadata:
languageName: node
linkType: hard
-"@metamask/profile-sync-controller@npm:^0.9.6":
- version: 0.9.6
- resolution: "@metamask/profile-sync-controller@npm:0.9.6"
+"@metamask/profile-sync-controller@npm:^0.9.7":
+ version: 0.9.7
+ resolution: "@metamask/profile-sync-controller@npm:0.9.7"
dependencies:
"@metamask/base-controller": "npm:^7.0.1"
"@metamask/keyring-api": "npm:^8.1.3"
@@ -6084,7 +6084,7 @@ __metadata:
"@metamask/accounts-controller": ^18.1.1
"@metamask/keyring-controller": ^17.2.0
"@metamask/snaps-controllers": ^9.7.0
- checksum: 10/102572a8805dde33eb318bf87ff2cd14cd5d5eae9139f18641c72a166ffa42dd4365d7617407d98521f3ec5e9b1d46517b283742be32825faf276141413bab51
+ checksum: 10/e53888533b2aae937bbe4e385dca2617c324b34e3e60af218cd98c26d514fb725f4c67b649f126e055f6a50a554817b229d37488115b98d70e8aee7b3a910bde
languageName: node
linkType: hard
@@ -26149,7 +26149,7 @@ __metadata:
"@metamask/post-message-stream": "npm:^8.0.0"
"@metamask/ppom-validator": "npm:0.34.0"
"@metamask/preinstalled-example-snap": "npm:^0.1.0"
- "@metamask/profile-sync-controller": "npm:^0.9.6"
+ "@metamask/profile-sync-controller": "npm:^0.9.7"
"@metamask/providers": "npm:^14.0.2"
"@metamask/queued-request-controller": "npm:^2.0.0"
"@metamask/rate-limit-controller": "npm:^6.0.0"
From 04ba878198df5f3d0af4c6b2dc0b0ce3da1db806 Mon Sep 17 00:00:00 2001
From: Charly Chevalier
Date: Thu, 10 Oct 2024 14:35:42 +0200
Subject: [PATCH 30/41] fix(btc): fix jazzicons generations (#27662)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
The jazzicons were all the same for mainnet/testnet accounts. It was
probably due to the fact that the namespace being used was `eip155` for
all addresses, but Bitcoin addresses have a different format.
Here's the technical details:
1. The current "icon factory" being in used is the ethereum one:
-
https://github.com/MetaMask/metamask-extension/blob/develop/ui/components/ui/jazzicon/jazzicon.component.tsx#L25
-
https://github.com/MetaMask/metamask-extension/blob/develop/ui/components/ui/jazzicon/jazzicon.component.tsx#L64
- `namespace` always defaults to `eip155`
2. The default constructor used for the ethereum factory uses the
`jsNumberForAddress` which is ethereum-specific (or more like,
"hex-specific" here):
-
https://github.com/MetaMask/metamask-extension/blob/develop/ui/helpers/utils/icon-factory.ts#L40
-
https://github.com/MetaMask/metamask-extension/blob/develop/ui/helpers/utils/icon-factory.ts#L150-L154
- It slices the first 2 characters (probably to remove the `0x` prefix)
+ `parseInt(addr, 16)` will only work hex-strings, but Bitcoin is not
using this format
- the `parseInt` here will only consider the first valid hex-characters
of its input
To fix this, we check for the current address used for the jazzicon and
change the namespace based on this.
Ideally, we would want to use the `InternalAccount` object directly, but
that would require quite a lot of changes, so for now we keep this
simple.
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27662?quickstart=1)
## **Related issues**
N/A
## **Manual testing steps**
1. `yarn start:flask`
2. Settings > Experimental > "Enable Bitcoin support"
3. Create a Bitcoin mainnet account
4. Create a Bitcoin testnet account
5. Check that both jazzicons are different for those 2 Bitcoin accounts
6. Remove your Bitcoin accounts
7. Re-create them
8. Re-check that jazzicons are the same than step 5
9. "Hard"-restart your extension
10. Re-check that jazzicons are the same than step 5
## **Screenshots/Recordings**
### **Before**
![Screenshot 2024-10-07 at 16 17
35](https://github.com/user-attachments/assets/0a2e28e8-a81d-4468-9261-f1b0c8c3f02d)
### **After**
![Screenshot 2024-10-07 at 16 18
57](https://github.com/user-attachments/assets/81d378c9-6941-4067-9022-660e7dffb7b2)
## **Pre-merge author checklist**
- [ ] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
package.json | 2 +-
shared/lib/multichain.test.ts | 105 ++++++++++++------
shared/lib/multichain.ts | 15 +++
.../account-list-item.test.js.snap | 56 +++++-----
.../ui/jazzicon/jazzicon.component.tsx | 11 +-
yarn.lock | 10 +-
6 files changed, 130 insertions(+), 69 deletions(-)
diff --git a/package.json b/package.json
index d3f7cf42a1dc..fad9fae96418 100644
--- a/package.json
+++ b/package.json
@@ -361,7 +361,7 @@
"@metamask/snaps-utils": "^8.1.1",
"@metamask/transaction-controller": "^37.2.0",
"@metamask/user-operation-controller": "^13.0.0",
- "@metamask/utils": "^9.1.0",
+ "@metamask/utils": "^9.3.0",
"@ngraveio/bc-ur": "^1.1.12",
"@noble/hashes": "^1.3.3",
"@popperjs/core": "^2.4.0",
diff --git a/shared/lib/multichain.test.ts b/shared/lib/multichain.test.ts
index 3b982ff8aff3..4c1bab12d03b 100644
--- a/shared/lib/multichain.test.ts
+++ b/shared/lib/multichain.test.ts
@@ -1,4 +1,9 @@
-import { isBtcMainnetAddress, isBtcTestnetAddress } from './multichain';
+import { KnownCaipNamespace } from '@metamask/utils';
+import {
+ getCaipNamespaceFromAddress,
+ isBtcMainnetAddress,
+ isBtcTestnetAddress,
+} from './multichain';
const BTC_MAINNET_ADDRESSES = [
// P2WPKH
@@ -20,35 +25,71 @@ const SOL_ADDRESSES = [
];
describe('multichain', () => {
- // @ts-expect-error This is missing from the Mocha type definitions
- it.each(BTC_MAINNET_ADDRESSES)(
- 'returns true if address is compatible with BTC mainnet: %s',
- (address: string) => {
- expect(isBtcMainnetAddress(address)).toBe(true);
- },
- );
-
- // @ts-expect-error This is missing from the Mocha type definitions
- it.each([...BTC_TESTNET_ADDRESSES, ...ETH_ADDRESSES, ...SOL_ADDRESSES])(
- 'returns false if address is not compatible with BTC mainnet: %s',
- (address: string) => {
- expect(isBtcMainnetAddress(address)).toBe(false);
- },
- );
-
- // @ts-expect-error This is missing from the Mocha type definitions
- it.each(BTC_TESTNET_ADDRESSES)(
- 'returns true if address is compatible with BTC testnet: %s',
- (address: string) => {
- expect(isBtcTestnetAddress(address)).toBe(true);
- },
- );
-
- // @ts-expect-error This is missing from the Mocha type definitions
- it.each([...BTC_MAINNET_ADDRESSES, ...ETH_ADDRESSES, ...SOL_ADDRESSES])(
- 'returns false if address is compatible with BTC testnet: %s',
- (address: string) => {
- expect(isBtcTestnetAddress(address)).toBe(false);
- },
- );
+ describe('isBtcMainnetAddress', () => {
+ // @ts-expect-error This is missing from the Mocha type definitions
+ it.each(BTC_MAINNET_ADDRESSES)(
+ 'returns true if address is compatible with BTC mainnet: %s',
+ (address: string) => {
+ expect(isBtcMainnetAddress(address)).toBe(true);
+ },
+ );
+
+ // @ts-expect-error This is missing from the Mocha type definitions
+ it.each([...BTC_TESTNET_ADDRESSES, ...ETH_ADDRESSES, ...SOL_ADDRESSES])(
+ 'returns false if address is not compatible with BTC mainnet: %s',
+ (address: string) => {
+ expect(isBtcMainnetAddress(address)).toBe(false);
+ },
+ );
+ });
+
+ describe('isBtcTestnetAddress', () => {
+ // @ts-expect-error This is missing from the Mocha type definitions
+ it.each(BTC_TESTNET_ADDRESSES)(
+ 'returns true if address is compatible with BTC testnet: %s',
+ (address: string) => {
+ expect(isBtcTestnetAddress(address)).toBe(true);
+ },
+ );
+
+ // @ts-expect-error This is missing from the Mocha type definitions
+ it.each([...BTC_MAINNET_ADDRESSES, ...ETH_ADDRESSES, ...SOL_ADDRESSES])(
+ 'returns false if address is compatible with BTC testnet: %s',
+ (address: string) => {
+ expect(isBtcTestnetAddress(address)).toBe(false);
+ },
+ );
+ });
+
+ describe('getChainTypeFromAddress', () => {
+ // @ts-expect-error This is missing from the Mocha type definitions
+ it.each([...BTC_MAINNET_ADDRESSES, ...BTC_TESTNET_ADDRESSES])(
+ 'returns ChainType.Bitcoin for bitcoin address: %s',
+ (address: string) => {
+ expect(getCaipNamespaceFromAddress(address)).toBe(
+ KnownCaipNamespace.Bip122,
+ );
+ },
+ );
+
+ // @ts-expect-error This is missing from the Mocha type definitions
+ it.each(ETH_ADDRESSES)(
+ 'returns ChainType.Ethereum for ethereum address: %s',
+ (address: string) => {
+ expect(getCaipNamespaceFromAddress(address)).toBe(
+ KnownCaipNamespace.Eip155,
+ );
+ },
+ );
+
+ // @ts-expect-error This is missing from the Mocha type definitions
+ it.each(SOL_ADDRESSES)(
+ 'returns ChainType.Ethereum for non-supported address: %s',
+ (address: string) => {
+ expect(getCaipNamespaceFromAddress(address)).toBe(
+ KnownCaipNamespace.Eip155,
+ );
+ },
+ );
+ });
});
diff --git a/shared/lib/multichain.ts b/shared/lib/multichain.ts
index 8ef03509541b..942a9ce6c964 100644
--- a/shared/lib/multichain.ts
+++ b/shared/lib/multichain.ts
@@ -1,3 +1,4 @@
+import { CaipNamespace, KnownCaipNamespace } from '@metamask/utils';
import { validate, Network } from 'bitcoin-address-validation';
/**
@@ -26,3 +27,17 @@ export function isBtcMainnetAddress(address: string): boolean {
export function isBtcTestnetAddress(address: string): boolean {
return validate(address, Network.testnet);
}
+
+/**
+ * Returns the associated chain's type for the given address.
+ *
+ * @param address - The address to check.
+ * @returns The chain's type for that address.
+ */
+export function getCaipNamespaceFromAddress(address: string): CaipNamespace {
+ if (isBtcMainnetAddress(address) || isBtcTestnetAddress(address)) {
+ return KnownCaipNamespace.Bip122;
+ }
+ // Defaults to "Ethereum" for all other cases for now.
+ return KnownCaipNamespace.Eip155;
+}
diff --git a/ui/components/multichain/account-list-item/__snapshots__/account-list-item.test.js.snap b/ui/components/multichain/account-list-item/__snapshots__/account-list-item.test.js.snap
index c14fb8a0c42d..51f6f2e905f9 100644
--- a/ui/components/multichain/account-list-item/__snapshots__/account-list-item.test.js.snap
+++ b/ui/components/multichain/account-list-item/__snapshots__/account-list-item.test.js.snap
@@ -32,7 +32,7 @@ exports[`AccountListItem renders AccountListItem component and shows account nam
class="mm-avatar-account__jazzicon"
>
Date: Thu, 10 Oct 2024 05:43:27 -0700
Subject: [PATCH 31/41] feat: add network picker to AssetPicker (#26559)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## **Description**
Changes included in this PR:
* Add a network picker to the AssetPicker modal component so that it can
be reused within the cross-chain swaps experience
* Update AssetPicker components to enable displaying network and asset
data when the selected network is not the same as the wallet's active
network. Example usecase: destination asset for cross-chain swaps.
Specifically:
- when selected `network` is not the same as wallet's network, display
- selected network's icons in asset list
- selected network's native token icons
- add `customTokenListGenerator` prop to AssetPicker that allows
upstream components to override the default displayed token list
Figma design:
https://www.figma.com/design/bC6RgeriyERMtMlZE8xwkm/Cross-Chain-Swaps?node-id=1490-18690&t=pnpoVVaJTqh15I0a-0
[![Open in GitHub
Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/26559?quickstart=1)
## **Related issues**
Fixes: https://consensyssoftware.atlassian.net/browse/METABRIDGE-866
## **Manual testing steps**
1. Swap+Send asset selection experience should not change
2. Storybook should show an AssetPicker variation that has a network
picker
## **Screenshots/Recordings**
### **Before**
### **After**
![Screenshot 2024-10-02 at 4 09
51 PM](https://github.com/user-attachments/assets/ff3f2854-7120-4f3d-9e55-88a325a5b3db)
## **Pre-merge author checklist**
- [X] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask
Extension Coding
Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/CODING_GUIDELINES.md).
- [X] I've completed the PR template to the best of my ability
- [X] I’ve included tests if applicable
- [X] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [X] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-extension/blob/develop/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.
## **Pre-merge reviewer checklist**
- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.
---
app/_locales/en/messages.json | 3 +
.../multichain/asset-picker-send.spec.ts | 4 +-
.../asset-picker-modal/Asset.test.tsx | 5 +-
.../asset-picker-modal/Asset.tsx | 14 +-
.../asset-picker-modal/AssetList.tsx | 48 +--
.../asset-picker-modal-network.test.tsx.snap | 392 ++++++++++++++++++
.../asset-picker-modal-network.test.tsx | 132 ++++++
.../asset-picker-modal-network.tsx | 111 +++++
.../asset-picker-modal.test.tsx | 65 +++
.../asset-picker-modal/asset-picker-modal.tsx | 183 +++++---
.../asset-picker-modal/index.scss | 19 +
.../__snapshots__/asset-picker.test.tsx.snap | 72 ++++
.../asset-picker/asset-picker.stories.tsx | 91 +++-
.../asset-picker/asset-picker.test.tsx | 96 ++++-
.../asset-picker/asset-picker.tsx | 168 +++++---
.../asset-picker/index.scss | 5 +
.../token-list-item/token-list-item.tsx | 12 +-
17 files changed, 1251 insertions(+), 169 deletions(-)
create mode 100644 ui/components/multichain/asset-picker-amount/asset-picker-modal/__snapshots__/asset-picker-modal-network.test.tsx.snap
create mode 100644 ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-network.test.tsx
create mode 100644 ui/components/multichain/asset-picker-amount/asset-picker-modal/asset-picker-modal-network.tsx
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index ecaedb3201d0..5f6a977c1cf4 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -870,6 +870,9 @@
"bridgeDontSend": {
"message": "Bridge, don't send"
},
+ "bridgeSelectNetwork": {
+ "message": "Select network"
+ },
"browserNotSupported": {
"message": "Your browser is not supported..."
},
diff --git a/test/e2e/tests/multichain/asset-picker-send.spec.ts b/test/e2e/tests/multichain/asset-picker-send.spec.ts
index 5accb14c6074..a071bec9426d 100644
--- a/test/e2e/tests/multichain/asset-picker-send.spec.ts
+++ b/test/e2e/tests/multichain/asset-picker-send.spec.ts
@@ -71,7 +71,7 @@ describe('AssetPickerSendFlow @no-mmi', function () {
)
).getText();
- assert.equal(tokenListValue, '25 ETH');
+ assert.equal(tokenListValue, '$250,000.00');
const tokenListSecondaryValue = await (
await driver.findElement(
@@ -79,7 +79,7 @@ describe('AssetPickerSendFlow @no-mmi', function () {
)
).getText();
- assert.equal(tokenListSecondaryValue, '$250,000.00');
+ assert.equal(tokenListSecondaryValue, '25 ETH');
// Search for CHZ
const searchInputField = await driver.waitForSelector(
diff --git a/ui/components/multichain/asset-picker-amount/asset-picker-modal/Asset.test.tsx b/ui/components/multichain/asset-picker-amount/asset-picker-modal/Asset.test.tsx
index f35bc8196724..0b641101c5dd 100644
--- a/ui/components/multichain/asset-picker-amount/asset-picker-modal/Asset.test.tsx
+++ b/ui/components/multichain/asset-picker-amount/asset-picker-modal/Asset.test.tsx
@@ -77,10 +77,11 @@ describe('Asset', () => {
expect.objectContaining({
tokenSymbol: 'WETH',
tokenImage: 'token-icon-url',
- primary: '10',
- secondary: '$10.10',
+ primary: '$10.10',
+ secondary: '10 WETH',
title: 'Token',
tooltipText: 'tooltip',
+ isPrimaryTokenSymbolHidden: true,
}),
{},
);
diff --git a/ui/components/multichain/asset-picker-amount/asset-picker-modal/Asset.tsx b/ui/components/multichain/asset-picker-amount/asset-picker-modal/Asset.tsx
index 83229689f055..f384ef8fd96f 100644
--- a/ui/components/multichain/asset-picker-amount/asset-picker-modal/Asset.tsx
+++ b/ui/components/multichain/asset-picker-amount/asset-picker-modal/Asset.tsx
@@ -40,18 +40,22 @@ export default function Asset({
{},
true,
);
+ const formattedAmount = decimalTokenAmount
+ ? `${formatAmount(
+ locale,
+ new BigNumber(decimalTokenAmount || '0', 10),
+ )} ${symbol}`
+ : undefined;
return (
);
}
diff --git a/ui/components/multichain/asset-picker-amount/asset-picker-modal/AssetList.tsx b/ui/components/multichain/asset-picker-amount/asset-picker-modal/AssetList.tsx
index 9061592cf37c..fa071740b51d 100644
--- a/ui/components/multichain/asset-picker-amount/asset-picker-modal/AssetList.tsx
+++ b/ui/components/multichain/asset-picker-amount/asset-picker-modal/AssetList.tsx
@@ -1,10 +1,11 @@
import React from 'react';
import { useSelector } from 'react-redux';
import classnames from 'classnames';
-import { getSelectedAccountCachedBalance } from '../../../../selectors';
+import {
+ getCurrentCurrency,
+ getSelectedAccountCachedBalance,
+} from '../../../../selectors';
import { getNativeCurrency } from '../../../../ducks/metamask/metamask';
-import { useUserPreferencedCurrency } from '../../../../hooks/useUserPreferencedCurrency';
-import { PRIMARY, SECONDARY } from '../../../../helpers/constants/common';
import { useCurrencyDisplay } from '../../../../hooks/useCurrencyDisplay';
import { AssetType } from '../../../../../shared/constants/transaction';
import { Box } from '../../../component-library';
@@ -43,28 +44,16 @@ export default function AssetList({
const nativeCurrency = useSelector(getNativeCurrency);
const balanceValue = useSelector(getSelectedAccountCachedBalance);
+ const currentCurrency = useSelector(getCurrentCurrency);
- const {
- currency: primaryCurrency,
- numberOfDecimals: primaryNumberOfDecimals,
- } = useUserPreferencedCurrency(PRIMARY, { ethNumberOfDecimals: 4 });
-
- const {
- currency: secondaryCurrency,
- numberOfDecimals: secondaryNumberOfDecimals,
- } = useUserPreferencedCurrency(SECONDARY, { ethNumberOfDecimals: 4 });
-
- const [, primaryCurrencyProperties] = useCurrencyDisplay(balanceValue, {
- numberOfDecimals: primaryNumberOfDecimals,
- currency: primaryCurrency,
+ const [primaryCurrencyValue] = useCurrencyDisplay(balanceValue, {
+ currency: currentCurrency,
+ hideLabel: true,
});
- const [secondaryCurrencyDisplay, secondaryCurrencyProperties] =
- useCurrencyDisplay(balanceValue, {
- numberOfDecimals: secondaryNumberOfDecimals,
- currency: secondaryCurrency,
- hideLabel: true,
- });
+ const [secondaryCurrencyValue] = useCurrencyDisplay(balanceValue, {
+ currency: nativeCurrency,
+ });
return (
@@ -72,6 +61,7 @@ export default function AssetList({
const tokenAddress = token.address?.toLowerCase();
const isSelected = tokenAddress === selectedToken?.toLowerCase();
const isDisabled = isTokenDisabled?.(token) ?? false;
+
return (
{token.type === AssetType.native ? (
) : (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+