From 50247caea536cdbe3ad3aac7c8a449a00b181642 Mon Sep 17 00:00:00 2001 From: metamaskbot Date: Wed, 21 Jun 2023 01:10:46 +0000 Subject: [PATCH 01/17] 7.2.0 --- CHANGELOG.md | 60 ++++++++++++++++++++++++++ android/app/build.gradle | 4 +- bitrise.yml | 4 +- ios/MetaMask.xcodeproj/project.pbxproj | 16 +++---- package.json | 2 +- 5 files changed, 73 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b657fd1158..4aceb8ec50e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,66 @@ # Changelog ## Current Main Branch +- [#6549](https://github.com/MetaMask/metamask-mobile/pull/6549): fix: Networks text alignement +- [#6632](https://github.com/MetaMask/metamask-mobile/pull/6632): feat: add linea mainnet alert message +- [#6467](https://github.com/MetaMask/metamask-mobile/pull/6467): chore(translations): New Crowdin translations by Github Action +- [#6480](https://github.com/MetaMask/metamask-mobile/pull/6480): feat(release): 7.1.0 +- [#6636](https://github.com/MetaMask/metamask-mobile/pull/6636): test: add approve ERC20 with custom amount +- [#6496](https://github.com/MetaMask/metamask-mobile/pull/6496): feat(551): add Linea Mainnet +- [#6634](https://github.com/MetaMask/metamask-mobile/pull/6634): disable next button if custom input is invalid +- [#6612](https://github.com/MetaMask/metamask-mobile/pull/6612): chore: approve txn when gas estimation ready +- [#6494](https://github.com/MetaMask/metamask-mobile/pull/6494): feat: Update banner component to show/hide details section +- [#6621](https://github.com/MetaMask/metamask-mobile/pull/6621): E2e/655 remove drawer +- [#6491](https://github.com/MetaMask/metamask-mobile/pull/6491): fix: refactor linea testnet implementation +- [#6054](https://github.com/MetaMask/metamask-mobile/pull/6054): Improve TagURL +- [#6539](https://github.com/MetaMask/metamask-mobile/pull/6539): feat: [MC 0.5] Remove drawer and add remain options to settings tab +- [#6378](https://github.com/MetaMask/metamask-mobile/pull/6378): feat: Add eth_sign friction +- [#6520](https://github.com/MetaMask/metamask-mobile/pull/6520): improve variable name +- [#6358](https://github.com/MetaMask/metamask-mobile/pull/6358): No Warning appears when a Dapp sets a really high Fees for a tx, potentially loosing all user funds +- [#6592](https://github.com/MetaMask/metamask-mobile/pull/6592): fix: Nonce too low error on Approve ERC20 and ERC721 transactions +- [#6577](https://github.com/MetaMask/metamask-mobile/pull/6577): feat: fix onBoarding wizard horizontal alignment on step1 and on browser step +- [#6597](https://github.com/MetaMask/metamask-mobile/pull/6597): action tx: rm unused prepareFullTransaction +- [#6423](https://github.com/MetaMask/metamask-mobile/pull/6423): ci(stale-bot): increase number of operations +- [#6477](https://github.com/MetaMask/metamask-mobile/pull/6477): ci(stale-bot): update stale bot to only flag issues that are type-bug with stale +- [#6598](https://github.com/MetaMask/metamask-mobile/pull/6598): fix: Hold to reveal Spanish copy +- [#6562](https://github.com/MetaMask/metamask-mobile/pull/6562): test: adding hooks on confirmations e2e wdio and fix failing test +- [#6557](https://github.com/MetaMask/metamask-mobile/pull/6557): test: add signing e2e tests +- [#6291](https://github.com/MetaMask/metamask-mobile/pull/6291): refactor: trigger transaction modals using approval requests +- [#6513](https://github.com/MetaMask/metamask-mobile/pull/6513): Bump rexml from 3.2.4 to 3.2.5 +- [#5751](https://github.com/MetaMask/metamask-mobile/pull/5751): update Keystone links +- [#6523](https://github.com/MetaMask/metamask-mobile/pull/6523): fix: Network logo to represent first letter of network +- [#6541](https://github.com/MetaMask/metamask-mobile/pull/6541): Delete an unused hook +- [#6534](https://github.com/MetaMask/metamask-mobile/pull/6534): feat(action): remove labels after issue closed +- [#6569](https://github.com/MetaMask/metamask-mobile/pull/6569): feat(release): 7.0.1 merge main +- [#6570](https://github.com/MetaMask/metamask-mobile/pull/6570): feat: Translations for the disconnected account toast +- [#6560](https://github.com/MetaMask/metamask-mobile/pull/6560): Fix asset page header transition +- [#6452](https://github.com/MetaMask/metamask-mobile/pull/6452): [MC 0.5] - Add Account management actions +- [#6530](https://github.com/MetaMask/metamask-mobile/pull/6530): chore: pending review feedback for token details related changes +- [#6554](https://github.com/MetaMask/metamask-mobile/pull/6554): feat: Translations for permissions management +- [#6473](https://github.com/MetaMask/metamask-mobile/pull/6473): bugfix: fix for swaps button displaying on unsupported networks +- [#6547](https://github.com/MetaMask/metamask-mobile/pull/6547): feat(release): 7.0.0 +- [#6511](https://github.com/MetaMask/metamask-mobile/pull/6511): test: Send ETH with Gas API Down - Introducing Mock Responses +- [#6464](https://github.com/MetaMask/metamask-mobile/pull/6464): Fix bug domain not shown on signature +- [#6543](https://github.com/MetaMask/metamask-mobile/pull/6543): ci(bitrise): fix pod install step +- [#6401](https://github.com/MetaMask/metamask-mobile/pull/6401): refactor: handle watch asset accept and reject using ApprovalController only +- [#6529](https://github.com/MetaMask/metamask-mobile/pull/6529): adding english string for advanced settings eth_sign warning +- [#6521](https://github.com/MetaMask/metamask-mobile/pull/6521): feat: translation for settings +- [#6517](https://github.com/MetaMask/metamask-mobile/pull/6517): fix: remove duplicate ganache steps definitions +- [#6026](https://github.com/MetaMask/metamask-mobile/pull/6026): Add toggle to enable/disable multi account balances fetching +- [#5591](https://github.com/MetaMask/metamask-mobile/pull/5591): feat: Custom Spend Allowance +- [#6426](https://github.com/MetaMask/metamask-mobile/pull/6426): feat: Componentize ListItem +- [#6514](https://github.com/MetaMask/metamask-mobile/pull/6514): feat: Componentize BottomSheetFooter +- [#6466](https://github.com/MetaMask/metamask-mobile/pull/6466): feat: componentize BottomSheetHeader +- [#6512](https://github.com/MetaMask/metamask-mobile/pull/6512): upgrade to cocoapods 1.12.0 +- [#6437](https://github.com/MetaMask/metamask-mobile/pull/6437): ci(bitrise):Build Pipelines for just Android & iOS Store +- [#6299](https://github.com/MetaMask/metamask-mobile/pull/6299): fix: for from address balance shown for ERC20 transfers +- [#6294](https://github.com/MetaMask/metamask-mobile/pull/6294): feat: [MC 0.5] - Activity view and Settings on the tab bar +- [#6462](https://github.com/MetaMask/metamask-mobile/pull/6462): ci(SonarCloud): enable test coverage analysis +- [#6478](https://github.com/MetaMask/metamask-mobile/pull/6478): ci(validation): PR Title Validation Run on Every Edit +- [#6486](https://github.com/MetaMask/metamask-mobile/pull/6486): feat: Add disabled prop on base button +- [#6471](https://github.com/MetaMask/metamask-mobile/pull/6471): Approve default ERC20 +- [#6487](https://github.com/MetaMask/metamask-mobile/pull/6487): add new Show test networks translation +- [#6357](https://github.com/MetaMask/metamask-mobile/pull/6357): refactor: use approval controller for watch asset confirmation ## 7.1.0 - Jun 20, 2023 - [#6334](https://github.com/MetaMask/metamask-mobile/pull/6334): feat: Aurora Token Detection diff --git a/android/app/build.gradle b/android/app/build.gradle index fa09f2621a9..9dc4e5c68d2 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -159,8 +159,8 @@ android { applicationId "io.metamask" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 1136 - versionName "7.1.0" + versionCode 1137 + versionName "7.2.0" multiDexEnabled true testBuildType System.getProperty('testBuildType', 'debug') missingDimensionStrategy "minReactNative", "minReactNative46" diff --git a/bitrise.yml b/bitrise.yml index ed37dceb586..9c6271e1043 100644 --- a/bitrise.yml +++ b/bitrise.yml @@ -702,10 +702,10 @@ app: PROJECT_LOCATION_IOS: ios - opts: is_expand: false - VERSION_NAME: 7.1.0 + VERSION_NAME: 7.2.0 - opts: is_expand: false - VERSION_NUMBER: 1136 + VERSION_NUMBER: 1137 - opts: is_expand: false ANDROID_APK_LINK: '' diff --git a/ios/MetaMask.xcodeproj/project.pbxproj b/ios/MetaMask.xcodeproj/project.pbxproj index 1239d5672ce..95545c1269c 100644 --- a/ios/MetaMask.xcodeproj/project.pbxproj +++ b/ios/MetaMask.xcodeproj/project.pbxproj @@ -1132,7 +1132,7 @@ CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMaskDebug.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1136; + CURRENT_PROJECT_VERSION = 1137; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 48XVW22RCG; @@ -1168,7 +1168,7 @@ "\"$(SRCROOT)/MetaMask/System/Library/Frameworks\"", ); LLVM_LTO = YES; - MARKETING_VERSION = 7.1.0; + MARKETING_VERSION = 7.2.0; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = ( "$(inherited)", @@ -1199,7 +1199,7 @@ CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMask.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1136; + CURRENT_PROJECT_VERSION = 1137; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 48XVW22RCG; ENABLE_BITCODE = NO; @@ -1235,7 +1235,7 @@ "\"$(SRCROOT)/MetaMask/System/Library/Frameworks\"", ); LLVM_LTO = YES; - MARKETING_VERSION = 7.1.0; + MARKETING_VERSION = 7.2.0; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = ( "$(inherited)", @@ -1345,7 +1345,7 @@ CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMaskDebug.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1136; + CURRENT_PROJECT_VERSION = 1137; DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 48XVW22RCG; @@ -1381,7 +1381,7 @@ "\"$(SRCROOT)/MetaMask/System/Library/Frameworks\"", ); LLVM_LTO = YES; - MARKETING_VERSION = 7.1.0; + MARKETING_VERSION = 7.2.0; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = ( "$(inherited)", @@ -1412,7 +1412,7 @@ CODE_SIGN_ENTITLEMENTS = MetaMask/MetaMask.entitlements; CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; - CURRENT_PROJECT_VERSION = 1136; + CURRENT_PROJECT_VERSION = 1137; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 48XVW22RCG; ENABLE_BITCODE = NO; @@ -1448,7 +1448,7 @@ "\"$(SRCROOT)/MetaMask/System/Library/Frameworks\"", ); LLVM_LTO = YES; - MARKETING_VERSION = 7.1.0; + MARKETING_VERSION = 7.2.0; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = ( "$(inherited)", diff --git a/package.json b/package.json index de5c6ded87c..5f3388ade5f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "metamask", - "version": "7.1.0", + "version": "7.2.0", "private": true, "scripts": { "audit:ci": "./scripts/yarn-audit.sh", From a779bd9bc02ace898d064af9e5e457e1f4ef8b9d Mon Sep 17 00:00:00 2001 From: Chris Wilcox Date: Wed, 21 Jun 2023 16:07:48 -0700 Subject: [PATCH 02/17] change view ID back to proper view to scroll down (#6669) --- .../Settings/SecurityAndPrivacy/SecurityAndPrivacyView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/pages/Drawer/Settings/SecurityAndPrivacy/SecurityAndPrivacyView.js b/e2e/pages/Drawer/Settings/SecurityAndPrivacy/SecurityAndPrivacyView.js index a21c515ae68..499e57c1a50 100644 --- a/e2e/pages/Drawer/Settings/SecurityAndPrivacy/SecurityAndPrivacyView.js +++ b/e2e/pages/Drawer/Settings/SecurityAndPrivacy/SecurityAndPrivacyView.js @@ -39,7 +39,7 @@ export default class SecurityAndPrivacy { await TestHelpers.swipe(SECURITY_SETTINGS_SCROLL_ID, 'up', 'fast'); await TestHelpers.delay(1000); } else { - await TestHelpers.swipe(CHANGE_PASSWORD_TITLE_ID, 'up', 'fast', 0.9); + await TestHelpers.swipe(SECURITY_SETTINGS_SCROLL_ID, 'up', 'fast', 0.9); } //await TestHelpers.swipe(PRIVACY_MODE_SECTION_ID, 'up', 'fast'); } From 5746d0d462069b39b2ba355865e1c594c61ba503 Mon Sep 17 00:00:00 2001 From: tommasini <46944231+tommasini@users.noreply.github.com> Date: Fri, 23 Jun 2023 16:10:36 +0100 Subject: [PATCH 03/17] fix: Migration not returning state (#6675) --- app/store/migrations.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/store/migrations.js b/app/store/migrations.js index ac7bcb3d2cf..b63e13022cc 100644 --- a/app/store/migrations.js +++ b/app/store/migrations.js @@ -425,6 +425,7 @@ export const migrations = { if (state.engine.backgroundState.TokensController.suggestedAssets) { delete state.engine.backgroundState.TokensController.suggestedAssets; } + return state; }, }; From 774d4adb29f45bd224ff59d1949df41d130fc711 Mon Sep 17 00:00:00 2001 From: Sylva Elendu Date: Fri, 23 Jun 2023 17:36:11 +0100 Subject: [PATCH 04/17] fix: Approving an ERC20 token with an amount with more decimals than expected crashes approving (#6623) * fix: Support Decimal Comma for Token Custom Spend Cap (#6637) * should replace decimal comma to decimal dots * check that value is a number before saving * token decimal value should not be greater than token decimal * improve test ids * improve variable naming * rebased to main --- .../CustomInput/CustomInput.constants.ts | 7 ++- .../CustomInput/CustomInput.test.tsx | 43 ++++++++++++++ .../CustomInput/CustomInput.tsx | 21 ++++++- .../CustomInput/CustomInput.types.ts | 1 + .../__snapshots__/CustomInput.test.tsx.snap | 4 +- .../CustomSpendCap/CustomSpendCap.test.tsx | 1 + .../CustomSpendCap/CustomSpendCap.tsx | 2 + .../CustomSpendCap/CustomSpendCap.types.ts | 4 ++ .../CustomSpendCap.test.tsx.snap | 4 +- .../UI/ApproveTransactionReview/index.js | 14 +++-- app/util/number/index.js | 8 +++ app/util/number/index.test.ts | 56 ++++++++++++------- 12 files changed, 131 insertions(+), 34 deletions(-) diff --git a/app/component-library/components-temp/CustomSpendCap/CustomInput/CustomInput.constants.ts b/app/component-library/components-temp/CustomSpendCap/CustomInput/CustomInput.constants.ts index 0584b27380c..2364089e924 100644 --- a/app/component-library/components-temp/CustomSpendCap/CustomInput/CustomInput.constants.ts +++ b/app/component-library/components-temp/CustomSpendCap/CustomInput/CustomInput.constants.ts @@ -1,3 +1,4 @@ -const CUSTOM_INPUT_TEST_ID = 'custom-input-test-id'; - -export default CUSTOM_INPUT_TEST_ID; +export const CUSTOM_SPEND_CAP_INPUT_TEST_ID = 'custom-spend-cap-input-test-id'; +export const CUSTOM_SPEND_CAP_MAX_TEST_ID = 'custom-spend-cap-max-test-id'; +export const CUSTOM_SPEND_CAP_INPUT_INPUT_ID = + 'custom-spend-cap-input-input-id'; diff --git a/app/component-library/components-temp/CustomSpendCap/CustomInput/CustomInput.test.tsx b/app/component-library/components-temp/CustomSpendCap/CustomInput/CustomInput.test.tsx index d5548f0386b..00e11f8fff7 100644 --- a/app/component-library/components-temp/CustomSpendCap/CustomInput/CustomInput.test.tsx +++ b/app/component-library/components-temp/CustomSpendCap/CustomInput/CustomInput.test.tsx @@ -6,6 +6,10 @@ import React from 'react'; import { TICKER } from '../CustomSpendCap.constants'; // Internal dependencies. import CustomInput from './CustomInput'; +import { + CUSTOM_SPEND_CAP_INPUT_INPUT_ID, + CUSTOM_SPEND_CAP_MAX_TEST_ID, +} from './CustomInput.constants'; import { CustomInputProps } from './CustomInput.types'; describe('CustomInput', () => { @@ -19,6 +23,7 @@ describe('CustomInput', () => { isEditDisabled: false, setMaxSelected: jest.fn(), setValue: jest.fn(), + tokenDecimal: 4, }; }); @@ -28,4 +33,42 @@ describe('CustomInput', () => { const component = renderComponent(); expect(component).toMatchSnapshot(); }); + + it('should call setMaxSelected when max button is pressed', () => { + const component = renderComponent(); + component + .findWhere((node) => node.prop('testID') === CUSTOM_SPEND_CAP_MAX_TEST_ID) + .simulate('press'); + expect(props.setMaxSelected).toHaveBeenCalled(); + }); + + it('should update value if input is integer', () => { + const component = renderComponent(); + component + .findWhere( + (node) => node.prop('testID') === CUSTOM_SPEND_CAP_INPUT_INPUT_ID, + ) + .simulate('changeText', '123'); + expect(props.setValue).toHaveBeenCalledWith('123'); + }); + + it('should update value if input is decimal and decimal points are less than or equal to tokenDecimal', () => { + const component = renderComponent(); + component + .findWhere( + (node) => node.prop('testID') === CUSTOM_SPEND_CAP_INPUT_INPUT_ID, + ) + .simulate('changeText', '123.1234'); + expect(props.setValue).toHaveBeenCalledWith('123.1234'); + }); + + it('should not update value if input is decimal and decimal points are greater than tokenDecimal', () => { + const component = renderComponent(); + component + .findWhere( + (node) => node.prop('testID') === CUSTOM_SPEND_CAP_INPUT_INPUT_ID, + ) + .simulate('changeText', '123.1234567'); + expect(props.setValue).not.toHaveBeenCalled(); + }); }); diff --git a/app/component-library/components-temp/CustomSpendCap/CustomInput/CustomInput.tsx b/app/component-library/components-temp/CustomSpendCap/CustomInput/CustomInput.tsx index 3283f32a7ff..ba3d881e2fd 100644 --- a/app/component-library/components-temp/CustomSpendCap/CustomInput/CustomInput.tsx +++ b/app/component-library/components-temp/CustomSpendCap/CustomInput/CustomInput.tsx @@ -4,10 +4,15 @@ import { TextInput, View } from 'react-native'; import { strings } from '../../../../../locales/i18n'; import formatNumber from '../../../../util/formatNumber'; +import { dotAndCommaDecimalFormatter } from '../../../../util/number'; import Text, { TextVariant } from '../../../components/Texts/Text'; // External dependencies. import { useStyles } from '../../../hooks'; -import CUSTOM_INPUT_TEST_ID from './CustomInput.constants'; +import { + CUSTOM_SPEND_CAP_INPUT_INPUT_ID, + CUSTOM_SPEND_CAP_INPUT_TEST_ID, + CUSTOM_SPEND_CAP_MAX_TEST_ID, +} from './CustomInput.constants'; import stylesheet from './CustomInput.styles'; // Internal dependencies. import { CustomInputProps } from './CustomInput.types'; @@ -19,9 +24,17 @@ const CustomInput = ({ isInputGreaterThanBalance, setValue, isEditDisabled, + tokenDecimal, }: CustomInputProps) => { const handleUpdate = (text: string) => { - setValue(text); + const decimalIndex = text.indexOf('.'); + const fractionalLength = text.substring(decimalIndex + 1).length; + + if (decimalIndex !== -1 && fractionalLength > Number(tokenDecimal)) { + return; + } + + setValue(dotAndCommaDecimalFormatter(text)); }; const handleMaxPress = () => { @@ -48,11 +61,12 @@ const CustomInput = ({ backgroundColor: colors.background.alternative, }, ]} - testID={CUSTOM_INPUT_TEST_ID} + testID={CUSTOM_SPEND_CAP_INPUT_TEST_ID} > {!isEditDisabled ? ( {!isEditDisabled && ( @@ -57,6 +58,7 @@ exports[`CustomInput should render correctly 1`] = ` "color": "#535A61", } } + testID="custom-spend-cap-max-test-id" variant="sBodySM" > Max diff --git a/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.test.tsx b/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.test.tsx index 0a564f89879..48b814ff636 100644 --- a/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.test.tsx +++ b/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.test.tsx @@ -30,6 +30,7 @@ function RenderCustomSpendCap( editValue={() => ({})} tokenSpendValue={tokenSpendValue} isInputValid={isInputValid} + tokenDecimal={18} /> ); } diff --git a/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.tsx b/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.tsx index a49675af402..f913af35c9a 100644 --- a/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.tsx +++ b/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.tsx @@ -28,6 +28,7 @@ const CustomSpendCap = ({ editValue, tokenSpendValue, isInputValid, + tokenDecimal, }: CustomSpendCapProps) => { const { styles, @@ -218,6 +219,7 @@ const CustomSpendCap = ({ setMaxSelected={setMaxSelected} value={value} isEditDisabled={isEditDisabled} + tokenDecimal={tokenDecimal} /> {value.length > 0 && inputHasError && ( diff --git a/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.types.ts b/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.types.ts index 8b4172c9ba1..6436415100f 100644 --- a/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.types.ts +++ b/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.types.ts @@ -24,4 +24,8 @@ export interface CustomSpendCapProps { * isInputValid - function to check if input is valid and has no errors */ isInputValid: (value: boolean) => boolean; + /** + * tokenDecimal - token decimal number + */ + tokenDecimal?: number; } diff --git a/app/component-library/components-temp/CustomSpendCap/__snapshots__/CustomSpendCap.test.tsx.snap b/app/component-library/components-temp/CustomSpendCap/__snapshots__/CustomSpendCap.test.tsx.snap index 7b6419829be..3e9930ed430 100644 --- a/app/component-library/components-temp/CustomSpendCap/__snapshots__/CustomSpendCap.test.tsx.snap +++ b/app/component-library/components-temp/CustomSpendCap/__snapshots__/CustomSpendCap.test.tsx.snap @@ -107,7 +107,7 @@ exports[`CustomSpendCap should match snapshot 1`] = ` false, ] } - testID="custom-input-test-id" + testID="custom-spend-cap-input-test-id" > @@ -155,6 +156,7 @@ exports[`CustomSpendCap should match snapshot 1`] = ` "lineHeight": 20, } } + testID="custom-spend-cap-max-test-id" > Max diff --git a/app/components/UI/ApproveTransactionReview/index.js b/app/components/UI/ApproveTransactionReview/index.js index ecd50b53e6f..422270d4a05 100644 --- a/app/components/UI/ApproveTransactionReview/index.js +++ b/app/components/UI/ApproveTransactionReview/index.js @@ -24,6 +24,7 @@ import { GAS_ESTIMATE_TYPES } from '@metamask/gas-fee-controller'; import { hexToBN } from '@metamask/controller-utils'; import { fromTokenMinimalUnit, + isNumber, renderFromTokenMinimalUnit, } from '../../../util/number'; import { @@ -863,15 +864,18 @@ class ApproveTransactionReview extends PureComponent { dappProposedValue={originalApproveAmount} tokenSpendValue={tokenSpendValue} accountBalance={tokenBalance} + tokenDecimal={tokenDecimals} domain={host} isEditDisabled={Boolean(isReadyToApprove)} editValue={this.goToSpendCap} isInputValid={this.customSpendInputValid} - onInputChanged={(value) => - this.setState({ - tokenSpendValue: value.replace(/[^0-9.]/g, ''), - }) - } + onInputChanged={(value) => { + if (isNumber(value)) { + this.setState({ + tokenSpendValue: value.replace(/[^0-9.]/g, ''), + }); + } + }} /> ) )} diff --git a/app/util/number/index.js b/app/util/number/index.js index f108356f9dc..9d8196c17f7 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -361,6 +361,14 @@ export function isNumber(str) { return /^(\d+(\.\d+)?)$/.test(str); } +export const dotAndCommaDecimalFormatter = (value) => { + const valueStr = String(value); + + const formattedValue = valueStr.replace(',', '.'); + + return formattedValue; +}; + /** * Determines whether the given number is going to be * displalyed in scientific notation after being converted to a string. diff --git a/app/util/number/index.test.ts b/app/util/number/index.test.ts index a8f6a1e5e0b..6fcd2e8d251 100644 --- a/app/util/number/index.test.ts +++ b/app/util/number/index.test.ts @@ -1,36 +1,38 @@ import { BN } from 'ethereumjs-util'; + import { + addCurrencySymbol, + balanceToFiat, + balanceToFiatNumber, BNToHex, - fromWei, + calcTokenValueToSend, + calculateEthFeeForMultiLayer, + dotAndCommaDecimalFormatter, + fastSplit, + fiatNumberToTokenMinimalUnit, + fiatNumberToWei, fromTokenMinimalUnit, fromTokenMinimalUnitString, - toTokenMinimalUnit, - renderFromTokenMinimalUnit, - renderFromWei, - calcTokenValueToSend, + fromWei, + handleWeiNumber, hexToBN, isBN, isDecimal, - toWei, - weiToFiat, - weiToFiatNumber, - fiatNumberToWei, - fiatNumberToTokenMinimalUnit, - balanceToFiat, - balanceToFiatNumber, - renderFiat, - handleWeiNumber, - toHexadecimal, - safeNumberToBN, - fastSplit, isNumber, isNumberScientificNotationWhenString, - calculateEthFeeForMultiLayer, - limitToMaximumDecimalPlaces, isZeroValue, + limitToMaximumDecimalPlaces, + renderFiat, + renderFromTokenMinimalUnit, + renderFromWei, + safeNumberToBN, toBN, - addCurrencySymbol, -} from '.'; + toHexadecimal, + toTokenMinimalUnit, + toWei, + weiToFiat, + weiToFiatNumber, +} from './'; describe('Number utils :: BNToHex', () => { it('BNToHex', () => { @@ -728,6 +730,18 @@ describe('Number utils :: isNumber', () => { }); }); +describe('Number utils :: dotAndCommaDecimalFormatter', () => { + it('should return the number if it does not contain a dot or comma', () => { + expect(dotAndCommaDecimalFormatter('1650')).toBe('1650'); + }); + it('should return the number if it contains a dot', () => { + expect(dotAndCommaDecimalFormatter('1650.7')).toBe('1650.7'); + }); + it('should replace the comma with a decimal with a comma if it contains a dot', () => { + expect(dotAndCommaDecimalFormatter('1650,7')).toBe('1650.7'); + }); +}); + describe('Number utils :: isNumberScientificNotationWhenString', () => { it('isNumberScientificNotationWhenString passing number', () => { expect(isNumberScientificNotationWhenString(1.337e-6)).toEqual(false); From ae3c7895dc7e563344ad068c4a60083712e1768c Mon Sep 17 00:00:00 2001 From: Sylva Elendu Date: Mon, 26 Jun 2023 14:25:15 +0100 Subject: [PATCH 05/17] fix: Token allowance flow update (#6619) * token allowance flow * failing test * lint * moved url * updated copy changes * undefined to null * rebased to release --- .../CustomSpendCap/CustomSpendCap.stories.tsx | 4 +- .../CustomSpendCap/CustomSpendCap.test.tsx | 18 +++---- .../CustomSpendCap/CustomSpendCap.tsx | 50 +++++++++---------- .../CustomSpendCap/CustomSpendCap.types.ts | 5 +- .../CustomSpendCap.test.tsx.snap | 23 +++++++-- .../ShowBlockExplorer/index.tsx | 26 ++++++---- .../UI/ApproveTransactionReview/index.js | 20 +++++--- app/constants/urls.ts | 2 + locales/languages/de.json | 3 -- locales/languages/el.json | 3 -- locales/languages/en.json | 19 ++++--- locales/languages/es.json | 3 -- locales/languages/fr.json | 3 -- locales/languages/hi.json | 3 -- locales/languages/id.json | 3 -- locales/languages/ja.json | 3 -- locales/languages/ko.json | 3 -- locales/languages/pt.json | 3 -- locales/languages/ru.json | 3 -- locales/languages/tl.json | 3 -- locales/languages/tr.json | 3 -- locales/languages/vi.json | 3 -- locales/languages/zh.json | 3 -- 23 files changed, 99 insertions(+), 110 deletions(-) diff --git a/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.stories.tsx b/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.stories.tsx index 3f8b4d962c5..c4efb87a9d8 100644 --- a/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.stories.tsx +++ b/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.stories.tsx @@ -7,7 +7,6 @@ import CustomSpendCap from './CustomSpendCap'; // Internal dependencies. import { ACCOUNT_BALANCE, - DAPP_DOMAIN, DAPP_PROPOSED_VALUE, INPUT_VALUE_CHANGED, TICKER, @@ -18,10 +17,11 @@ storiesOf('Component Library / CustomSpendCap', module).add('Default', () => ( ticker={TICKER} accountBalance={ACCOUNT_BALANCE} dappProposedValue={DAPP_PROPOSED_VALUE} - domain={DAPP_DOMAIN} onInputChanged={INPUT_VALUE_CHANGED} isEditDisabled={false} editValue={() => undefined} tokenSpendValue={''} + toggleLearnMoreWebPage={() => undefined} + isInputValid={() => true} /> )); diff --git a/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.test.tsx b/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.test.tsx index 48b814ff636..dd6cf5b73b6 100644 --- a/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.test.tsx +++ b/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.test.tsx @@ -7,8 +7,6 @@ import CustomSpendCap from './CustomSpendCap'; import { ACCOUNT_BALANCE, CUSTOM_SPEND_CAP_TEST_ID, - DAPP_DOMAIN, - DAPP_PROPOSED_VALUE, INPUT_VALUE_CHANGED, TICKER, } from './CustomSpendCap.constants'; @@ -23,14 +21,14 @@ function RenderCustomSpendCap( ({})} tokenSpendValue={tokenSpendValue} isInputValid={isInputValid} tokenDecimal={18} + toggleLearnMoreWebPage={() => undefined} /> ); } @@ -64,7 +62,7 @@ describe('CustomSpendCap', () => { expect( await findByText( - `Only enter a number that you're comfortable with ${DAPP_DOMAIN} accessing now or in the future. You can always increase the token limit later.`, + `Only enter a number that you're comfortable with the third party spending now or in the future. You can always increase the spending cap later. Learn more`, ), ).toBeDefined(); }); @@ -82,13 +80,15 @@ describe('CustomSpendCap', () => { it('should render valid message if value is greater than account balance', async () => { const valueGreaterThanBalance = '300'; - const valueDifference = - Number(valueGreaterThanBalance) - Number(ACCOUNT_BALANCE); - const { toJSON } = renderWithProvider( + const { findByText } = renderWithProvider( RenderCustomSpendCap(valueGreaterThanBalance), ); - expect(JSON.stringify(toJSON())).toMatch(`${valueDifference} ${TICKER}`); + expect( + await findByText( + 'This allows the third party to spend all your token balance until it reaches the cap or you revoke the spending cap. If this is not intended, consider setting a lower spending cap. Learn more', + ), + ).toBeDefined(); }); it('should call isInputValid with false if value is not a number', async () => { diff --git a/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.tsx b/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.tsx index f913af35c9a..bf2853889f3 100644 --- a/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.tsx +++ b/app/component-library/components-temp/CustomSpendCap/CustomSpendCap.tsx @@ -1,10 +1,10 @@ -import BigNumber from 'bignumber.js'; // Third party dependencies. import React, { useEffect, useState } from 'react'; import { Pressable, View } from 'react-native'; import { strings } from '../../../../locales/i18n'; import InfoModal from '../../../components/UI/Swaps/components/InfoModal'; +import { TOKEN_APPROVAL_SPENDING_CAP } from '../../../constants/urls'; import formatNumber from '../../../util/formatNumber'; import { isNumber } from '../../../util/number'; import Button, { ButtonVariants } from '../../components/Buttons/Button'; @@ -22,13 +22,13 @@ const CustomSpendCap = ({ ticker, dappProposedValue, accountBalance, - domain, onInputChanged, isEditDisabled, editValue, tokenSpendValue, isInputValid, tokenDecimal, + toggleLearnMoreWebPage, }: CustomSpendCapProps) => { const { styles, @@ -59,6 +59,12 @@ const CustomSpendCap = ({ isInputValid(!inputHasError); }, [inputHasError, isInputValid]); + useEffect(() => { + if (dappProposedValue) { + setValue(dappProposedValue); + } + }, [dappProposedValue]); + const handleDefaultValue = () => { setMaxSelected(false); setValue(dappProposedValue); @@ -74,10 +80,6 @@ const CustomSpendCap = ({ if (maxSelected) setValue(accountBalance); }, [maxSelected, accountBalance]); - const newValue = new BigNumber(value); - - const difference = newValue.minus(accountBalance).toFixed(); - useEffect(() => { if (Number(value) > Number(accountBalance)) return setInputValueHigherThanAccountBalance(true); @@ -95,22 +97,11 @@ const CustomSpendCap = ({ ); const NO_SELECTED = strings( - 'contract_allowance.custom_spend_cap.no_value_selected', - { domain }, + 'contract_allowance.custom_spend_cap.default_error_message', ); - const INPUT_VALUE_GREATER_THAN_ACCOUNT_BALANCE = ( - <> - {strings('contract_allowance.custom_spend_cap.this_contract_allows')} - - {` ${formatNumber(accountBalance)} ${ticker} `} - - {strings('contract_allowance.custom_spend_cap.from_your_current_balance')} - - {` ${formatNumber(difference)} ${ticker} `} - - {strings('contract_allowance.custom_spend_cap.future_tokens')} - + const INPUT_VALUE_GREATER_THAN_ACCOUNT_BALANCE = strings( + 'contract_allowance.custom_spend_cap.amount_greater_than_balance', ); const INPUT_VALUE_LOWER_THAN_ACCOUNT_BALANCE = ( @@ -156,6 +147,9 @@ const CustomSpendCap = ({ message = INPUT_VALUE_LOWER_THAN_ACCOUNT_BALANCE; } + const openLearnMore = () => + toggleLearnMoreWebPage(TOKEN_APPROVAL_SPENDING_CAP); + return ( {isModalVisible ? ( @@ -169,10 +163,7 @@ const CustomSpendCap = ({ 'contract_allowance.custom_spend_cap.info_modal_description_default', ) : strings( - 'contract_allowance.custom_spend_cap.no_value_selected', - { - domain, - }, + 'contract_allowance.custom_spend_cap.default_error_message', )} } @@ -207,7 +198,9 @@ const CustomSpendCap = ({ label={ isEditDisabled ? strings('contract_allowance.custom_spend_cap.edit') - : strings('contract_allowance.custom_spend_cap.use_default') + : strings( + 'contract_allowance.custom_spend_cap.use_site_suggestion', + ) } /> @@ -230,7 +223,12 @@ const CustomSpendCap = ({ {!isEditDisabled && ( - {message} + {message}{' '} +