diff --git a/.github/workflows/update-attributions.yml b/.github/workflows/update-attributions.yml
new file mode 100644
index 00000000000..785a1ee5f7d
--- /dev/null
+++ b/.github/workflows/update-attributions.yml
@@ -0,0 +1,195 @@
+name: Update Attributions
+
+on:
+ issue_comment:
+ types: created
+
+jobs:
+ is-fork-pull-request:
+ name: Determine whether this issue comment was on a pull request from a fork
+ if: ${{ github.event.issue.pull_request && startsWith(github.event.comment.body, '@metamaskbot update-attributions') }}
+ runs-on: ubuntu-latest
+ outputs:
+ IS_FORK: ${{ steps.is-fork.outputs.IS_FORK }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Determine whether this PR is from a fork
+ id: is-fork
+ run: echo "IS_FORK=$(gh pr view --json isCrossRepository --jq '.isCrossRepository' "${PR_NUMBER}" )" >> "$GITHUB_OUTPUT"
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ PR_NUMBER: ${{ github.event.issue.number }}
+
+ react-to-comment:
+ name: React to the comment
+ runs-on: ubuntu-latest
+ needs: is-fork-pull-request
+ # Early exit if this is a fork, since later steps are skipped for forks
+ if: ${{ needs.is-fork-pull-request.outputs.IS_FORK == 'false' }}
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: React to the comment
+ run: |
+ gh api \
+ --method POST \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ "/repos/${REPO}/issues/comments/${COMMENT_ID}/reactions" \
+ -f content='+1'
+ env:
+ COMMENT_ID: ${{ github.event.comment.id }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ REPO: ${{ github.repository }}
+
+ prepare:
+ name: Prepare dependencies
+ runs-on: ubuntu-latest
+ needs: is-fork-pull-request
+ # Early exit if this is a fork, since later steps are skipped for forks
+ if: ${{ needs.is-fork-pull-request.outputs.IS_FORK == 'false' }}
+ outputs:
+ COMMIT_SHA: ${{ steps.commit-sha.outputs.COMMIT_SHA }}
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: Checkout pull request
+ run: gh pr checkout "${PR_NUMBER}"
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ PR_NUMBER: ${{ github.event.issue.number }}
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.nvmrc'
+ cache: 'yarn'
+ - name: Install Yarn dependencies
+ run: yarn --immutable
+ - name: Get commit SHA
+ id: commit-sha
+ run: echo "COMMIT_SHA=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
+
+ update-attributions:
+ name: Update Attributions
+ runs-on: ubuntu-latest
+ needs:
+ - prepare
+ - is-fork-pull-request
+ # Early exit if this is a fork, since later steps are skipped for forks
+ if: ${{ needs.is-fork-pull-request.outputs.IS_FORK == 'false' }}
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ - name: Checkout pull request
+ run: gh pr checkout "${PR_NUMBER}"
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ PR_NUMBER: ${{ github.event.issue.number }}
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: '.nvmrc'
+ cache: 'yarn'
+ - name: Install dependencies from cache
+ run: yarn --immutable --immutable-cache
+ - name: Generate Attributions
+ run: yarn build:attribution
+ - name: Cache attributions file
+ uses: actions/cache/save@v3
+ with:
+ path: attribution.txt
+ key: cache-build-${{ needs.prepare.outputs.COMMIT_SHA }}
+
+ commit-updated-attributions:
+ name: Commit the updated Attributions
+ runs-on: ubuntu-latest
+ needs:
+ - prepare
+ - is-fork-pull-request
+ - update-attributions
+ if: ${{ needs.is-fork-pull-request.outputs.IS_FORK == 'false' }}
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+ with:
+ # Use PAT to ensure that the commit later can trigger status check workflows
+ token: ${{ secrets.GITHUB_TOKEN }}
+ - name: Checkout pull request
+ run: gh pr checkout "${PR_NUMBER}"
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ PR_NUMBER: ${{ github.event.issue.number }}
+ - name: Get commit SHA
+ id: commit-sha
+ run: echo "COMMIT_SHA=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT"
+ - name: Restore attributions file
+ uses: actions/cache/restore@v3
+ with:
+ path: attribution.txt
+ key: cache-build-${{ needs.prepare.outputs.COMMIT_SHA }}
+ fail-on-cache-miss: true
+ - name: Check whether there are attributions changes
+ id: attributions-changes
+ run: |
+ if git diff --exit-code
+ then
+ echo "HAS_CHANGES=false" >> "$GITHUB_OUTPUT"
+ else
+ echo "HAS_CHANGES=true" >> "$GITHUB_OUTPUT"
+ fi
+ - name: Commit the updated attributions
+ if: steps.attributions-changes.outputs.HAS_CHANGES == 'true'
+ run: |
+ git config --global user.name 'MetaMask Bot'
+ git config --global user.email 'metamaskbot@users.noreply.github.com'
+ git commit -am "Update Attributions"
+ git push
+ - name: Post comment
+ run: |
+ if [[ $HAS_CHANGES == 'true' ]]
+ then
+ gh pr comment "${PR_NUMBER}" --body 'Attributions updated'
+ else
+ gh pr comment "${PR_NUMBER}" --body 'No attributions changes'
+ fi
+ env:
+ HAS_CHANGES: ${{ steps.attributions-changes.outputs.HAS_CHANGES }}
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ PR_NUMBER: ${{ github.event.issue.number }}
+
+ check-status:
+ name: Check whether the attributions update succeeded
+ runs-on: ubuntu-latest
+ needs:
+ - commit-updated-attributions
+ - is-fork-pull-request
+ # Early exit if this is a fork, since later steps are skipped for forks
+ if: ${{ needs.is-fork-pull-request.outputs.IS_FORK == 'false' }}
+ outputs:
+ PASSED: ${{ steps.set-output.outputs.PASSED }}
+ steps:
+ - name: Set PASSED output
+ id: set-output
+ run: echo "PASSED=true" >> "$GITHUB_OUTPUT"
+
+ failure-comment:
+ name: Comment about the attributions update failure
+ if: ${{ always() && needs.is-fork-pull-request.outputs.IS_FORK == 'false' }}
+ runs-on: ubuntu-latest
+ needs:
+ - is-fork-pull-request
+ - check-status
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ - name: Post comment if the update failed
+ run: |
+ passed="${{ needs.check-status.outputs.PASSED }}"
+ if [[ $passed != "true" ]]; then
+ gh pr comment "${PR_NUMBER}" --body "Attributions update failed. You can [review the logs or retry the attributions update here](${ACTION_RUN_URL})"
+ fi
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ PR_NUMBER: ${{ github.event.issue.number }}
+ ACTION_RUN_URL: '${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}'
diff --git a/.gitignore b/.gitignore
index f4c8af6ff83..d0ee5c4774a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,6 +45,8 @@ android/app/google-services.json
node_modules/
npm-debug.log
yarn-error.log
+.yalc
+yalc.lock
# buck
buck-out/
diff --git a/.storybook/storybook.requires.js b/.storybook/storybook.requires.js
index 8c929c9fe7d..4c8963175cc 100644
--- a/.storybook/storybook.requires.js
+++ b/.storybook/storybook.requires.js
@@ -117,6 +117,8 @@ const getStories = () => {
'./app/components/UI/Name/Name.stories.tsx': require('../app/components/UI/Name/Name.stories.tsx'),
"./app/components/UI/SimulationDetails/SimulationDetails.stories.tsx": require("../app/components/UI/SimulationDetails/SimulationDetails.stories.tsx"),
"./app/component-library/components-temp/CellSelectWithMenu/CellSelectWithMenu.stories.tsx": require("../app/component-library/components-temp/CellSelectWithMenu/CellSelectWithMenu.stories.tsx"),
+ './app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.stories': require('../app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.stories.tsx'),
+ './app/component-library/components-temp/Price/PercentageChange/PercentageChange.stories': require('../app/component-library/components-temp/Price/PercentageChange/PercentageChange.stories.tsx'),
};
};
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 94dc5e5e7cf..e51efda74ec 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,105 @@
## Current Main Branch
+## 7.26.0 - Jul 5, 2024
+### Added
+- [#9937](https://github.com/MetaMask/metamask-mobile/pull/9937): feat: modification of the network bottom sheet to use the new UI redesign by adding the popular network section as additional network (#9937)
+- [#9856](https://github.com/MetaMask/metamask-mobile/pull/9856): feat: new attribution github workflow (#9856)
+- [#9768](https://github.com/MetaMask/metamask-mobile/pull/9768): feat: add MetaMetrics delete on Wallet delete (#9768)
+- [#9785](https://github.com/MetaMask/metamask-mobile/pull/9785): feat: Log the validity of the keyringController in the top 3 Migrations that appear in Sentry (#9785)
+- [#9885](https://github.com/MetaMask/metamask-mobile/pull/9885): feat: Feat/9492 add unsupported method and legacy method middlewares (#9885)
+- [#9743](https://github.com/MetaMask/metamask-mobile/pull/9743): feat: Metrics/1803 emit error viewed event (#9743)
+- [#9888](https://github.com/MetaMask/metamask-mobile/pull/9888): feat: add set approve for all screen (#9888)
+- [#9794](https://github.com/MetaMask/metamask-mobile/pull/9794): feat: add increase allowance screen (#9794)
+- [#9828](https://github.com/MetaMask/metamask-mobile/pull/9828): feat: enable transaction simulations (#9828)
+- [#9648](https://github.com/MetaMask/metamask-mobile/pull/9648): feat: add transaction simulations preference (#9648)
+- [#9783](https://github.com/MetaMask/metamask-mobile/pull/9783): feat: add transaction simulation metrics (#9783)
+- [#9793](https://github.com/MetaMask/metamask-mobile/pull/9793): feat: add fiat support to simulations (#9793)
+- [#9410](https://github.com/MetaMask/metamask-mobile/pull/9410): feat: add SimulationDetails component (#9410)
+- [#9070](https://github.com/MetaMask/metamask-mobile/pull/9070): feat: remove selectSelectedAddress in favour of selectSelectedInternalAccount (#9070)
+- [#9845](https://github.com/MetaMask/metamask-mobile/pull/9845): feat: updated design-tokens to v4 (#9845)
+- [#9653](https://github.com/MetaMask/metamask-mobile/pull/9653): feat: added design tokens eslint rules to mobile (#9653)
+- [#9473](https://github.com/MetaMask/metamask-mobile/pull/9473): feat: notifications details screen (#9473)
+
+### Changed
+- [#9884](https://github.com/MetaMask/metamask-mobile/pull/9884): chore(pr template + readme): add link to contributor docs (#9884)
+- [#9863](https://github.com/MetaMask/metamask-mobile/pull/9863): chore: Revert ""fix: swaps quote nan to bnjs (#9848)"" (#9863)
+- [#9915](https://github.com/MetaMask/metamask-mobile/pull/9915): test: 1454 refactor modal pages batch 4 (#9915)
+- [#9998](https://github.com/MetaMask/metamask-mobile/pull/9998): test: marketing optin date trigger testing. (#9998)
+- [#9941](https://github.com/MetaMask/metamask-mobile/pull/9941): chore: Revert ""chore: fitness quality gate to only allow TS & TSX files in app directory"" (#9941)
+- [#9913](https://github.com/MetaMask/metamask-mobile/pull/9913): chore: Update signature controller to v16 (#9913)
+- [#9723](https://github.com/MetaMask/metamask-mobile/pull/9723): chore: fitness quality gate to only allow TS & TSX files in app directory (#9723)
+- [#9926](https://github.com/MetaMask/metamask-mobile/pull/9926): chore: Resolve braces package to address audit issue (#9926)
+- [#9814](https://github.com/MetaMask/metamask-mobile/pull/9814): chore: Update Preferences Controller v^11 (#9814)
+- [#9714](https://github.com/MetaMask/metamask-mobile/pull/9714): test: import tokens detected (#9714)
+- [#9693](https://github.com/MetaMask/metamask-mobile/pull/9693): chore: update gas fee controller to 15.1.2 (#9693)
+- [#9868](https://github.com/MetaMask/metamask-mobile/pull/9868): chore: add source to setup script (#9868)
+- [#9886](https://github.com/MetaMask/metamask-mobile/pull/9886): test: Update Browserstack url as old link deprecated (#9886)
+- [#9865](https://github.com/MetaMask/metamask-mobile/pull/9865): chore: swap view crash fetching quotes (#9865)
+- [#9852](https://github.com/MetaMask/metamask-mobile/pull/9852): test: fix Assertion only working on IOS (#9852)
+- [#9838](https://github.com/MetaMask/metamask-mobile/pull/9838): test: E2e Regression failure fix (#9838)
+- [#9805](https://github.com/MetaMask/metamask-mobile/pull/9805): chore: Upgrade address-book-controller (#9805)
+- [#9809](https://github.com/MetaMask/metamask-mobile/pull/9809): chore: merge 7.23.0 tag (#9809)
+- [#9952](https://github.com/MetaMask/metamask-mobile/pull/9952): chore: update code owners (#9952)
+- [#9790](https://github.com/MetaMask/metamask-mobile/pull/9790): chore(ci): update @rhysd/actionlint to 1.7.1 (#9790)
+- [#9545](https://github.com/MetaMask/metamask-mobile/pull/9545): chore: Fix CocoaPods install on Linux (#9545)
+- [#9883](https://github.com/MetaMask/metamask-mobile/pull/9883): chore: Update ppom package to 1.4.7 (#9883)
+- [#9866](https://github.com/MetaMask/metamask-mobile/pull/9866): chore: commit changes to project.pgxproj caused by known issue in xcode 15 (#9866)
+- [#9986](https://github.com/MetaMask/metamask-mobile/pull/9986): test: fix `TransactionReview` snapshots (#9986)
+- [#9965](https://github.com/MetaMask/metamask-mobile/pull/9965): test: comment out flaky test from `encryption-with-key` (#9965)
+- [#9964](https://github.com/MetaMask/metamask-mobile/pull/9964): test: fix snapshots from `AesCryptoTestForm` (#9964)
+- [#9898](https://github.com/MetaMask/metamask-mobile/pull/9898): test: AES module E2E tests (#9898)
+- [#9949](https://github.com/MetaMask/metamask-mobile/pull/9949): chore: add SmokeAccounts E2E tag (#9949)
+- [#9942](https://github.com/MetaMask/metamask-mobile/pull/9942): refactor: updated cellbase to allow size changes (#9942)
+- [#9922](https://github.com/MetaMask/metamask-mobile/pull/9922): refactor: replace secondary colors with warning colors (#9922)
+- [#9899](https://github.com/MetaMask/metamask-mobile/pull/9899): chore: align ButtonIcons with design (#9899)
+- [#9875](https://github.com/MetaMask/metamask-mobile/pull/9875): refactor: update brandColors to be imported from design system (#9875)
+- [#9718](https://github.com/MetaMask/metamask-mobile/pull/9718): chore: upgrade snaps-controller and adapts its usage (#9718)
+- [#9920](https://github.com/MetaMask/metamask-mobile/pull/9920): chore: remove update-attributions.yml (#9920)
+- [#9570](https://github.com/MetaMask/metamask-mobile/pull/9570): chore: Update `@metamask/keyring-controller` to v16 (#9570)
+- [#9234](https://github.com/MetaMask/metamask-mobile/pull/9234): chore: update the 'CODEOWNERS' file to include directories relevant to the 'sdk-devs' team (#9234)
+
+### Fixed
+- [#9903](https://github.com/MetaMask/metamask-mobile/pull/9903): fix: upgrade test failure fix for 7.24.0 release branch (#9903)
+- [#9844](https://github.com/MetaMask/metamask-mobile/pull/9844): fix: confirmations failing ci tests (#9844)
+- [#9831](https://github.com/MetaMask/metamask-mobile/pull/9831): fix: Fix audit ci (#9831)
+- [#9893](https://github.com/MetaMask/metamask-mobile/pull/9893): fix: contributor docs link is not correct in pr template (#9893)
+- [#9847](https://github.com/MetaMask/metamask-mobile/pull/9847): Fix/release testing issues (#9847)
+- [#9946](https://github.com/MetaMask/metamask-mobile/pull/9946): fix: Update help center URLs (#9946)
+- [#9848](https://github.com/MetaMask/metamask-mobile/pull/9848): fix: swaps quote nan to bnjs (#9848)
+- [#9781](https://github.com/MetaMask/metamask-mobile/pull/9781): fix: Update Basic Functionality settings description.json (#9781)
+- [#9763](https://github.com/MetaMask/metamask-mobile/pull/9763): "fix: JS ""pseudo protocol"" works when pasted on mobile browser (#9763)"
+- [#9993](https://github.com/MetaMask/metamask-mobile/pull/9993): fix: Fix/re order internal accounts (#9993)
+- [#9991](https://github.com/MetaMask/metamask-mobile/pull/9991): fix: fixed snapshots (#9991)
+- [#9905](https://github.com/MetaMask/metamask-mobile/pull/9905): "fix: ""data collection for marketing"" from PR #9687 (#9905)"
+- [#9980](https://github.com/MetaMask/metamask-mobile/pull/9980): fix: add migration to fix engine does not exist and (#9980)
+- [#9982](https://github.com/MetaMask/metamask-mobile/pull/9982): fix: migration 43 stringify to type of (#9982)
+- [#9894](https://github.com/MetaMask/metamask-mobile/pull/9894): fix: Update bitrise.yml with correct Browserstack url (#9894)
+- [#9887](https://github.com/MetaMask/metamask-mobile/pull/9887): fix: Update Browserstack url as old link deprecated (#9887)
+- [#9869](https://github.com/MetaMask/metamask-mobile/pull/9869): fix: Cherry pick of e2e fixes from main (#9869)
+- [#9855](https://github.com/MetaMask/metamask-mobile/pull/9855): fix: Undefined balance when fetching from chain (#9855)
+- [#9812](https://github.com/MetaMask/metamask-mobile/pull/9812): fix: main token balance not updating when switching accounts (#9812)
+- [#9674](https://github.com/MetaMask/metamask-mobile/pull/9674): fix: update Delete MetaMetrics Data copy to 30 days (#9674)
+- [#9819](https://github.com/MetaMask/metamask-mobile/pull/9819): fix: Add .e2e as part of the setup script (#9819)
+- [#9791](https://github.com/MetaMask/metamask-mobile/pull/9791): fix: Disable segment in E2E mode (#9791)
+- [#9934](https://github.com/MetaMask/metamask-mobile/pull/9934): fix: flakey CI asdf node version (#9934)
+- [#9584](https://github.com/MetaMask/metamask-mobile/pull/9584): fix: @metamask/swaps-controller v6 -> v9 (#9584)
+- [#9867](https://github.com/MetaMask/metamask-mobile/pull/9867): fix: only remove SES from exception if exception exists (#9867)
+- [#9870](https://github.com/MetaMask/metamask-mobile/pull/9870): fix: yarn deduplicate release/7.24.0 to fix dupe in #9864 (#9870)
+- [#9842](https://github.com/MetaMask/metamask-mobile/pull/9842): fix: error validating wallet connect signature with security provider (#9842)
+- [#9999](https://github.com/MetaMask/metamask-mobile/pull/9999): fix: new locales (#9999)
+- [#9826](https://github.com/MetaMask/metamask-mobile/pull/9826): fix: add migration for linea goerli (#9826)
+- [#9876](https://github.com/MetaMask/metamask-mobile/pull/9876): fix: update patch for updateNftMetadata fct (#9876)
+- [#9759](https://github.com/MetaMask/metamask-mobile/pull/9759): fix: remove unecessary calls to third party apis (#9759)
+- [#9746](https://github.com/MetaMask/metamask-mobile/pull/9746): fix: render images of networks removed from popularNetwork list (#9746)
+- [#9970](https://github.com/MetaMask/metamask-mobile/pull/9970): fix: error 'Invalid character in NaN' while gas editing (#9970)
+- [#9902](https://github.com/MetaMask/metamask-mobile/pull/9902): fix: Update PPOM controller to fix handling of HTTP status codes (#9902)
+- [#9943](https://github.com/MetaMask/metamask-mobile/pull/9943): fix: Duplicate accounts (#9943)
+- [#9974](https://github.com/MetaMask/metamask-mobile/pull/9974): fix(ramp): memoize asset before passing it to balance hook (#9968) (#9974)
+- [#9882](https://github.com/MetaMask/metamask-mobile/pull/9882): fix: edit account name screen display incorrect account name (#9882)
+- [#9891](https://github.com/MetaMask/metamask-mobile/pull/9891): fix: bug report template - remove reference to recordit (#9891)
+- [#9755](https://github.com/MetaMask/metamask-mobile/pull/9755): fix: display the DApp URL in connect screen for MetaMask IOS-SDK (#9755)
+
## 7.24.4 - Jun 25, 2024
### Fixed
- [10064](https://github.com/MetaMask/metamask-mobile/pull/10064) fix: Always mark the STX Opt In modal as seen
diff --git a/android/app/build.gradle b/android/app/build.gradle
index b9d2c2f58e5..1133709a933 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -181,8 +181,8 @@ android {
applicationId "io.metamask"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode 1354
- versionName "7.24.4"
+ versionCode 1359
+ versionName "7.26.0"
testBuildType System.getProperty('testBuildType', 'debug')
missingDimensionStrategy 'react-native-camera', 'general'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
diff --git a/android/gradle.properties b/android/gradle.properties
index f06abec2465..75e96754502 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -48,4 +48,3 @@ hermesEnabled=true
# TODO: explain following config options
android.disableResourceValidation=true
android.enableDexingArtifactTransform.desugaring=false
-AsyncStorage_db_size_in_MB=10
diff --git a/app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.stories.tsx b/app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.stories.tsx
new file mode 100644
index 00000000000..d9706d5e2e6
--- /dev/null
+++ b/app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.stories.tsx
@@ -0,0 +1,63 @@
+import React from 'react';
+import { Provider } from 'react-redux';
+import AggregatedPercentage from './AggregatedPercentage';
+import { createStore } from 'redux';
+import initialBackgroundState from '../../../../util/test/initial-background-state.json';
+
+const mockInitialState = {
+ wizard: {
+ step: 1,
+ },
+ engine: {
+ backgroundState: initialBackgroundState,
+ },
+};
+
+const rootReducer = (state = mockInitialState) => state;
+const store = createStore(rootReducer);
+
+export default {
+ title: 'Component Library / AggregatedPercentage',
+ component: AggregatedPercentage,
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+};
+
+const Template = (args) => ;
+
+export const Default = Template.bind({});
+Default.args = {
+ ethFiat: 1000,
+ tokenFiat: 500,
+ tokenFiat1dAgo: 950,
+ ethFiat1dAgo: 450,
+};
+
+export const NegativePercentageChange = Template.bind({});
+NegativePercentageChange.args = {
+ ethFiat: 900,
+ tokenFiat: 400,
+ tokenFiat1dAgo: 950,
+ ethFiat1dAgo: 1000,
+};
+
+export const PositivePercentageChange = Template.bind({});
+PositivePercentageChange.args = {
+ ethFiat: 1100,
+ tokenFiat: 600,
+ tokenFiat1dAgo: 500,
+ ethFiat1dAgo: 1000,
+};
+
+export const MixedPercentageChange = Template.bind({});
+MixedPercentageChange.args = {
+ ethFiat: 1050,
+ tokenFiat: 450,
+ tokenFiat1dAgo: 500,
+ ethFiat1dAgo: 1000,
+};
diff --git a/app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.styles.ts b/app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.styles.ts
new file mode 100644
index 00000000000..4852ce1d684
--- /dev/null
+++ b/app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.styles.ts
@@ -0,0 +1,20 @@
+// Third party dependencies.
+import { StyleSheet } from 'react-native';
+
+/**
+ * Style sheet function for AggregatedPercentage component.
+ *
+ * @param params Style sheet params.
+ * @param params.theme App theme from ThemeContext.
+ * @param params.vars Inputs that the style sheet depends on.
+ * @returns StyleSheet object.
+ */
+const styleSheet = () =>
+ StyleSheet.create({
+ wrapper: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ });
+
+export default styleSheet;
diff --git a/app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.test.tsx b/app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.test.tsx
new file mode 100644
index 00000000000..affec361321
--- /dev/null
+++ b/app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.test.tsx
@@ -0,0 +1,68 @@
+import React from 'react';
+import { render } from '@testing-library/react-native';
+import AggregatedPercentage from './AggregatedPercentage';
+import { mockTheme } from '../../../../util/theme';
+import { useSelector } from 'react-redux';
+import { selectCurrentCurrency } from '../../../../selectors/currencyRateController';
+
+jest.mock('react-redux', () => ({
+ ...jest.requireActual('react-redux'),
+ useSelector: jest.fn(),
+}));
+describe('AggregatedPercentage', () => {
+ beforeEach(() => {
+ (useSelector as jest.Mock).mockImplementation((selector) => {
+ if (selector === selectCurrentCurrency) return 'USD';
+ });
+ });
+ afterEach(() => {
+ (useSelector as jest.Mock).mockClear();
+ });
+ it('should render correctly', () => {
+ const { toJSON } = render(
+ ,
+ );
+ expect(toJSON()).toMatchSnapshot();
+ });
+
+ it('renders positive percentage change correctly', () => {
+ const { getByText } = render(
+ ,
+ );
+
+ expect(getByText('(+25.00%)')).toBeTruthy();
+ expect(getByText('+100 USD')).toBeTruthy();
+
+ expect(getByText('(+25.00%)').props.style).toMatchObject({
+ color: mockTheme.colors.success.default,
+ });
+ });
+
+ it('renders negative percentage change correctly', () => {
+ const { getByText } = render(
+ ,
+ );
+
+ expect(getByText('(-30.00%)')).toBeTruthy();
+ expect(getByText('-150 USD')).toBeTruthy();
+
+ expect(getByText('(-30.00%)').props.style).toMatchObject({
+ color: mockTheme.colors.error.default,
+ });
+ });
+});
diff --git a/app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.tsx b/app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.tsx
new file mode 100644
index 00000000000..3e0907f937b
--- /dev/null
+++ b/app/component-library/components-temp/Price/AggregatedPercentage/AggregatedPercentage.tsx
@@ -0,0 +1,76 @@
+import React from 'react';
+import Text, {
+ TextColor,
+ TextVariant,
+} from '../../../../component-library/components/Texts/Text';
+import { View } from 'react-native';
+import { renderFiat } from '../../../../util/number';
+import { useSelector } from 'react-redux';
+import { selectCurrentCurrency } from '../../../../selectors/currencyRateController';
+import styleSheet from './AggregatedPercentage.styles';
+import { useStyles } from '../../../hooks';
+
+const isValidAmount = (amount: number | null | undefined): boolean =>
+ amount !== null && amount !== undefined && !Number.isNaN(amount);
+
+const AggregatedPercentage = ({
+ ethFiat,
+ tokenFiat,
+ tokenFiat1dAgo,
+ ethFiat1dAgo,
+}: {
+ ethFiat: number;
+ tokenFiat: number;
+ tokenFiat1dAgo: number;
+ ethFiat1dAgo: number;
+}) => {
+ const { styles } = useStyles(styleSheet, {});
+
+ const currentCurrency = useSelector(selectCurrentCurrency);
+ const DECIMALS_TO_SHOW = 2;
+
+ const totalBalance = ethFiat + tokenFiat;
+ const totalBalance1dAgo = ethFiat1dAgo + tokenFiat1dAgo;
+
+ const amountChange = totalBalance - totalBalance1dAgo;
+
+ const percentageChange =
+ ((totalBalance - totalBalance1dAgo) / totalBalance1dAgo) * 100 || 0;
+
+ let percentageTextColor = TextColor.Default;
+
+ if (percentageChange === 0) {
+ percentageTextColor = TextColor.Default;
+ } else if (percentageChange > 0) {
+ percentageTextColor = TextColor.Success;
+ } else {
+ percentageTextColor = TextColor.Error;
+ }
+
+ const formattedPercentage = isValidAmount(percentageChange)
+ ? `(${(percentageChange as number) >= 0 ? '+' : ''}${(
+ percentageChange as number
+ ).toFixed(2)}%)`
+ : '';
+
+ const formattedValuePrice = isValidAmount(amountChange)
+ ? `${(amountChange as number) >= 0 ? '+' : ''}${renderFiat(
+ amountChange,
+ currentCurrency,
+ DECIMALS_TO_SHOW,
+ )} `
+ : '';
+
+ return (
+
+
+ {formattedValuePrice}
+
+
+ {formattedPercentage}
+
+
+ );
+};
+
+export default AggregatedPercentage;
diff --git a/app/component-library/components-temp/Price/AggregatedPercentage/__snapshots__/AggregatedPercentage.test.tsx.snap b/app/component-library/components-temp/Price/AggregatedPercentage/__snapshots__/AggregatedPercentage.test.tsx.snap
new file mode 100644
index 00000000000..7eea6a3bd9f
--- /dev/null
+++ b/app/component-library/components-temp/Price/AggregatedPercentage/__snapshots__/AggregatedPercentage.test.tsx.snap
@@ -0,0 +1,43 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`AggregatedPercentage should render correctly 1`] = `
+
+
+ +20 USD
+
+
+ (+11.11%)
+
+
+`;
diff --git a/app/component-library/components-temp/Price/AggregatedPercentage/index.ts b/app/component-library/components-temp/Price/AggregatedPercentage/index.ts
new file mode 100644
index 00000000000..3e7965d02fa
--- /dev/null
+++ b/app/component-library/components-temp/Price/AggregatedPercentage/index.ts
@@ -0,0 +1 @@
+export { default } from './AggregatedPercentage';
diff --git a/app/component-library/components-temp/Price/PercentageChange/PercentageChange.stories.tsx b/app/component-library/components-temp/Price/PercentageChange/PercentageChange.stories.tsx
new file mode 100644
index 00000000000..59612dcf9ba
--- /dev/null
+++ b/app/component-library/components-temp/Price/PercentageChange/PercentageChange.stories.tsx
@@ -0,0 +1,56 @@
+import React from 'react';
+import { Provider } from 'react-redux';
+import PercentageChange from './PercentageChange';
+import { createStore } from 'redux';
+import initialBackgroundState from '../../../../util/test/initial-background-state.json';
+
+const mockInitialState = {
+ wizard: {
+ step: 1,
+ },
+ engine: {
+ backgroundState: initialBackgroundState,
+ },
+};
+
+const rootReducer = (state = mockInitialState) => state;
+const store = createStore(rootReducer);
+
+export default {
+ title: 'Component Library / PercentageChange',
+ component: PercentageChange,
+ decorators: [
+ (Story) => (
+
+
+
+ ),
+ ],
+};
+
+const Template = (args) => ;
+
+export const Default = Template.bind({});
+Default.args = {
+ value: 0,
+};
+
+export const PositiveChange = Template.bind({});
+PositiveChange.args = {
+ value: 5.5,
+};
+
+export const NegativeChange = Template.bind({});
+NegativeChange.args = {
+ value: -3.75,
+};
+
+export const NoChange = Template.bind({});
+NoChange.args = {
+ value: 0,
+};
+
+export const InvalidValue = Template.bind({});
+InvalidValue.args = {
+ value: null,
+};
diff --git a/app/component-library/components-temp/Price/PercentageChange/PercentageChange.test.tsx b/app/component-library/components-temp/Price/PercentageChange/PercentageChange.test.tsx
new file mode 100644
index 00000000000..f01d3e7606f
--- /dev/null
+++ b/app/component-library/components-temp/Price/PercentageChange/PercentageChange.test.tsx
@@ -0,0 +1,40 @@
+import React from 'react';
+import { render } from '@testing-library/react-native';
+import PercentageChange from './PercentageChange';
+import { mockTheme } from '../../../../util/theme';
+
+describe('PercentageChange', () => {
+ it('should render correctly', () => {
+ const { toJSON } = render();
+ expect(toJSON()).toMatchSnapshot();
+ });
+ it('displays a positive value correctly', () => {
+ const { getByText } = render();
+ const positiveText = getByText('+5.50%');
+ expect(positiveText).toBeTruthy();
+ expect(positiveText.props.style).toMatchObject({
+ color: mockTheme.colors.success.default,
+ });
+ });
+
+ it('displays a negative value correctly', () => {
+ const { getByText } = render();
+ const negativeText = getByText('-3.25%');
+ expect(negativeText).toBeTruthy();
+ expect(negativeText.props.style).toMatchObject({
+ color: mockTheme.colors.error.default,
+ });
+ });
+
+ it('handles null value correctly', () => {
+ const { queryByText } = render();
+ expect(queryByText(/\+/)).toBeNull();
+ expect(queryByText(/-/)).toBeNull();
+ });
+
+ it('handles undefined value correctly', () => {
+ const { queryByText } = render();
+ expect(queryByText(/\+/)).toBeNull();
+ expect(queryByText(/-/)).toBeNull();
+ });
+});
diff --git a/app/component-library/components-temp/Price/PercentageChange/PercentageChange.tsx b/app/component-library/components-temp/Price/PercentageChange/PercentageChange.tsx
new file mode 100644
index 00000000000..206b905fc92
--- /dev/null
+++ b/app/component-library/components-temp/Price/PercentageChange/PercentageChange.tsx
@@ -0,0 +1,28 @@
+import React from 'react';
+import Text, {
+ TextColor,
+ TextVariant,
+} from '../../../../component-library/components/Texts/Text';
+import { View } from 'react-native';
+
+const PercentageChange = ({ value }: { value: number | null | undefined }) => {
+ const percentageColorText =
+ value && value >= 0 ? TextColor.Success : TextColor.Error;
+
+ const isValidAmount = (amount: number | null | undefined): boolean =>
+ amount !== null && amount !== undefined && !Number.isNaN(amount);
+
+ const formattedValue = isValidAmount(value)
+ ? `${(value as number) >= 0 ? '+' : ''}${(value as number).toFixed(2)}%`
+ : '';
+
+ return (
+
+
+ {formattedValue}
+
+
+ );
+};
+
+export default PercentageChange;
diff --git a/app/component-library/components-temp/Price/PercentageChange/__snapshots__/PercentageChange.test.tsx.snap b/app/component-library/components-temp/Price/PercentageChange/__snapshots__/PercentageChange.test.tsx.snap
new file mode 100644
index 00000000000..571dec70ebc
--- /dev/null
+++ b/app/component-library/components-temp/Price/PercentageChange/__snapshots__/PercentageChange.test.tsx.snap
@@ -0,0 +1,21 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`PercentageChange should render correctly 1`] = `
+
+
+ +5.50%
+
+
+`;
diff --git a/app/component-library/components-temp/Price/PercentageChange/index.ts b/app/component-library/components-temp/Price/PercentageChange/index.ts
new file mode 100644
index 00000000000..6a3f076bb2a
--- /dev/null
+++ b/app/component-library/components-temp/Price/PercentageChange/index.ts
@@ -0,0 +1 @@
+export { default } from './PercentageChange';
diff --git a/app/component-library/components/Navigation/TabBar/TabBar.stories.tsx b/app/component-library/components/Navigation/TabBar/TabBar.stories.tsx
index 50389c64ea7..55874e85b0a 100644
--- a/app/component-library/components/Navigation/TabBar/TabBar.stories.tsx
+++ b/app/component-library/components/Navigation/TabBar/TabBar.stories.tsx
@@ -7,7 +7,7 @@ import { createStore } from 'redux';
import { Provider } from 'react-redux';
// External dependencies.
-import initialBackgroundState from '../../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../../util/test/initial-root-state';
// Internal dependencies.
import { default as TabBarComponent } from './TabBar';
@@ -18,7 +18,7 @@ const mockInitialState = {
step: 1,
},
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
};
const rootReducer = (state = mockInitialState) => state;
diff --git a/app/component-library/components/Navigation/TabBar/TabBar.test.tsx b/app/component-library/components/Navigation/TabBar/TabBar.test.tsx
index e009d59d2bf..0d9ee3d09f9 100644
--- a/app/component-library/components/Navigation/TabBar/TabBar.test.tsx
+++ b/app/component-library/components/Navigation/TabBar/TabBar.test.tsx
@@ -5,7 +5,7 @@ import { ParamListBase, TabNavigationState } from '@react-navigation/native';
// External dependencies
import renderWithProvider from '../../../../util/test/renderWithProvider';
-import initialBackgroundState from '../../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../../util/test/initial-root-state';
// Internal dependencies
import TabBar from './TabBar';
@@ -22,7 +22,7 @@ const mockInitialState = {
step: 1,
},
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
};
diff --git a/app/component-library/components/Pickers/PickerAccount/PickerAccount.tsx b/app/component-library/components/Pickers/PickerAccount/PickerAccount.tsx
index 2f6ee293579..29fdaffa08f 100644
--- a/app/component-library/components/Pickers/PickerAccount/PickerAccount.tsx
+++ b/app/component-library/components/Pickers/PickerAccount/PickerAccount.tsx
@@ -2,7 +2,7 @@
// Third party dependencies.
import React, { forwardRef } from 'react';
-import { Platform, TouchableOpacity, View } from 'react-native';
+import { TouchableOpacity, View } from 'react-native';
// External dependencies.
import Avatar, { AvatarSize, AvatarVariant } from '../../Avatars/Avatar';
@@ -15,8 +15,7 @@ import { strings } from '../../../../../locales/i18n';
import PickerBase from '../PickerBase';
import { PickerAccountProps } from './PickerAccount.types';
import styleSheet from './PickerAccount.styles';
-import generateTestId from '../../../../../wdio/utils/generateTestId';
-import { WALLET_ACCOUNT_NAME_LABEL_TEXT } from '../../../../../wdio/screen-objects/testIDs/Screens/WalletView.testIds';
+import { WalletViewSelectorsIDs } from '../../../../../e2e/selectors/wallet/WalletView.selectors';
const PickerAccount: React.ForwardRefRenderFunction<
TouchableOpacity,
@@ -52,7 +51,7 @@ const PickerAccount: React.ForwardRefRenderFunction<
{accountName}
diff --git a/app/component-library/components/Pickers/PickerNetwork/PickerNetwork.tsx b/app/component-library/components/Pickers/PickerNetwork/PickerNetwork.tsx
index 586c53d09fb..9c4dd1f150a 100644
--- a/app/component-library/components/Pickers/PickerNetwork/PickerNetwork.tsx
+++ b/app/component-library/components/Pickers/PickerNetwork/PickerNetwork.tsx
@@ -2,7 +2,7 @@
// Third party dependencies.
import React from 'react';
-import { Platform, TouchableOpacity } from 'react-native';
+import { TouchableOpacity } from 'react-native';
// External dependencies.
import Avatar, { AvatarSize, AvatarVariant } from '../../Avatars/Avatar';
@@ -13,8 +13,7 @@ import { useStyles } from '../../../hooks';
// Internal dependencies.
import { PickerNetworkProps } from './PickerNetwork.types';
import stylesheet from './PickerNetwork.styles';
-import generateTestId from '../../../../../wdio/utils/generateTestId';
-import { NAVBAR_NETWORK_TEXT } from '../../../../../wdio/screen-objects/testIDs/Screens/WalletView.testIds';
+import { WalletViewSelectorsIDs } from '../../../../../e2e/selectors/wallet/WalletView.selectors';
import { PICKERNETWORK_ARROW_TESTID } from './PickerNetwork.constants';
const PickerNetwork = ({
@@ -38,7 +37,7 @@ const PickerNetwork = ({
style={styles.label}
numberOfLines={1}
variant={TextVariant.BodyMD}
- {...generateTestId(Platform, NAVBAR_NETWORK_TEXT)}
+ testID={WalletViewSelectorsIDs.NAVBAR_NETWORK_TEXT}
>
{label}
diff --git a/app/component-library/components/Toast/Toast.tsx b/app/component-library/components/Toast/Toast.tsx
index e4a37893279..b7916a32b93 100644
--- a/app/component-library/components/Toast/Toast.tsx
+++ b/app/component-library/components/Toast/Toast.tsx
@@ -10,7 +10,6 @@ import React, {
import {
Dimensions,
LayoutChangeEvent,
- Platform,
StyleProp,
View,
ViewStyle,
@@ -39,8 +38,7 @@ import {
ToastVariants,
} from './Toast.types';
import styles from './Toast.styles';
-import generateTestId from '../../../../wdio/utils/generateTestId';
-import { TOAST_ID } from '../../../../wdio/screen-objects/testIDs/Common.testIds';
+import { ToastSelectorsIDs } from '../../../../e2e/selectors/Modals/ToastModal.selectors';
import { ButtonProps } from '../Buttons/Button/Button.types';
const visibilityDuration = 2750;
@@ -210,7 +208,7 @@ const Toast = forwardRef((_, ref: React.ForwardedRef) => {
{renderAvatar()}
{renderLabel(labelOptions)}
{renderButtonLink(linkButtonOptions)}
diff --git a/app/components/Approvals/PermissionApproval/PermissionApproval.test.tsx b/app/components/Approvals/PermissionApproval/PermissionApproval.test.tsx
index 3333b2b3501..fd84b0f9915 100644
--- a/app/components/Approvals/PermissionApproval/PermissionApproval.test.tsx
+++ b/app/components/Approvals/PermissionApproval/PermissionApproval.test.tsx
@@ -6,7 +6,7 @@ import PermissionApproval from './PermissionApproval';
import { createAccountConnectNavDetails } from '../../Views/AccountConnect';
import { useSelector } from 'react-redux';
import { MetaMetricsEvents } from '../../../core/Analytics';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
import { render } from '@testing-library/react-native';
import { useMetrics } from '../../../components/hooks/useMetrics';
@@ -129,7 +129,7 @@ describe('PermissionApproval', () => {
mockSelectorState({
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
AccountTrackerController: {
accounts: {
1: 'testAccount',
diff --git a/app/components/Base/RemoteImage/index.js b/app/components/Base/RemoteImage/index.js
index 53aba49ae0d..f47269f60ce 100644
--- a/app/components/Base/RemoteImage/index.js
+++ b/app/components/Base/RemoteImage/index.js
@@ -10,6 +10,7 @@ import ComponentErrorBoundary from '../../UI/ComponentErrorBoundary';
import useIpfsGateway from '../../hooks/useIpfsGateway';
import { getFormattedIpfsUrl } from '@metamask/assets-controllers';
import Identicon from '../../UI/Identicon';
+import useSvgUriViewBox from '../../hooks/useSvgUriViewBox';
const createStyles = () =>
StyleSheet.create({
@@ -40,16 +41,19 @@ const RemoteImage = (props) => {
const onError = ({ nativeEvent: { error } }) => setError(error);
+ const isSVG =
+ source &&
+ source.uri &&
+ source.uri.match('.svg') &&
+ (isImageUrl || resolvedIpfsUrl);
+
+ const viewbox = useSvgUriViewBox(uri, isSVG);
+
if (error && props.address) {
return ;
}
- if (
- source &&
- source.uri &&
- source.uri.match('.svg') &&
- (isImageUrl || resolvedIpfsUrl)
- ) {
+ if (isSVG) {
const style = props.style || {};
if (source.__packager_asset && typeof style !== 'number') {
if (!style.width) {
@@ -66,7 +70,13 @@ const RemoteImage = (props) => {
componentLabel="RemoteImage-SVG"
>
-
+
);
diff --git a/app/components/Nav/App/index.js b/app/components/Nav/App/index.js
index 59ec7fb2b12..4b43ede6c99 100644
--- a/app/components/Nav/App/index.js
+++ b/app/components/Nav/App/index.js
@@ -6,7 +6,7 @@ import React, {
useState,
} from 'react';
import { CommonActions, NavigationContainer } from '@react-navigation/native';
-import { Animated, Linking } from 'react-native';
+import { Animated, Linking, View } from 'react-native';
import { createStackNavigator } from '@react-navigation/stack';
import Login from '../../Views/Login';
import QRScanner from '../../Views/QRScanner';
@@ -110,6 +110,9 @@ import DefaultSettings from '../../Views/OnboardingSuccess/DefaultSettings';
import BasicFunctionalityModal from '../../UI/BasicFunctionality/BasicFunctionalityModal/BasicFunctionalityModal';
import SmartTransactionsOptInModal from '../../Views/SmartTransactionsOptInModal/SmartTranactionsOptInModal';
import NFTAutoDetectionModal from '../../../../app/components/Views/NFTAutoDetectionModal/NFTAutoDetectionModal';
+///: BEGIN:ONLY_INCLUDE_IF(preinstalled-snaps,external-snaps)
+import { SnapsExecutionWebView } from '../../../lib/snaps';
+///: END:ONLY_INCLUDE_IF
const clearStackNavigatorOptions = {
headerShown: false,
@@ -770,6 +773,15 @@ const App = ({ userLoggedIn }) => {
// do not render unless a route is defined
(route && (
<>
+ {
+ ///: BEGIN:ONLY_INCLUDE_IF(preinstalled-snaps,external-snaps)
+ }
+
+
+
+ {
+ ///: END:ONLY_INCLUDE_IF
+ }
{
) : (
renderLoader()
)}
- {
- ///: BEGIN:ONLY_INCLUDE_IF(preinstalled-snaps,external-snaps)
- }
-
-
-
- {
- ///: END:ONLY_INCLUDE_IF
- }
diff --git a/app/components/UI/AccountApproval/__snapshots__/index.test.tsx.snap b/app/components/UI/AccountApproval/__snapshots__/index.test.tsx.snap
index 9864f17e99f..c5704972d10 100644
--- a/app/components/UI/AccountApproval/__snapshots__/index.test.tsx.snap
+++ b/app/components/UI/AccountApproval/__snapshots__/index.test.tsx.snap
@@ -334,7 +334,7 @@ exports[`AccountApproval should render correctly 1`] = `
}
}
>
- 0xC496...a756
+ Account 2
({
const mockInitialState = {
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
},
},
diff --git a/app/components/UI/AccountFromToInfoCard/AccountFromToInfoCard.test.tsx b/app/components/UI/AccountFromToInfoCard/AccountFromToInfoCard.test.tsx
index 5f9914e8d3e..eb71e64fec7 100644
--- a/app/components/UI/AccountFromToInfoCard/AccountFromToInfoCard.test.tsx
+++ b/app/components/UI/AccountFromToInfoCard/AccountFromToInfoCard.test.tsx
@@ -8,7 +8,7 @@ import { ENSCache } from '../../../util/ENSUtils';
import { Transaction } from './AccountFromToInfoCard.types';
import AccountFromToInfoCard from '.';
import Engine from '../../../core/Engine';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
import { createMockAccountsControllerState } from '../../../util/test/accountsControllerTestUtils';
const MOCK_ADDRESS_1 = '0xe64dD0AB5ad7e8C5F2bf6Ce75C34e187af8b920A';
@@ -23,7 +23,7 @@ const mockInitialState = {
settings: {},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
AccountTrackerController: {
accounts: {
[MOCK_ADDRESS_1]: {
@@ -39,19 +39,6 @@ const mockInitialState = {
'0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': '0x5',
},
},
- PreferencesController: {
- selectedAddress: MOCK_ADDRESS_1,
- identities: {
- [MOCK_ADDRESS_1]: {
- address: MOCK_ADDRESS_1,
- name: 'Account 1',
- },
- [MOCK_ADDRESS_2]: {
- address: MOCK_ADDRESS_2,
- name: 'Account 2',
- },
- },
- },
AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
},
},
diff --git a/app/components/UI/AccountFromToInfoCard/AccountFromToInfoCard.tsx b/app/components/UI/AccountFromToInfoCard/AccountFromToInfoCard.tsx
index f567bfee7b7..599042c9476 100644
--- a/app/components/UI/AccountFromToInfoCard/AccountFromToInfoCard.tsx
+++ b/app/components/UI/AccountFromToInfoCard/AccountFromToInfoCard.tsx
@@ -9,7 +9,6 @@ import {
selectChainId,
selectTicker,
} from '../../../selectors/networkController';
-import { selectIdentities } from '../../../selectors/preferencesController';
import { collectConfusables } from '../../../util/confusables';
import { decodeTransferData } from '../../../util/transactions';
import { doENSReverseLookup } from '../../../util/ENSUtils';
@@ -20,10 +19,13 @@ import useExistingAddress from '../../hooks/useExistingAddress';
import { AddressFrom, AddressTo } from '../AddressInputs';
import createStyles from './AccountFromToInfoCard.styles';
import { AccountFromToInfoCardProps } from './AccountFromToInfoCard.types';
+import { selectInternalAccounts } from '../../../selectors/accountsController';
+import { toLowerCaseEquals } from '../../../util/general';
+import { RootState } from '../../../reducers';
const AccountFromToInfoCard = (props: AccountFromToInfoCardProps) => {
const {
- identities,
+ internalAccounts,
chainId,
onPressFromAddressIcon,
ticker,
@@ -33,7 +35,6 @@ const AccountFromToInfoCard = (props: AccountFromToInfoCardProps) => {
const {
transaction: { from: rawFromAddress, data, to },
transactionTo,
- transactionToName,
transactionFromName,
selectedAsset,
ensRecipient,
@@ -56,50 +57,88 @@ const AccountFromToInfoCard = (props: AccountFromToInfoCardProps) => {
);
useEffect(() => {
- if (!fromAddress) {
- return;
- }
- if (transactionFromName) {
- setFromAccountName(transactionFromName);
- return;
- }
- (async () => {
+ const fetchFromAccountDetails = async () => {
+ if (!fromAddress) {
+ return;
+ }
+
+ if (transactionFromName) {
+ if (fromAccountName !== transactionFromName) {
+ setFromAccountName(transactionFromName);
+ }
+ return;
+ }
+
const fromEns = await doENSReverseLookup(fromAddress, chainId);
if (fromEns) {
- setFromAccountName(fromEns);
+ if (fromAccountName !== fromEns) {
+ setFromAccountName(fromEns);
+ }
} else {
- const { name: fromName } = identities[fromAddress];
- setFromAccountName(fromName);
+ const accountWithMatchingFromAddress = internalAccounts.find(
+ (account) => toLowerCaseEquals(account.address, fromAddress),
+ );
+
+ const newName = accountWithMatchingFromAddress
+ ? accountWithMatchingFromAddress.metadata.name
+ : fromAddress;
+
+ if (fromAccountName !== newName) {
+ setFromAccountName(newName);
+ }
}
- })();
- }, [fromAddress, identities, transactionFromName, chainId]);
+ };
+
+ fetchFromAccountDetails();
+ }, [
+ fromAddress,
+ transactionFromName,
+ chainId,
+ internalAccounts,
+ fromAccountName,
+ ]);
useEffect(() => {
- if (existingToAddress) {
- setToAccountName(existingToAddress?.name);
- return;
- }
- (async () => {
+ const fetchAccountDetails = async () => {
+ if (existingToAddress) {
+ if (toAccountName !== existingToAddress.name) {
+ setToAccountName(existingToAddress.name);
+ }
+ return;
+ }
+
const toEns = await doENSReverseLookup(toAddress, chainId);
if (toEns) {
- setToAccountName(toEns);
- } else if (identities[toAddress]) {
- const { name: toName } = identities[toAddress];
- setToAccountName(toName);
+ if (toAccountName !== toEns) {
+ setToAccountName(toEns);
+ }
+ } else {
+ const accountWithMatchingToAddress = internalAccounts.find((account) =>
+ toLowerCaseEquals(account.address, toAddress),
+ );
+
+ const newName = accountWithMatchingToAddress
+ ? accountWithMatchingToAddress.metadata.name
+ : toAddress;
+
+ if (toAccountName !== newName) {
+ setToAccountName(newName);
+ }
}
- })();
- }, [existingToAddress, identities, chainId, toAddress, transactionToName]);
+ };
+
+ fetchAccountDetails();
+ }, [existingToAddress, chainId, toAddress, internalAccounts, toAccountName]);
useEffect(() => {
- const accountNames =
- (identities &&
- Object.keys(identities).map((hash) => identities[hash].name)) ||
- [];
+ const accountNames = internalAccounts.map(
+ (account) => account.metadata.name,
+ );
const isOwnAccount = ensRecipient && accountNames.includes(ensRecipient);
if (ensRecipient && !isOwnAccount) {
setConfusableCollection(collectConfusables(ensRecipient));
}
- }, [identities, ensRecipient]);
+ }, [internalAccounts, ensRecipient]);
useEffect(() => {
let toAddr;
@@ -172,10 +211,8 @@ const AccountFromToInfoCard = (props: AccountFromToInfoCardProps) => {
);
};
-// TODO: Replace "any" with type
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-const mapStateToProps = (state: any) => ({
- identities: selectIdentities(state),
+const mapStateToProps = (state: RootState) => ({
+ internalAccounts: selectInternalAccounts(state),
chainId: selectChainId(state),
ticker: selectTicker(state),
});
diff --git a/app/components/UI/AccountFromToInfoCard/AccountFromToInfoCard.types.tsx b/app/components/UI/AccountFromToInfoCard/AccountFromToInfoCard.types.tsx
index ece567c7bdd..84690a6c732 100644
--- a/app/components/UI/AccountFromToInfoCard/AccountFromToInfoCard.types.tsx
+++ b/app/components/UI/AccountFromToInfoCard/AccountFromToInfoCard.types.tsx
@@ -1,9 +1,4 @@
-interface Identity {
- address: string;
- name: string;
-}
-
-type Identities = Record;
+import { InternalAccount } from '@metamask/keyring-api';
interface SelectedAsset {
isETH: boolean;
@@ -26,7 +21,7 @@ export interface Transaction {
}
export interface AccountFromToInfoCardProps {
- identities: Identities;
+ internalAccounts: InternalAccount[];
chainId: string;
onPressFromAddressIcon?: () => void;
ticker?: string;
diff --git a/app/components/UI/AccountInfoCard/__snapshots__/index.test.tsx.snap b/app/components/UI/AccountInfoCard/__snapshots__/index.test.tsx.snap
index b8b3d0ae551..6a4a79370c7 100644
--- a/app/components/UI/AccountInfoCard/__snapshots__/index.test.tsx.snap
+++ b/app/components/UI/AccountInfoCard/__snapshots__/index.test.tsx.snap
@@ -232,7 +232,7 @@ exports[`AccountInfoCard should match snapshot 1`] = `
}
}
>
- 0xC495...D272
+ Account 1
StyleSheet.create({
@@ -111,9 +111,9 @@ class AccountInfoCard extends PureComponent {
*/
accounts: PropTypes.object,
/**
- * List of accounts from the PreferencesController
+ * List of accounts from the AccountsController
*/
- identities: PropTypes.object,
+ internalAccounts: PropTypes.array,
/**
* A number that specifies the ETH/USD conversion rate
*/
@@ -142,7 +142,7 @@ class AccountInfoCard extends PureComponent {
render() {
const {
accounts,
- identities,
+ internalAccounts,
conversionRate,
currentCurrency,
operation,
@@ -162,7 +162,7 @@ class AccountInfoCard extends PureComponent {
? hexToBN(accounts[fromAddress].balance)
: 0;
const balance = `${renderFromWei(weiBalance)} ${getTicker(ticker)}`;
- const accountLabel = renderAccountName(fromAddress, identities);
+ const accountLabel = renderAccountName(fromAddress, internalAccounts);
const address = renderShortAddress(fromAddress);
const dollarBalance = showFiatBalance
? weiToFiat(weiBalance, conversionRate, currentCurrency, 2)?.toUpperCase()
@@ -248,7 +248,7 @@ class AccountInfoCard extends PureComponent {
const mapStateToProps = (state) => ({
accounts: selectAccounts(state),
- identities: selectIdentities(state),
+ internalAccounts: selectInternalAccounts(state),
conversionRate: selectConversionRate(state),
currentCurrency: selectCurrentCurrency(state),
ticker: selectTicker(state),
diff --git a/app/components/UI/AccountInfoCard/index.test.tsx b/app/components/UI/AccountInfoCard/index.test.tsx
index d8500ab9d38..2462c41d648 100644
--- a/app/components/UI/AccountInfoCard/index.test.tsx
+++ b/app/components/UI/AccountInfoCard/index.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import AccountInfoCard from './';
import renderWithProvider from '../../../util/test/renderWithProvider';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
import {
MOCK_ACCOUNTS_CONTROLLER_STATE,
MOCK_ADDRESS_1,
@@ -27,7 +27,7 @@ const mockInitialState = {
},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
AccountTrackerController: {
accounts: {
[MOCK_ADDRESS_1]: {
diff --git a/app/components/UI/AccountOverview/index.js b/app/components/UI/AccountOverview/index.js
index c65706e35a0..b844d7ac534 100644
--- a/app/components/UI/AccountOverview/index.js
+++ b/app/components/UI/AccountOverview/index.js
@@ -2,7 +2,6 @@ import PropTypes from 'prop-types';
import React, { PureComponent } from 'react';
import {
InteractionManager,
- Platform,
ScrollView,
StyleSheet,
TextInput,
@@ -11,12 +10,7 @@ import {
} from 'react-native';
import { connect } from 'react-redux';
import { strings } from '../../../../locales/i18n';
-import {
- WALLET_ACCOUNT_ICON,
- WALLET_ACCOUNT_NAME_LABEL_INPUT,
- WALLET_ACCOUNT_NAME_LABEL_TEXT,
-} from '../../../../wdio/screen-objects/testIDs/Screens/WalletView.testIds';
-import generateTestId from '../../../../wdio/utils/generateTestId';
+import { WalletViewSelectorsIDs } from '../../../../e2e/selectors/wallet/WalletView.selectors';
import { showAlert } from '../../../actions/alert';
import { toggleReceiveModal } from '../../../actions/modals';
import { newAssetTransaction } from '../../../actions/transaction';
@@ -41,14 +35,17 @@ import AppConstants from '../../../core/AppConstants';
import Engine from '../../../core/Engine';
import { selectChainId } from '../../../selectors/networkController';
import { selectCurrentCurrency } from '../../../selectors/currencyRateController';
-import { selectIdentities } from '../../../selectors/preferencesController';
-import { selectSelectedInternalAccountChecksummedAddress } from '../../../selectors/accountsController';
+import {
+ selectInternalAccounts,
+ selectSelectedInternalAccountChecksummedAddress,
+} from '../../../selectors/accountsController';
import { createAccountSelectorNavDetails } from '../../Views/AccountSelector';
import Text, {
TextVariant,
} from '../../../component-library/components/Texts/Text';
import { withMetricsAwareness } from '../../../components/hooks/useMetrics';
import { isPortfolioUrl } from '../../../util/url';
+import { toLowerCaseEquals } from '../../../util/general';
const createStyles = (colors) =>
StyleSheet.create({
@@ -157,18 +154,14 @@ class AccountOverview extends PureComponent {
*/
selectedAddress: PropTypes.string,
/**
- /* Identities object required to get account name
+ /* InternalAccounts object required to get account name
*/
- identities: PropTypes.object,
+ internalAccounts: PropTypes.object,
/**
* Object that represents the selected account
*/
account: PropTypes.object,
/**
- /* Selected currency
- */
- currentCurrency: PropTypes.string,
- /**
/* Triggers global alert
*/
showAlert: PropTypes.func,
@@ -184,19 +177,11 @@ class AccountOverview extends PureComponent {
* Prompts protect wallet modal
*/
protectWalletModalVisible: PropTypes.func,
- /**
- * Start transaction with asset
- */
- newAssetTransaction: PropTypes.func,
/**
/* navigation object required to access the props
/* passed by the parent component
*/
navigation: PropTypes.object,
- /**
- * Action that toggles the receive modal
- */
- toggleReceiveModal: PropTypes.func,
/**
* The chain ID for the current selected network
*/
@@ -234,8 +219,8 @@ class AccountOverview extends PureComponent {
input = React.createRef();
componentDidMount = () => {
- const { identities, selectedAddress, onRef } = this.props;
- const accountLabel = renderAccountName(selectedAddress, identities);
+ const { internalAccounts, selectedAddress, onRef } = this.props;
+ const accountLabel = renderAccountName(selectedAddress, internalAccounts);
this.setState({ accountLabel });
onRef && onRef(this);
InteractionManager.runAfterInteractions(() => {
@@ -259,16 +244,18 @@ class AccountOverview extends PureComponent {
}
setAccountLabel = () => {
- const { selectedAddress, identities } = this.props;
+ const { selectedAddress, internalAccounts } = this.props;
const { accountLabel } = this.state;
- const lastAccountLabel = identities[selectedAddress].name;
+ const accountWithMatchingToAddress = internalAccounts.find((account) =>
+ toLowerCaseEquals(account.address, selectedAddress),
+ );
Engine.setAccountLabel(
selectedAddress,
this.isAccountLabelDefined(accountLabel)
? accountLabel
- : lastAccountLabel,
+ : accountWithMatchingToAddress.metadata.name,
);
this.setState({ accountLabelEditable: false });
};
@@ -278,8 +265,8 @@ class AccountOverview extends PureComponent {
};
setAccountLabelEditable = () => {
- const { identities, selectedAddress } = this.props;
- const accountLabel = renderAccountName(selectedAddress, identities);
+ const { internalAccounts, selectedAddress } = this.props;
+ const accountLabel = renderAccountName(selectedAddress, internalAccounts);
this.setState({ accountLabelEditable: true, accountLabel });
setTimeout(() => {
this.input && this.input.current && this.input.current.focus();
@@ -287,8 +274,8 @@ class AccountOverview extends PureComponent {
};
cancelAccountLabelEdition = () => {
- const { identities, selectedAddress } = this.props;
- const accountLabel = renderAccountName(selectedAddress, identities);
+ const { internalAccounts, selectedAddress } = this.props;
+ const accountLabel = renderAccountName(selectedAddress, internalAccounts);
this.setState({ accountLabelEditable: false, accountLabel });
};
@@ -368,7 +355,7 @@ class AccountOverview extends PureComponent {
style={styles.identiconBorder}
disabled={onboardingWizard}
onPress={this.openAccountSelector}
- {...generateTestId(Platform, WALLET_ACCOUNT_ICON)}
+ testID={WalletViewSelectorsIDs.ACCOUNT_ICON}
>
{isDefaultAccountName(name) && ens ? ens : name}
@@ -461,7 +445,7 @@ class AccountOverview extends PureComponent {
const mapStateToProps = (state) => ({
selectedAddress: selectSelectedInternalAccountChecksummedAddress(state),
- identities: selectIdentities(state),
+ internalAccounts: selectInternalAccounts(state),
currentCurrency: selectCurrentCurrency(state),
chainId: selectChainId(state),
browserTabs: state.browser.tabs,
diff --git a/app/components/UI/AccountOverview/index.test.tsx b/app/components/UI/AccountOverview/index.test.tsx
index 90d3b464d96..303d3fe177d 100644
--- a/app/components/UI/AccountOverview/index.test.tsx
+++ b/app/components/UI/AccountOverview/index.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import renderWithProvider from '../../../util/test/renderWithProvider';
import AccountOverview from './';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
import Engine from '../../../core/Engine';
import {
@@ -33,7 +33,7 @@ const mockInitialState = {
settings: {},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
PreferencesController: {
selectedAddress: MOCK_ADDRESS_1,
},
diff --git a/app/components/UI/AccountRightButton/index.test.tsx b/app/components/UI/AccountRightButton/index.test.tsx
index 8d8b409c78f..ce5b1f12c23 100644
--- a/app/components/UI/AccountRightButton/index.test.tsx
+++ b/app/components/UI/AccountRightButton/index.test.tsx
@@ -1,12 +1,12 @@
import { renderScreen } from '../../../util/test/renderWithProvider';
import AccountRightButton from './';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
const mockInitialState = {
settings: {},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
NetworkController: {
providerConfig: {
chainId: 0x1,
diff --git a/app/components/UI/AccountSelectorList/AccountSelector.test.tsx b/app/components/UI/AccountSelectorList/AccountSelector.test.tsx
index 8961cd92278..5b26df8e705 100644
--- a/app/components/UI/AccountSelectorList/AccountSelector.test.tsx
+++ b/app/components/UI/AccountSelectorList/AccountSelector.test.tsx
@@ -6,7 +6,7 @@ import AccountSelectorList from './AccountSelectorList';
import { useAccounts } from '../../../components/hooks/useAccounts';
import { View } from 'react-native';
import { ACCOUNT_BALANCE_BY_ADDRESS_TEST_ID } from '../../../../wdio/screen-objects/testIDs/Components/AccountListComponent.testIds';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
import { regex } from '../../../../app/util/regex';
import { createMockAccountsControllerState } from '../../../util/test/accountsControllerTestUtils';
@@ -29,7 +29,7 @@ jest.mock('../../../util/address', () => {
const initialState = {
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
NetworkController: {
network: '1',
providerConfig: {
@@ -48,16 +48,6 @@ const initialState = {
PreferencesController: {
isMultiAccountBalancesEnabled: true,
selectedAddress: BUSINESS_ACCOUNT,
- identities: {
- [BUSINESS_ACCOUNT]: {
- address: BUSINESS_ACCOUNT,
- name: 'Business Account',
- },
- [PERSONAL_ACCOUNT]: {
- address: PERSONAL_ACCOUNT,
- name: 'Personal Account',
- },
- },
},
CurrencyRateController: {
currentCurrency: 'usd',
@@ -120,12 +110,12 @@ describe('AccountSelectorList', () => {
onRemoveImportedAccount.mockClear();
});
- it('should render correctly', async () => {
+ it('renders correctly', async () => {
const { toJSON } = renderComponent(initialState);
await waitFor(() => expect(toJSON()).toMatchSnapshot());
});
- it('should render all accounts with balances', async () => {
+ it('renders all accounts with balances', async () => {
const { queryByTestId, getAllByTestId, toJSON } =
renderComponent(initialState);
@@ -186,7 +176,7 @@ describe('AccountSelectorList', () => {
});
});
- it('should render all accounts with right acessory', async () => {
+ it('renders all accounts with right accessory', async () => {
const { getAllByTestId, toJSON } = renderComponent(
initialState,
AccountSelectorListRightAccessoryUseAccounts,
@@ -199,4 +189,13 @@ describe('AccountSelectorList', () => {
expect(toJSON()).toMatchSnapshot();
});
});
+ it('renders correct account names', async () => {
+ const { getAllByTestId } = renderComponent(initialState);
+
+ await waitFor(() => {
+ const accountNameItems = getAllByTestId('cellbase-avatar-title');
+ expect(within(accountNameItems[0]).getByText('Account 1')).toBeDefined();
+ expect(within(accountNameItems[1]).getByText('Account 2')).toBeDefined();
+ });
+ });
});
diff --git a/app/components/UI/AccountSelectorList/__snapshots__/AccountSelector.test.tsx.snap b/app/components/UI/AccountSelectorList/__snapshots__/AccountSelector.test.tsx.snap
index 8b7c6c08b72..1e4cbf6b45b 100644
--- a/app/components/UI/AccountSelectorList/__snapshots__/AccountSelector.test.tsx.snap
+++ b/app/components/UI/AccountSelectorList/__snapshots__/AccountSelector.test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`AccountSelectorList should render all accounts but only the balance for selected account 1`] = `
+exports[`AccountSelectorList renders all accounts with balances 1`] = `
-
+ >
+
+
+
+
+
+
+
+
-
-
-
-
- Account 2
-
-
- 0xd018...78E7
-
-
-
-
-
-
-
-
-`;
-
-exports[`AccountSelectorList should render all accounts with balances 1`] = `
-
+
+
+
+
+
+
+
+
+
+
+ Account 2
+
+
+ 0xd018...78E7
+
+
+
+
+
+ $6400.00
+2 ETH
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`AccountSelectorList renders all accounts with right accessory 1`] = `
+
-
- $3200.00
-1 ETH
-
+ 0xC4955C0d639D99699Bfd7Ec54d9FaFEe40e4D272 - Account 1
+
+
+
+
-
-
-
-
-
-
-
-
- $6400.00
-2 ETH
-
+ 0xd018538C87232FF95acbCe4870629b75640a78E7 - Account 2
@@ -937,7 +1139,7 @@ exports[`AccountSelectorList should render all accounts with balances 1`] = `
`;
-exports[`AccountSelectorList should render all accounts with right acessory 1`] = `
+exports[`AccountSelectorList renders correctly 1`] = `
- 0xC4955C0d639D99699Bfd7Ec54d9FaFEe40e4D272 - Account 1
+
+ $3200.00
+1 ETH
+
+
+
+
- 0xd018538C87232FF95acbCe4870629b75640a78E7 - Account 2
+
+ $6400.00
+2 ETH
+
@@ -1473,7 +1742,7 @@ exports[`AccountSelectorList should render all accounts with right acessory 1`]
`;
-exports[`AccountSelectorList should render correctly 1`] = `
+exports[`AccountSelectorList should render all accounts but only the balance for selected account 1`] = `
-
-
-
-
-
-
-
-
-
+ }
+ />
-
-
-
-
-
-
-
-
-
+ }
+ />
-
-
-
- $6400.00
-2 ETH
-
-
-
diff --git a/app/components/UI/AddCustomCollectible/index.test.tsx b/app/components/UI/AddCustomCollectible/index.test.tsx
index 3ca9f3d80e2..33afc2910a9 100644
--- a/app/components/UI/AddCustomCollectible/index.test.tsx
+++ b/app/components/UI/AddCustomCollectible/index.test.tsx
@@ -3,15 +3,11 @@ import { shallow } from 'enzyme';
import AddCustomCollectible from './';
import configureMockStore from 'redux-mock-store';
import { Provider } from 'react-redux';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import initialRootState from '../../../util/test/initial-root-state';
const mockStore = configureMockStore();
-const initialState = {
- engine: {
- backgroundState: initialBackgroundState,
- },
-};
-const store = mockStore(initialState);
+
+const store = mockStore(initialRootState);
jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
diff --git a/app/components/UI/AddToAddressBookWrapper/AddToAddressBookWrapper.test.tsx b/app/components/UI/AddToAddressBookWrapper/AddToAddressBookWrapper.test.tsx
index b2ce68ace60..00ad7df7a8c 100644
--- a/app/components/UI/AddToAddressBookWrapper/AddToAddressBookWrapper.test.tsx
+++ b/app/components/UI/AddToAddressBookWrapper/AddToAddressBookWrapper.test.tsx
@@ -5,36 +5,33 @@ import { Text } from 'react-native';
import AddToAddressBookWrapper from './AddToAddressBookWrapper';
import { AddAddressModalSelectorsIDs } from '../../../../e2e/selectors/Modals/AddAddressModal.selectors';
import renderWithProvider from '../../../util/test/renderWithProvider';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
+import { createMockAccountsControllerState } from '../../../util/test/accountsControllerTestUtils';
+
+const MOCK_ADDRESS_1 = '0x0';
+const MOCK_ADDRESS_2 = '0x1';
+
+const MOCK_ACCOUNTS_CONTROLLER_STATE = createMockAccountsControllerState([
+ MOCK_ADDRESS_1,
+ MOCK_ADDRESS_2,
+]);
const initialState = {
settings: {},
engine: {
backgroundState: {
- ...initialBackgroundState,
- PreferencesController: {
- selectedAddress: '0x0',
- identities: {
- '0x0': {
- address: '0x0',
- name: 'Account 1',
- },
- '0x1': {
- address: '0x1',
- name: 'Account 2',
- },
- },
- },
+ ...backgroundState,
AddressBookController: {
addressBook: {
- '0x1': {
- '0x1': {
- address: '0x1',
+ [MOCK_ADDRESS_2]: {
+ [MOCK_ADDRESS_2]: {
+ address: MOCK_ADDRESS_2,
name: 'Account 2',
},
},
},
},
+ AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
},
},
};
@@ -66,7 +63,7 @@ describe('AddToAddressBookWrapper', () => {
});
it('should not render touchable wrapper if address is already saved', async () => {
const { queryByText } = renderWithProvider(
-
+
DUMMY
,
{ state: initialState },
@@ -78,7 +75,7 @@ describe('AddToAddressBookWrapper', () => {
});
it('should return null if address is already saved and defaultNull is true', async () => {
const { queryByText } = renderWithProvider(
-
+
DUMMY
,
{ state: initialState },
diff --git a/app/components/UI/AddressCopy/AddressCopy.tsx b/app/components/UI/AddressCopy/AddressCopy.tsx
index 80af16dcbeb..17f8dbd1550 100644
--- a/app/components/UI/AddressCopy/AddressCopy.tsx
+++ b/app/components/UI/AddressCopy/AddressCopy.tsx
@@ -18,17 +18,17 @@ import ClipboardManager from '../../../core/ClipboardManager';
import { showAlert } from '../../../actions/alert';
import { protectWalletModalVisible } from '../../../actions/user';
import { strings } from '../../../../locales/i18n';
-import { Platform, View } from 'react-native';
+import { View } from 'react-native';
import { MetaMetricsEvents } from '../../../core/Analytics';
import { useStyles } from '../../../component-library/hooks';
-import generateTestId from '../../../../wdio/utils/generateTestId';
+import { WalletViewSelectorsIDs } from '../../../../e2e/selectors/wallet/WalletView.selectors';
// Internal dependencies
import styleSheet from './AddressCopy.styles';
import { AddressCopyProps } from './AddressCopy.types';
-import { selectIdentities } from '../../../selectors/preferencesController';
-import { selectSelectedInternalAccountChecksummedAddress } from '../../../selectors/accountsController';
+import { selectSelectedInternalAccount } from '../../../selectors/accountsController';
import { useMetrics } from '../../../components/hooks/useMetrics';
+import { toChecksumHexAddress } from '@metamask/controller-utils';
const AddressCopy = ({ formatAddressType = 'full' }: AddressCopyProps) => {
const { styles } = useStyles(styleSheet, {});
@@ -49,22 +49,14 @@ const AddressCopy = ({ formatAddressType = 'full' }: AddressCopyProps) => {
/**
* A string that represents the selected address
*/
- const selectedAddress = useSelector(
- selectSelectedInternalAccountChecksummedAddress,
- );
-
- /**
- * An object containing each identity in the format address => account
- */
- const identities = useSelector(selectIdentities);
-
- const account = {
- ...identities[selectedAddress],
- address: selectedAddress,
- };
+ const selectedInternalAccount = useSelector(selectSelectedInternalAccount);
const copyAccountToClipboard = async () => {
- await ClipboardManager.setString(selectedAddress);
+ if (selectedInternalAccount?.address) {
+ await ClipboardManager.setString(
+ toChecksumHexAddress(selectedInternalAccount.address),
+ );
+ }
handleShowAlert({
isVisible: true,
autodismiss: 1500,
@@ -83,14 +75,16 @@ const AddressCopy = ({ formatAddressType = 'full' }: AddressCopyProps) => {
- {formatAddress(account.address, formatAddressType)}
+ {selectedInternalAccount
+ ? formatAddress(selectedInternalAccount.address, formatAddressType)
+ : null}
{
- {renderSlightlyLongAddress(toSelectedAddress, 4, 9)}
+ {toSelectedAddress
+ ? renderSlightlyLongAddress(toSelectedAddress, 4, 9)
+ : ''}
diff --git a/app/components/UI/AddressInputs/index.test.jsx b/app/components/UI/AddressInputs/index.test.jsx
index cc3a6d2bfc5..73a80cda421 100644
--- a/app/components/UI/AddressInputs/index.test.jsx
+++ b/app/components/UI/AddressInputs/index.test.jsx
@@ -3,26 +3,15 @@ import { fireEvent } from '@testing-library/react-native';
import renderWithProvider from '../../../util/test/renderWithProvider';
import { AddressFrom, AddressTo } from './index';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
import { AddAddressModalSelectorsIDs } from '../../../../e2e/selectors/Modals/AddAddressModal.selectors';
const initialState = {
settings: {},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
PreferencesController: {
- selectedAddress: '0xe64dD0AB5ad7e8C5F2bf6Ce75C34e187af8b920A',
- identities: {
- '0xe64dD0AB5ad7e8C5F2bf6Ce75C34e187af8b920A': {
- address: '0xe64dD0AB5ad7e8C5F2bf6Ce75C34e187af8b920A',
- name: 'Account 1',
- },
- '0x519d2CE57898513F676a5C3b66496c3C394c9CC7': {
- address: '0x519d2CE57898513F676a5C3b66496c3C394c9CC7',
- name: 'Account 2',
- },
- },
useTokenDetection: false,
},
AddressBookController: {
diff --git a/app/components/UI/AssetElement/__snapshots__/index.test.tsx.snap b/app/components/UI/AssetElement/__snapshots__/index.test.tsx.snap
index 5704e5960e9..99fc71bcbfc 100644
--- a/app/components/UI/AssetElement/__snapshots__/index.test.tsx.snap
+++ b/app/components/UI/AssetElement/__snapshots__/index.test.tsx.snap
@@ -14,5 +14,15 @@ exports[`AssetElement should render correctly 1`] = `
}
}
testID="asset-DAI"
-/>
+>
+
+
`;
diff --git a/app/components/UI/AssetElement/index.tsx b/app/components/UI/AssetElement/index.tsx
index e95c3a3a1f6..fdf638bb125 100644
--- a/app/components/UI/AssetElement/index.tsx
+++ b/app/components/UI/AssetElement/index.tsx
@@ -1,6 +1,6 @@
/* eslint-disable react/prop-types */
import React from 'react';
-import { TouchableOpacity, StyleSheet, Platform } from 'react-native';
+import { TouchableOpacity, StyleSheet, Platform, View } from 'react-native';
import Text, {
TextVariant,
} from '../../../component-library/components/Texts/Text';
@@ -12,15 +12,20 @@ import {
TOKEN_BALANCE_LOADING,
TOKEN_RATE_UNDEFINED,
} from '../Tokens/constants';
+import { Colors } from '../../../util/theme/models';
+import { fontStyles } from '../../../styles/common';
+import { useTheme } from '../../../util/theme';
+
interface AssetElementProps {
children?: React.ReactNode;
asset: TokenI;
onPress?: (asset: TokenI) => void;
onLongPress?: ((asset: TokenI) => void) | null;
balance?: string;
+ mainBalance?: string | null;
}
-const createStyles = () =>
+const createStyles = (colors: Colors) =>
StyleSheet.create({
itemWrapper: {
flex: 1,
@@ -32,6 +37,7 @@ const createStyles = () =>
arrow: {
flex: 1,
alignSelf: 'flex-end',
+ alignItems: 'flex-end',
},
arrowIcon: {
marginTop: 16,
@@ -39,6 +45,12 @@ const createStyles = () =>
skeleton: {
width: 50,
},
+ balanceFiat: {
+ color: colors.text.alternative,
+ paddingHorizontal: 0,
+ ...fontStyles.normal,
+ textTransform: 'uppercase',
+ },
});
/**
@@ -48,10 +60,12 @@ const AssetElement: React.FC = ({
children,
balance,
asset,
+ mainBalance = null,
onPress,
onLongPress,
}) => {
- const styles = createStyles();
+ const { colors } = useTheme();
+ const styles = createStyles(colors);
const handleOnPress = () => {
onPress?.(asset);
@@ -70,21 +84,32 @@ const AssetElement: React.FC = ({
>
{children}
- {balance && (
-
- {balance === TOKEN_BALANCE_LOADING ? (
-
- ) : (
- balance
- )}
-
- )}
+
+ {balance && (
+
+ {balance === TOKEN_BALANCE_LOADING ? (
+
+ ) : (
+ balance
+ )}
+
+ )}
+ {mainBalance ? (
+
+ {mainBalance === TOKEN_BALANCE_LOADING ? (
+
+ ) : (
+ mainBalance
+ )}
+
+ ) : null}
+
);
};
diff --git a/app/components/UI/AssetIcon/index.test.tsx b/app/components/UI/AssetIcon/index.test.tsx
index fd256ddb41e..626428cd36a 100644
--- a/app/components/UI/AssetIcon/index.test.tsx
+++ b/app/components/UI/AssetIcon/index.test.tsx
@@ -2,21 +2,14 @@ import React from 'react';
import renderWithProvider from '../../../util/test/renderWithProvider';
import AssetIcon from './';
const sampleLogo = 'https://s3.amazonaws.com/airswap-token-images/WBTC.png';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
const mockInitialState = {
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
PreferencesController: {
featureFlags: {},
- identities: {
- '0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3': {
- address: '0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3',
- name: 'Account 1',
- importTime: 1684232000456,
- },
- },
ipfsGateway: 'https://cloudflare-ipfs.com/ipfs/',
lostIdentities: {},
selectedAddress: '0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3',
@@ -34,13 +27,6 @@ const mockInitialState = {
_W: {
featureFlags: {},
frequentRpcList: [],
- identities: {
- '0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3': {
- address: '0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3',
- name: 'Account 1',
- importTime: 1684232000456,
- },
- },
ipfsGateway: 'https://cloudflare-ipfs.com/ipfs/',
lostIdentities: {},
selectedAddress: '0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3',
diff --git a/app/components/UI/AssetSearch/index.test.tsx b/app/components/UI/AssetSearch/index.test.tsx
index e58041c7314..9838088af3b 100644
--- a/app/components/UI/AssetSearch/index.test.tsx
+++ b/app/components/UI/AssetSearch/index.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import renderWithProvider from '../../../util/test/renderWithProvider';
import AssetSearch from './';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
import Engine from '../../../core/Engine';
const mockedEngine = Engine;
@@ -48,7 +48,7 @@ jest.mock('../../../core/Engine.ts', () => ({
const initialState = {
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
};
diff --git a/app/components/UI/CollectibleContractInformation/index.test.tsx b/app/components/UI/CollectibleContractInformation/index.test.tsx
index 526e2d4159b..2629113abd8 100644
--- a/app/components/UI/CollectibleContractInformation/index.test.tsx
+++ b/app/components/UI/CollectibleContractInformation/index.test.tsx
@@ -3,12 +3,12 @@ import { shallow } from 'enzyme';
import CollectibleContractInformation from './';
import configureMockStore from 'redux-mock-store';
import { Provider } from 'react-redux';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
const mockStore = configureMockStore();
const initialState = {
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
};
const store = mockStore(initialState);
diff --git a/app/components/UI/CollectibleContractOverview/index.test.tsx b/app/components/UI/CollectibleContractOverview/index.test.tsx
index df1b0e37866..e1e358db0ad 100644
--- a/app/components/UI/CollectibleContractOverview/index.test.tsx
+++ b/app/components/UI/CollectibleContractOverview/index.test.tsx
@@ -3,12 +3,12 @@ import CollectibleContractOverview from './';
import configureMockStore from 'redux-mock-store';
import { shallow } from 'enzyme';
import { Provider } from 'react-redux';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
const mockStore = configureMockStore();
const initialState = {
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
};
const store = mockStore(initialState);
diff --git a/app/components/UI/CollectibleContracts/index.js b/app/components/UI/CollectibleContracts/index.js
index 866d8b96d7b..d03c8bce4d3 100644
--- a/app/components/UI/CollectibleContracts/index.js
+++ b/app/components/UI/CollectibleContracts/index.js
@@ -5,7 +5,6 @@ import {
StyleSheet,
View,
Image,
- Platform,
FlatList,
RefreshControl,
ActivityIndicator,
@@ -30,7 +29,6 @@ import { compareTokenIds } from '../../../util/tokens';
import CollectibleDetectionModal from '../CollectibleDetectionModal';
import { useTheme } from '../../../util/theme';
import { MAINNET } from '../../../constants/network';
-import generateTestId from '../../../../wdio/utils/generateTestId';
import {
selectChainId,
selectProviderType,
@@ -41,10 +39,7 @@ import {
selectUseNftDetection,
} from '../../../selectors/preferencesController';
import { selectSelectedInternalAccountChecksummedAddress } from '../../../selectors/accountsController';
-import {
- IMPORT_NFT_BUTTON_ID,
- NFT_TAB_CONTAINER_ID,
-} from '../../../../wdio/screen-objects/testIDs/Screens/WalletView.testIds';
+import { WalletViewSelectorsIDs } from '../../../../e2e/selectors/wallet/WalletView.selectors';
import { useMetrics } from '../../../components/hooks/useMetrics';
import { RefreshTestId, SpinnerTestId } from './constants';
@@ -239,7 +234,7 @@ const CollectibleContracts = ({
{strings('wallet.add_collectibles')}
@@ -376,7 +371,7 @@ const CollectibleContracts = ({
return (
{renderList()}
diff --git a/app/components/UI/CollectibleContracts/index.test.tsx b/app/components/UI/CollectibleContracts/index.test.tsx
index 946a654ba62..db7045fdb84 100644
--- a/app/components/UI/CollectibleContracts/index.test.tsx
+++ b/app/components/UI/CollectibleContracts/index.test.tsx
@@ -3,7 +3,7 @@ import { shallow } from 'enzyme';
import CollectibleContracts from './';
import configureMockStore from 'redux-mock-store';
import { Provider } from 'react-redux';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
import renderWithProvider from '../../../util/test/renderWithProvider';
import { act } from '@testing-library/react-hooks';
@@ -51,7 +51,7 @@ const initialState = {
favorites: {},
},
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
};
const store = mockStore(initialState);
@@ -79,7 +79,7 @@ describe('CollectibleContracts', () => {
},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
NetworkController: {
network: '1',
providerConfig: {
@@ -196,7 +196,7 @@ describe('CollectibleContracts', () => {
},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
NetworkController: {
network: '1',
providerConfig: {
@@ -309,7 +309,7 @@ describe('CollectibleContracts', () => {
},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
NetworkController: {
network: '1',
providerConfig: {
@@ -426,7 +426,7 @@ describe('CollectibleContracts', () => {
},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
NetworkController: {
network: '1',
providerConfig: {
@@ -505,7 +505,7 @@ describe('CollectibleContracts', () => {
},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
NetworkController: {
network: '1',
providerConfig: {
@@ -564,7 +564,7 @@ describe('CollectibleContracts', () => {
},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
NetworkController: {
network: '1',
providerConfig: {
diff --git a/app/components/UI/CollectibleMedia/CollectibleMedia.test.tsx b/app/components/UI/CollectibleMedia/CollectibleMedia.test.tsx
index 978e0e12042..f45d0051d4c 100644
--- a/app/components/UI/CollectibleMedia/CollectibleMedia.test.tsx
+++ b/app/components/UI/CollectibleMedia/CollectibleMedia.test.tsx
@@ -3,11 +3,11 @@ import React from 'react';
import CollectibleMedia from './CollectibleMedia';
import renderWithProvider from '../../../util/test/renderWithProvider';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
const mockInitialState = {
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
};
diff --git a/app/components/UI/CollectibleModal/CollectibleModal.test.tsx b/app/components/UI/CollectibleModal/CollectibleModal.test.tsx
index 3d69d9c6a27..c7c9a52687e 100644
--- a/app/components/UI/CollectibleModal/CollectibleModal.test.tsx
+++ b/app/components/UI/CollectibleModal/CollectibleModal.test.tsx
@@ -3,7 +3,7 @@ import React from 'react';
import CollectibleModal from './CollectibleModal';
import renderWithProvider from '../../../util/test/renderWithProvider';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
import { collectiblesSelector } from '../../../reducers/collectibles';
import {
selectDisplayNftMedia,
@@ -15,7 +15,7 @@ import { MOCK_ACCOUNTS_CONTROLLER_STATE } from '../../../util/test/accountsContr
const mockInitialState = {
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
},
},
diff --git a/app/components/UI/CollectibleOverview/index.test.tsx b/app/components/UI/CollectibleOverview/index.test.tsx
index ea570feb266..6bc40a57a64 100644
--- a/app/components/UI/CollectibleOverview/index.test.tsx
+++ b/app/components/UI/CollectibleOverview/index.test.tsx
@@ -3,7 +3,7 @@ import CollectibleOverview from './';
import configureMockStore from 'redux-mock-store';
import { shallow } from 'enzyme';
import { Provider } from 'react-redux';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
const mockStore = configureMockStore();
const initialState = {
@@ -11,7 +11,7 @@ const initialState = {
favorites: {},
},
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
};
const store = mockStore(initialState);
diff --git a/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx b/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx
index 9288d2fbcbb..73647c006f0 100644
--- a/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx
+++ b/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import ConfirmAddAsset from './ConfirmAddAsset';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
import renderWithProvider from '../../../util/test/renderWithProvider';
import useBalance from '../Ramp/hooks/useBalance';
import { toTokenMinimalUnit } from '../../../util/number';
@@ -58,7 +58,7 @@ const mockInitialState = {
settings: {},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
AccountTrackerController: {
accounts: {
'0xC4955C0d639D99699Bfd7Ec54d9FaFEe40e4D272': {
diff --git a/app/components/UI/DrawerView/index.js b/app/components/UI/DrawerView/index.js
index 82963e61ae0..f33822e83f3 100644
--- a/app/components/UI/DrawerView/index.js
+++ b/app/components/UI/DrawerView/index.js
@@ -81,12 +81,12 @@ import { selectCurrentCurrency } from '../../../selectors/currencyRateController
import { selectTokens } from '../../../selectors/tokensController';
import { selectAccounts } from '../../../selectors/accountTrackerController';
import { selectContractBalances } from '../../../selectors/tokenBalancesController';
-import { selectIdentities } from '../../../selectors/preferencesController';
-import { selectSelectedInternalAccountChecksummedAddress } from '../../../selectors/accountsController';
+import { selectSelectedInternalAccount } from '../../../selectors/accountsController';
import { createAccountSelectorNavDetails } from '../../Views/AccountSelector';
import NetworkInfo from '../NetworkInfo';
import { withMetricsAwareness } from '../../../components/hooks/useMetrics';
+import { toChecksumHexAddress } from '@metamask/controller-utils';
const createStyles = (colors) =>
StyleSheet.create({
@@ -340,18 +340,14 @@ class DrawerView extends PureComponent {
* Object representing the configuration of the current selected network
*/
providerConfig: PropTypes.object.isRequired,
- /**
- * Selected address as string
- */
- selectedAddress: PropTypes.string,
/**
* List of accounts from the AccountTrackerController
*/
accounts: PropTypes.object,
/**
- * List of accounts from the PreferencesController
+ * Currently selected account
*/
- identities: PropTypes.object,
+ selectedInternalAccount: PropTypes.object,
/**
/* Selected currency
*/
@@ -474,16 +470,19 @@ class DrawerView extends PureComponent {
previousBalance = null;
processedNewBalance = false;
animatingNetworksModal = false;
+ selectedChecksummedAddress = toChecksumHexAddress(
+ this.props.selectedInternalAccount.address,
+ );
isCurrentAccountImported() {
let ret = false;
- const { keyrings, selectedAddress } = this.props;
+ const { keyrings } = this.props;
const allKeyrings =
keyrings && keyrings.length
? keyrings
: Engine.context.KeyringController.state.keyrings;
for (const keyring of allKeyrings) {
- if (keyring.accounts.includes(selectedAddress)) {
+ if (keyring.accounts.includes(this.selectedChecksummedAddress)) {
ret = keyring.type !== 'HD Key Tree';
break;
}
@@ -495,7 +494,7 @@ class DrawerView extends PureComponent {
renderTag() {
const colors = this.context.colors || mockTheme.colors;
const styles = createStyles(colors);
- const label = getLabelTextByAddress(this.props.selectedAddress);
+ const label = getLabelTextByAddress(this.selectedChecksummedAddress);
return label ? (
@@ -579,16 +578,16 @@ class DrawerView extends PureComponent {
}
updateAccountInfo = async () => {
- const { identities, providerConfig, selectedAddress } = this.props;
+ const { providerConfig, selectedInternalAccount } = this.props;
const { currentChainId, address, name } = this.state.account;
- const accountName = identities[selectedAddress]?.name;
+ const accountName = selectedInternalAccount.metadata.name;
if (
currentChainId !== providerConfig.chainId ||
- address !== selectedAddress ||
+ address !== this.selectedChecksummedAddress ||
name !== accountName
) {
const ens = await doENSReverseLookup(
- selectedAddress,
+ this.selectedChecksummedAddress,
providerConfig.chainId,
);
this.setState((state) => ({
@@ -596,7 +595,7 @@ class DrawerView extends PureComponent {
ens,
name: accountName,
currentChainId: providerConfig.chainId,
- address: selectedAddress,
+ address: this.selectedChecksummedAddress,
},
}));
}
@@ -697,18 +696,20 @@ class DrawerView extends PureComponent {
};
viewInEtherscan = () => {
- const { selectedAddress, providerConfig, networkConfigurations } =
- this.props;
+ const { providerConfig, networkConfigurations } = this.props;
if (providerConfig.type === RPC) {
const blockExplorer = findBlockExplorerForRpc(
providerConfig.rpcUrl,
networkConfigurations,
);
- const url = `${blockExplorer}/address/${selectedAddress}`;
+ const url = `${blockExplorer}/address/${this.selectedChecksummedAddress}`;
const title = new URL(blockExplorer).hostname;
this.goToBrowserUrl(url, title);
} else {
- const url = getEtherscanAddressUrl(providerConfig.type, selectedAddress);
+ const url = getEtherscanAddressUrl(
+ providerConfig.type,
+ this.selectedChecksummedAddress,
+ );
const etherscan_url = getEtherscanBaseUrl(providerConfig.type).replace(
'https://',
'',
@@ -892,8 +893,7 @@ class DrawerView extends PureComponent {
};
copyAccountToClipboard = async () => {
- const { selectedAddress } = this.props;
- await ClipboardManager.setString(selectedAddress);
+ await ClipboardManager.setString(this.selectedChecksummedAddress);
this.toggleReceiveModal();
InteractionManager.runAfterInteractions(() => {
this.props.showAlert({
@@ -906,9 +906,8 @@ class DrawerView extends PureComponent {
};
onShare = () => {
- const { selectedAddress } = this.props;
Share.open({
- message: selectedAddress,
+ message: this.selectedChecksummedAddress,
})
.then(() => {
this.props.protectWalletModalVisible();
@@ -996,8 +995,7 @@ class DrawerView extends PureComponent {
const {
providerConfig,
accounts,
- identities,
- selectedAddress,
+ selectedInternalAccount,
currentCurrency,
seedphraseBackedUp,
currentRoute,
@@ -1011,16 +1009,16 @@ class DrawerView extends PureComponent {
} = this.state;
const account = {
- address: selectedAddress,
+ address: this.selectedChecksummedAddress,
name: nameFromState,
ens: ensFromState,
- ...identities[selectedAddress],
- ...accounts[selectedAddress],
+ ...selectedInternalAccount,
+ ...accounts[this.selectedChecksummedAddress],
};
const { name, ens } = account;
account.balance =
- (accounts[selectedAddress] &&
- renderFromWei(accounts[selectedAddress].balance)) ||
+ (accounts[this.selectedChecksummedAddress] &&
+ renderFromWei(accounts[this.selectedChecksummedAddress].balance)) ||
0;
const fiatBalance = Engine.getTotalFiatAccountBalance();
const totalFiatBalance = fiatBalance.ethFiat + fiatBalance.tokenFiat;
@@ -1056,7 +1054,10 @@ class DrawerView extends PureComponent {
testID={'navbar-account-identicon'}
>
-
+
({
providerConfig: selectProviderConfig(state),
accounts: selectAccounts(state),
- selectedAddress: selectSelectedInternalAccountChecksummedAddress(state),
- identities: selectIdentities(state),
+ selectedInternalAccount: selectSelectedInternalAccount(state),
networkConfigurations: selectNetworkConfigurations(state),
currentCurrency: selectCurrentCurrency(state),
keyrings: state.engine.backgroundState.KeyringController.keyrings,
diff --git a/app/components/UI/DrawerView/index.test.tsx b/app/components/UI/DrawerView/index.test.tsx
index 9d06c981241..6eebe48bc6e 100644
--- a/app/components/UI/DrawerView/index.test.tsx
+++ b/app/components/UI/DrawerView/index.test.tsx
@@ -2,28 +2,16 @@ import React from 'react';
import renderWithProvider from '../../../util/test/renderWithProvider';
import DrawerView from './';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
import Engine from '../../../core/Engine';
-import {
- MOCK_ACCOUNTS_CONTROLLER_STATE,
- MOCK_ADDRESS_1,
-} from '../../../util/test/accountsControllerTestUtils';
+import { MOCK_ACCOUNTS_CONTROLLER_STATE } from '../../../util/test/accountsControllerTestUtils';
const mockedEngine = Engine;
const mockInitialState = {
engine: {
backgroundState: {
- ...initialBackgroundState,
- PreferencesController: {
- selectedAddress: MOCK_ADDRESS_1,
- identities: {
- [MOCK_ADDRESS_1]: {
- name: 'Account 1',
- address: MOCK_ADDRESS_1,
- },
- },
- },
+ ...backgroundState,
AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
},
},
diff --git a/app/components/UI/EthereumAddress/index.js b/app/components/UI/EthereumAddress/index.js
index b522b2bf0cd..82b2ce368a8 100644
--- a/app/components/UI/EthereumAddress/index.js
+++ b/app/components/UI/EthereumAddress/index.js
@@ -21,7 +21,7 @@ class EthereumAddress extends PureComponent {
address: PropTypes.string,
/**
* Type of formatting for the address
- * can be "short" or "full"
+ * can be "short", "mid" or "full"
*/
type: PropTypes.string,
};
diff --git a/app/components/UI/Navbar/index.js b/app/components/UI/Navbar/index.js
index 53b37cd4c9a..d56aec0c3db 100644
--- a/app/components/UI/Navbar/index.js
+++ b/app/components/UI/Navbar/index.js
@@ -27,12 +27,10 @@ import Device from '../../../util/device';
import PickerNetwork from '../../../component-library/components/Pickers/PickerNetwork';
import BrowserUrlBar from '../BrowserUrlBar';
import generateTestId from '../../../../wdio/utils/generateTestId';
-import { NAVBAR_NETWORK_BUTTON } from '../../../../wdio/screen-objects/testIDs/Screens/WalletView.testIds';
import { NAV_ANDROID_BACK_BUTTON } from '../../../../wdio/screen-objects/testIDs/Screens/NetworksScreen.testids';
import { ASSET_BACK_BUTTON } from '../../../../wdio/screen-objects/testIDs/Screens/TokenOverviewScreen.testIds';
import { REQUEST_SEARCH_RESULTS_BACK_BUTTON } from '../../../../wdio/screen-objects/testIDs/Screens/RequestToken.testIds';
import { BACK_BUTTON_SIMPLE_WEBVIEW } from '../../../../wdio/screen-objects/testIDs/Components/SimpleWebView.testIds';
-import { EDIT_BUTTON } from '../../../../wdio/screen-objects/testIDs/Common.testIds';
import Routes from '../../../constants/navigation/Routes';
import ButtonIcon, {
@@ -53,6 +51,7 @@ import { NetworksViewSelectorsIDs } from '../../../../e2e/selectors/Settings/Net
import { SendLinkViewSelectorsIDs } from '../../../../e2e/selectors/SendLinkView.selectors';
import { SendViewSelectorsIDs } from '../../../../e2e/selectors/SendView.selectors';
import { getBlockaidTransactionMetricsParams } from '../../../util/blockaid';
+import { AddContactViewSelectorsIDs } from '../../../../e2e/selectors/Settings/Contacts/AddContactView.selectors';
const trackEvent = (event, params = {}) => {
MetaMetrics.getInstance().trackEvent(event, params);
@@ -290,7 +289,7 @@ export function getEditableOptions(title, navigation, route, themeColors) {
{editMode
@@ -984,7 +983,7 @@ export function getWalletNavbarOptions(
label={networkName}
imageSource={networkImageSource}
onPress={onPressTitle}
- {...generateTestId(Platform, NAVBAR_NETWORK_BUTTON)}
+ testID={WalletViewSelectorsIDs.NAVBAR_NETWORK_BUTTON}
/>
),
diff --git a/app/components/UI/NavbarBrowserTitle/index.test.tsx b/app/components/UI/NavbarBrowserTitle/index.test.tsx
index 65a46192a79..5d7e771bedc 100644
--- a/app/components/UI/NavbarBrowserTitle/index.test.tsx
+++ b/app/components/UI/NavbarBrowserTitle/index.test.tsx
@@ -1,22 +1,14 @@
import React from 'react';
import renderWithProvider from '../../../util/test/renderWithProvider';
import NavbarBrowserTitle from './';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
import Engine from '../../../core/Engine';
const mockedEngine = Engine;
const mockInitialState = {
engine: {
- backgroundState: {
- ...initialBackgroundState,
- PreferencesController: {
- selectedAddress: '0x',
- identities: {
- '0x': { name: 'Account 1', address: '0x' },
- },
- },
- },
+ backgroundState,
},
};
diff --git a/app/components/UI/NetworkInfo/index.test.tsx b/app/components/UI/NetworkInfo/index.test.tsx
index 5e9cb5dfadf..e52882bc2a9 100644
--- a/app/components/UI/NetworkInfo/index.test.tsx
+++ b/app/components/UI/NetworkInfo/index.test.tsx
@@ -3,7 +3,7 @@ import { shallow } from 'enzyme';
import NetworkInfo from './';
import configureMockStore from 'redux-mock-store';
import { Provider } from 'react-redux';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
const mockStore = configureMockStore();
const initialState = {
@@ -11,7 +11,7 @@ const initialState = {
approvedHosts: {},
},
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
};
diff --git a/app/components/UI/NetworkMainAssetLogo/index.test.tsx b/app/components/UI/NetworkMainAssetLogo/index.test.tsx
index 687a841d2be..84a625a7c16 100644
--- a/app/components/UI/NetworkMainAssetLogo/index.test.tsx
+++ b/app/components/UI/NetworkMainAssetLogo/index.test.tsx
@@ -5,7 +5,7 @@ import { ChainId } from '@metamask/controller-utils';
import { render } from '@testing-library/react-native';
import NetworkMainAssetLogo from '.';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
jest.mock('../Swaps/components/TokenIcon', () => {
const originalModule = jest.requireActual('../Swaps/components/TokenIcon');
@@ -18,9 +18,7 @@ jest.mock('../Swaps/components/TokenIcon', () => {
const mockInitialState = {
engine: {
- backgroundState: {
- ...initialBackgroundState,
- },
+ backgroundState,
},
network: {
provider: {
diff --git a/app/components/UI/Notification/Row/Icon.test.tsx b/app/components/UI/Notification/Row/Icon.test.tsx
index dbd6cda22e6..ba8081b5346 100644
--- a/app/components/UI/Notification/Row/Icon.test.tsx
+++ b/app/components/UI/Notification/Row/Icon.test.tsx
@@ -6,7 +6,7 @@ import renderWithProvider from '../../../../util/test/renderWithProvider';
import NotificationIcon from './Icon';
import { TRIGGER_TYPES } from '../../../../util/notifications';
import { IconName } from '../../../../component-library/components/Icons/Icon';
-import initialBackgroundState from '../../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../../util/test/initial-root-state';
import { CommonSelectorsIDs } from '../../../../../e2e/selectors/Common.selectors';
import SVG_MM_LOGO_PATH from '../../../../images/fox.svg';
@@ -17,7 +17,7 @@ Linking.openURL = jest.fn(() => Promise.resolve('opened https://metamask.io!'));
const mockInitialState = {
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
},
},
};
diff --git a/app/components/UI/PaymentRequest/AssetList/index.test.tsx b/app/components/UI/PaymentRequest/AssetList/index.test.tsx
index 9320aa39c9c..02a3a1c73ea 100644
--- a/app/components/UI/PaymentRequest/AssetList/index.test.tsx
+++ b/app/components/UI/PaymentRequest/AssetList/index.test.tsx
@@ -3,12 +3,12 @@ import { shallow } from 'enzyme';
import AssetList from './';
import configureMockStore from 'redux-mock-store';
import { Provider } from 'react-redux';
-import initialBackgroundState from '../../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../../util/test/initial-root-state';
const mockStore = configureMockStore();
const initialState = {
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
};
const store = mockStore(initialState);
diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx
index c9d0dc77f24..d818aa6a342 100644
--- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx
+++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx
@@ -7,7 +7,7 @@ import BuildQuote from './BuildQuote';
import useRegions from '../../hooks/useRegions';
import { RampSDK } from '../../sdk';
import Routes from '../../../../../constants/navigation/Routes';
-import initialBackgroundState from '../../../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../../../util/test/initial-root-state';
import useCryptoCurrencies from '../../hooks/useCryptoCurrencies';
import useFiatCurrencies from '../../hooks/useFiatCurrencies';
import usePaymentMethods from '../../hooks/usePaymentMethods';
@@ -39,7 +39,7 @@ function render(Component: React.ComponentType) {
state: {
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
},
},
diff --git a/app/components/UI/Ramp/Views/GetStarted/GetStarted.test.tsx b/app/components/UI/Ramp/Views/GetStarted/GetStarted.test.tsx
index 223396f1835..2a926c9a527 100644
--- a/app/components/UI/Ramp/Views/GetStarted/GetStarted.test.tsx
+++ b/app/components/UI/Ramp/Views/GetStarted/GetStarted.test.tsx
@@ -7,7 +7,7 @@ import { RampType, Region } from '../../types';
import { RampSDK } from '../../sdk';
import useRampNetwork from '../../hooks/useRampNetwork';
import Routes from '../../../../../constants/navigation/Routes';
-import initialBackgroundState from '../../../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../../../util/test/initial-root-state';
function render(Component: React.ComponentType) {
return renderScreen(
@@ -18,7 +18,7 @@ function render(Component: React.ComponentType) {
{
state: {
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
},
},
diff --git a/app/components/UI/Ramp/Views/NetworkSwitcher/NetworkSwitcher.test.tsx b/app/components/UI/Ramp/Views/NetworkSwitcher/NetworkSwitcher.test.tsx
index 7970b289a16..bbb43e19a0f 100644
--- a/app/components/UI/Ramp/Views/NetworkSwitcher/NetworkSwitcher.test.tsx
+++ b/app/components/UI/Ramp/Views/NetworkSwitcher/NetworkSwitcher.test.tsx
@@ -8,7 +8,7 @@ import useFetchRampNetworks from '../../hooks/useFetchRampNetworks';
import useRampNetworksDetail from '../../hooks/useRampNetworksDetail';
import { RampSDK } from '../../sdk';
import Routes from '../../../../../constants/navigation/Routes';
-import initialBackgroundState from '../../../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../../../util/test/initial-root-state';
import Engine from '../../../../../core/Engine';
import { RampType } from '../../../../../reducers/fiatOrders/types';
@@ -76,9 +76,9 @@ function render(Component: React.ComponentType, chainId?: string) {
state: {
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
NetworkController: {
- ...initialBackgroundState.NetworkController,
+ ...backgroundState.NetworkController,
providerConfig: {
chainId: chainId ?? '0x38',
ticker: 'BNB',
diff --git a/app/components/UI/Ramp/Views/OrderDetails/OrderDetails.test.tsx b/app/components/UI/Ramp/Views/OrderDetails/OrderDetails.test.tsx
index 67c87bf41c7..9fabce779b3 100644
--- a/app/components/UI/Ramp/Views/OrderDetails/OrderDetails.test.tsx
+++ b/app/components/UI/Ramp/Views/OrderDetails/OrderDetails.test.tsx
@@ -3,7 +3,7 @@ import { processFiatOrder } from '../../index';
import { act, fireEvent, screen, waitFor } from '@testing-library/react-native';
import { renderScreen } from '../../../../../util/test/renderWithProvider';
import OrderDetails from './OrderDetails';
-import initialBackgroundState from '../../../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../../../util/test/initial-root-state';
import { FiatOrder } from '../../../../../reducers/fiatOrders';
import {
FIAT_ORDER_PROVIDERS,
@@ -141,7 +141,7 @@ function render(Component: React.ComponentType, orders = [mockOrder]) {
state: {
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
},
},
diff --git a/app/components/UI/Ramp/Views/OrderDetails/__snapshots__/OrderDetails.test.tsx.snap b/app/components/UI/Ramp/Views/OrderDetails/__snapshots__/OrderDetails.test.tsx.snap
index dd227168f98..e7db500ff72 100644
--- a/app/components/UI/Ramp/Views/OrderDetails/__snapshots__/OrderDetails.test.tsx.snap
+++ b/app/components/UI/Ramp/Views/OrderDetails/__snapshots__/OrderDetails.test.tsx.snap
@@ -863,6 +863,7 @@ exports[`OrderDetails renders a cancelled order 1`] = `
]
}
>
+ Account 1
(
+ Account 1
(
+ Account 1
(
+ Account 1
(
+ Account 1
(
+ Account 1
(
+ Account 1
(
+ Account 1
(
+ Account 1
(
= {
@@ -21,7 +21,7 @@ function render(Component: React.ComponentType) {
{
state: {
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
},
},
diff --git a/app/components/UI/Ramp/components/Account.tsx b/app/components/UI/Ramp/components/Account.tsx
index 23263f40612..900e96f3b33 100644
--- a/app/components/UI/Ramp/components/Account.tsx
+++ b/app/components/UI/Ramp/components/Account.tsx
@@ -7,8 +7,11 @@ import { View, StyleSheet } from 'react-native';
import { useTheme } from '../../../../util/theme';
import { Colors } from '../../../../util/theme/models';
import { colors as importedColors } from '../../../../styles/common';
-import { selectIdentities } from '../../../../selectors/preferencesController';
-import { selectSelectedInternalAccountChecksummedAddress } from '../../../../selectors/accountsController';
+import {
+ selectSelectedInternalAccountChecksummedAddress,
+ selectInternalAccounts,
+} from '../../../../selectors/accountsController';
+import { toLowerCaseEquals } from '../../../../util/general';
// TODO: Convert into typescript and correctly type
// TODO: Replace "any" with type
@@ -51,14 +54,25 @@ const Account = ({
const selectedAddress = useSelector(
selectSelectedInternalAccountChecksummedAddress,
);
- const identities = useSelector(selectIdentities);
+
+ const internalAccounts = useSelector(selectInternalAccounts);
+
+ const selectedInternalAccount = address
+ ? internalAccounts.find((account) =>
+ toLowerCaseEquals(account.address, address),
+ )
+ : internalAccounts.find((account) =>
+ toLowerCaseEquals(account.address, selectedAddress),
+ );
+
+ const accountName = selectedInternalAccount?.metadata?.name || '';
return (
- {identities[address || selectedAddress]?.name} (
+ {accountName} (
)
diff --git a/app/components/UI/Ramp/hooks/useBalance.ts b/app/components/UI/Ramp/hooks/useBalance.ts
index f0e49c63e3a..de0ed400742 100644
--- a/app/components/UI/Ramp/hooks/useBalance.ts
+++ b/app/components/UI/Ramp/hooks/useBalance.ts
@@ -1,5 +1,5 @@
-import { hexToBN } from '@metamask/controller-utils';
import { useSelector } from 'react-redux';
+import { hexToBN } from '@metamask/controller-utils';
import { NATIVE_ADDRESS } from '../../../../constants/on-ramp';
import { selectAccountsByChainId } from '../../../../selectors/accountTrackerController';
import {
@@ -19,13 +19,18 @@ import {
weiToFiat,
} from '../../../../util/number';
+const defaultReturn = {
+ balance: null,
+ balanceFiat: null,
+ balanceBN: null,
+};
+
interface Asset {
address: string;
decimals: number;
}
export default function useBalance(asset?: Asset) {
- const assetAddress = safeToChecksumAddress(asset?.address);
const accountsByChainId = useSelector(selectAccountsByChainId);
const chainId = useSelector(selectChainId);
const selectedAddress = useSelector(
@@ -36,8 +41,14 @@ export default function useBalance(asset?: Asset) {
const tokenExchangeRates = useSelector(selectContractExchangeRates);
const balances = useSelector(selectContractBalances);
- if (!asset || !assetAddress) {
- return { balance: null, balanceFiat: null, balanceBN: null };
+ if (!asset) {
+ return defaultReturn;
+ }
+
+ const assetAddress = safeToChecksumAddress(asset.address);
+
+ if (!assetAddress) {
+ return defaultReturn;
}
let balance, balanceFiat, balanceBN;
@@ -66,7 +77,9 @@ export default function useBalance(asset?: Asset) {
currentCurrency,
);
balanceBN =
- assetAddress && assetAddress in balances ? balances[assetAddress] : null;
+ assetAddress && assetAddress in balances
+ ? hexToBN(balances[assetAddress])
+ : null;
}
return { balance, balanceFiat, balanceBN };
diff --git a/app/components/UI/Ramp/hooks/useGasPriceEstimation.test.ts b/app/components/UI/Ramp/hooks/useGasPriceEstimation.test.ts
index 33116230fad..08651f52b69 100644
--- a/app/components/UI/Ramp/hooks/useGasPriceEstimation.test.ts
+++ b/app/components/UI/Ramp/hooks/useGasPriceEstimation.test.ts
@@ -2,7 +2,7 @@ import { merge } from 'lodash';
import type { GasFeeState } from '@metamask/gas-fee-controller';
import useGasPriceEstimation from './useGasPriceEstimation';
import { renderHookWithProvider } from '../../../../util/test/renderWithProvider';
-import initialBackgroundState from '../../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../../util/test/initial-root-state';
import Engine from '../../../../core/Engine';
type DeepPartial = {
@@ -23,7 +23,7 @@ jest.mock('../../../../core/Engine', () => ({
const mockInitialState = {
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
};
diff --git a/app/components/UI/ReceiveRequest/index.test.tsx b/app/components/UI/ReceiveRequest/index.test.tsx
index 1b95e369856..8cddbd17e97 100644
--- a/app/components/UI/ReceiveRequest/index.test.tsx
+++ b/app/components/UI/ReceiveRequest/index.test.tsx
@@ -3,14 +3,14 @@ import { shallow } from 'enzyme';
import ReceiveRequest from './';
import configureMockStore from 'redux-mock-store';
import { Provider } from 'react-redux';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
import { MOCK_ACCOUNTS_CONTROLLER_STATE } from '../../../util/test/accountsControllerTestUtils';
const mockStore = configureMockStore();
const initialState = {
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
},
},
diff --git a/app/components/UI/SearchTokenAutocomplete/index.test.tsx b/app/components/UI/SearchTokenAutocomplete/index.test.tsx
index 8ea3e4bd99f..90f39f6d2c2 100644
--- a/app/components/UI/SearchTokenAutocomplete/index.test.tsx
+++ b/app/components/UI/SearchTokenAutocomplete/index.test.tsx
@@ -1,21 +1,14 @@
import { renderScreen } from '../../../util/test/renderWithProvider';
import SearchTokenAutocomplete from './';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
const mockInitialState = {
settings: {},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
PreferencesController: {
useTokenDetection: true,
- selectedAddress: '0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3',
- identities: {
- '0x0': {
- address: '0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3',
- name: 'Account 1',
- },
- },
},
},
},
diff --git a/app/components/UI/SimulationDetails/FiatDisplay/FiatDisplay.test.tsx b/app/components/UI/SimulationDetails/FiatDisplay/FiatDisplay.test.tsx
index c5c3a1f4a78..4c349bf1dd9 100644
--- a/app/components/UI/SimulationDetails/FiatDisplay/FiatDisplay.test.tsx
+++ b/app/components/UI/SimulationDetails/FiatDisplay/FiatDisplay.test.tsx
@@ -1,9 +1,10 @@
import React from 'react';
import { merge } from 'lodash';
import renderWithProvider from '../../../../util/test/renderWithProvider';
-import initialBackgroundState from '../../../../util/test/initial-background-state.json';
-import { FIAT_UNAVAILABLE } from '../types';
+import { backgroundState } from '../../../../util/test/initial-root-state';
+
import { IndividualFiatDisplay, TotalFiatDisplay } from './FiatDisplay';
+import { FIAT_UNAVAILABLE } from '../types';
import useFiatFormatter from './useFiatFormatter';
import { NETWORKS_CHAIN_ID } from '../../../../constants/network';
@@ -11,7 +12,7 @@ jest.mock('./useFiatFormatter');
const mockInitialState = {
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
};
diff --git a/app/components/UI/Tabs/TabThumbnail/TabThumbnail.test.tsx b/app/components/UI/Tabs/TabThumbnail/TabThumbnail.test.tsx
index 6d18a67b1c5..8fcf4cf67d3 100644
--- a/app/components/UI/Tabs/TabThumbnail/TabThumbnail.test.tsx
+++ b/app/components/UI/Tabs/TabThumbnail/TabThumbnail.test.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import renderWithProvider from '../../../../util/test/renderWithProvider';
-import initialBackgroundState from '../../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../../util/test/initial-root-state';
import TabThumbnail from './TabThumbnail';
import { MOCK_ACCOUNTS_CONTROLLER_STATE } from '../../../../util/test/accountsControllerTestUtils';
@@ -10,7 +10,7 @@ const mockInitialState = {
},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
},
},
diff --git a/app/components/UI/Tabs/index.test.tsx b/app/components/UI/Tabs/index.test.tsx
index c2360474440..60bf5b6bade 100644
--- a/app/components/UI/Tabs/index.test.tsx
+++ b/app/components/UI/Tabs/index.test.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import renderWithProvider from '../../../util/test/renderWithProvider';
import Tabs from './';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
import { MOCK_ACCOUNTS_CONTROLLER_STATE } from '../../../util/test/accountsControllerTestUtils';
const mockInitialState = {
@@ -10,7 +10,7 @@ const mockInitialState = {
},
engine: {
backgroundState: {
- ...initialBackgroundState,
+ ...backgroundState,
AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
},
},
diff --git a/app/components/UI/TokenImage/index.test.tsx b/app/components/UI/TokenImage/index.test.tsx
index 685ccafa16a..1a881dcfb0b 100644
--- a/app/components/UI/TokenImage/index.test.tsx
+++ b/app/components/UI/TokenImage/index.test.tsx
@@ -3,12 +3,12 @@ import { shallow } from 'enzyme';
import TokenImage from './';
import configureMockStore from 'redux-mock-store';
import { Provider } from 'react-redux';
-import initialBackgroundState from '../../../util/test/initial-background-state.json';
+import { backgroundState } from '../../../util/test/initial-root-state';
const mockStore = configureMockStore();
const initialState = {
engine: {
- backgroundState: initialBackgroundState,
+ backgroundState,
},
settings: {
primaryCurrency: 'usd',
diff --git a/app/components/UI/Tokens/__snapshots__/index.test.tsx.snap b/app/components/UI/Tokens/__snapshots__/index.test.tsx.snap
index 4aaccc2fc58..5e8f8125c9b 100644
--- a/app/components/UI/Tokens/__snapshots__/index.test.tsx.snap
+++ b/app/components/UI/Tokens/__snapshots__/index.test.tsx.snap
@@ -327,19 +327,22 @@ exports[`Tokens should hide zero balance tokens when setting is on 1`] = `
}
}
>
-
+
- 0 USD
-
+ testID="total-balance-text"
+ >
+ 0 USD
+
+
+
-
+
- < $0.01
-
+ />
+
-
- < 0.00001 BAT
-
+
+ < 0.00001 BAT
+
+
+ < $0.01
+
+
-
+
- 0 USD
-
+ testID="total-balance-text"
+ >
+ 0 USD
+
+
+