From 915357d4eb8e8685ac97598265083373465cba9a Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Wed, 23 Oct 2024 10:18:25 +0000 Subject: [PATCH 01/57] fix(deps): unpin ethereumjs-abi@0.6,x ethereumjs-util@6.x --- package.json | 7 +++--- yarn.lock | 68 ++++++++++++++++++++-------------------------------- 2 files changed, 30 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index 49309856adfb..ae50c1d01657 100644 --- a/package.json +++ b/package.json @@ -242,8 +242,8 @@ "eth-json-rpc-filters": "^6.0.1", "eth-json-rpc-middleware": "9.0.1", "eth-url-parser": "1.0.4", - "ethereumjs-abi": "0.6.6", - "ethereumjs-util": "6.1.0", + "ethereumjs-abi": "^0.6.8", + "ethereumjs-util": "^6.2.0", "ethers": "^5.0.14", "ethjs-ens": "2.0.1", "eventemitter2": "^6.4.9", @@ -575,7 +575,8 @@ "@metamask/sdk-communication-layer>eciesjs>secp256k1": false, "detox>ws>utf-8-validate": false, "ganache>@trufflesuite/uws-js-unofficial>utf-8-validate": false, - "@react-native-firebase/app>firebase>@firebase/firestore>@grpc/proto-loader>protobufjs": false + "@react-native-firebase/app>firebase>@firebase/firestore>@grpc/proto-loader>protobufjs": false, + "ethereumjs-util>ethereum-cryptography>keccak": true } }, "packageManager": "yarn@1.22.22" diff --git a/yarn.lock b/yarn.lock index 0de7e3f473c7..d44a5f98f6ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9471,6 +9471,13 @@ dependencies: "@types/node" "*" +"@types/bn.js@^4.11.3": + version "4.11.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" + integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== + dependencies: + "@types/node" "*" + "@types/bn.js@^5.1.0", "@types/bn.js@^5.1.5": version "5.1.5" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.5.tgz#2e0dacdcce2c0f16b905d20ff87aedbc6f7b4bf0" @@ -13317,7 +13324,7 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bindings@^1.2.1, bindings@^1.5.0: +bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== @@ -13378,7 +13385,7 @@ bn.js@5.2.1, bn.js@^5.0.0, bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.12.0: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.12.0: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== @@ -17100,39 +17107,26 @@ ethereum-ens-network-map@^1.0.0: resolved "https://registry.yarnpkg.com/ethereum-ens-network-map/-/ethereum-ens-network-map-1.0.2.tgz#4e27bad18dae7bd95d84edbcac2c9e739fc959b9" integrity sha512-5qwJ5n3YhjSpE6O/WEBXCAb2nagUgyagJ6C0lGUBWC4LjKp/rRzD+pwtDJ6KCiITFEAoX4eIrWOjRy0Sylq5Hg== -ethereumjs-abi@0.6.6: - version "0.6.6" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.6.tgz#f8ba3413a98478173f5a00f7f1316819db1d09ec" - integrity sha512-w8KubDsA/+OAuqtIR9RGsMcoZ5nhM8vxwjJAJvEIY+clhxA3BHoLG3+ClYQaQhD0n3mlDt3U5rBrmSVJvI3c8A== - dependencies: - bn.js "^4.10.0" - ethereumjs-util "^5.0.0" - -ethereumjs-util@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz#e9c51e5549e8ebd757a339cc00f5380507e799c8" - integrity sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q== +ethereumjs-abi@^0.6.8: + version "0.6.8" + resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" + integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== dependencies: - bn.js "^4.11.0" - create-hash "^1.1.2" - ethjs-util "0.1.6" - keccak "^1.0.2" - rlp "^2.0.0" - safe-buffer "^5.1.1" - secp256k1 "^3.0.1" + bn.js "^4.11.8" + ethereumjs-util "^6.0.0" -ethereumjs-util@^5.0.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz#a833f0e5fca7e5b361384dc76301a721f537bf65" - integrity sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ== +ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" + integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== dependencies: + "@types/bn.js" "^4.11.3" bn.js "^4.11.0" create-hash "^1.1.2" elliptic "^6.5.2" ethereum-cryptography "^0.1.3" - ethjs-util "^0.1.3" - rlp "^2.0.0" - safe-buffer "^5.1.1" + ethjs-util "0.1.6" + rlp "^2.2.3" ethereumjs-util@^7.0.10, ethereumjs-util@^7.0.8, ethereumjs-util@^7.1.2: version "7.1.5" @@ -17281,7 +17275,7 @@ ethjs-util@0.1.3: is-hex-prefixed "1.0.0" strip-hex-prefix "1.0.0" -ethjs-util@0.1.6, ethjs-util@^0.1.3, ethjs-util@^0.1.6: +ethjs-util@0.1.6, ethjs-util@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== @@ -21095,16 +21089,6 @@ keccak@3.0.2, keccak@^3.0.0: node-gyp-build "^4.2.0" readable-stream "^3.6.0" -keccak@^1.0.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-1.4.0.tgz#572f8a6dbee8e7b3aa421550f9e6408ca2186f80" - integrity sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw== - dependencies: - bindings "^1.2.1" - inherits "^2.0.3" - nan "^2.2.1" - safe-buffer "^5.1.0" - keygrip@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226" @@ -22784,7 +22768,7 @@ mz@^2.7.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nan@^2.14.0, nan@^2.2.1: +nan@^2.14.0: version "2.20.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.20.0.tgz#08c5ea813dd54ed16e5bd6505bf42af4f7838ca3" integrity sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw== @@ -26492,7 +26476,7 @@ ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: hash-base "^3.0.0" inherits "^2.0.1" -rlp@^2.0.0, rlp@^2.2.4, rlp@^2.2.6: +rlp@^2.2.3, rlp@^2.2.4, rlp@^2.2.6: version "2.2.7" resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== @@ -26683,7 +26667,7 @@ scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== -secp256k1@3.8.1, secp256k1@^3.0.1: +secp256k1@3.8.1: version "3.8.1" resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.8.1.tgz#b62a62a882d6b16f9b51fe599c6b3a861e36c59f" integrity sha512-tArjQw2P0RTdY7QmkNehgp6TVvQXq6ulIhxv8gaH6YubKG/wxxAoNKcbuXjDhybbc+b2Ihc7e0xxiGN744UIiQ== From 64e9f80c3f2792f52932c37087f11393ac862827 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Wed, 23 Oct 2024 10:45:58 +0000 Subject: [PATCH 02/57] fix: add package @types/bn.js --- .depcheckrc.yml | 2 ++ package.json | 1 + yarn.lock | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.depcheckrc.yml b/.depcheckrc.yml index 36e2bc04bb1b..00959f049235 100644 --- a/.depcheckrc.yml +++ b/.depcheckrc.yml @@ -9,6 +9,8 @@ ignores: - 'babel-plugin-inline-import' # This is used on the patch for TokenRatesController of Assets controllers, for we to be able to use the last version of it - cockatiel + # Force intended major version of @types/bn.js used by TypeScript + - '@types/bn.js' # Note: Everything below this line should be removed after investigation # TODO: Investigate each dependency to see whether it's used diff --git a/package.json b/package.json index ae50c1d01657..aad6dff4ffba 100644 --- a/package.json +++ b/package.json @@ -392,6 +392,7 @@ "@testing-library/react": "14.0.0", "@testing-library/react-hooks": "^8.0.1", "@testing-library/react-native": "12.1.2", + "@types/bn.js": "^4.11.6", "@types/crypto-js": "^4.1.1", "@types/enzyme": "^3.10.12", "@types/eth-url-parser": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index d44a5f98f6ef..d93dedffd85d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9471,7 +9471,7 @@ dependencies: "@types/node" "*" -"@types/bn.js@^4.11.3": +"@types/bn.js@^4.11.3", "@types/bn.js@^4.11.6": version "4.11.6" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== From 82d9427edb3212bc2d52f5495223246aa43c955f Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Wed, 23 Oct 2024 11:44:17 +0000 Subject: [PATCH 03/57] fix: import BN.js directly instead of through ethereumjs-util - to get correct types - to prepare upgrading to versions which don't provide the re-export - fix: vendor BNToHex and hexToBN in order to use bn.js v4 - fix: explicitly use either bn.js@4 and bn.js@5 - Why mixing v4 and v5 is A Bad Thing: https://github.com/ethereumjs/ethereumjs-util/issues/250 --- app/components/Nav/Main/RootRPCMethodsUI.js | 2 +- .../ConfirmAddAsset/ConfirmAddAsset.test.tsx | 4 +- .../Ramp/Views/BuildQuote/BuildQuote.test.tsx | 18 +- .../UI/Ramp/Views/BuildQuote/BuildQuote.tsx | 12 +- .../Views/SendTransaction/SendTransaction.tsx | 4 +- app/components/UI/Ramp/hooks/useBalance.ts | 2 +- .../UI/Ramp/hooks/useGasPriceEstimation.ts | 2 +- .../UI/Ramp/hooks/useIntentAmount.ts | 2 +- .../StakeInputView/StakeInputView.test.tsx | 4 +- .../UnstakeInputView/UnstakeInputView.tsx | 4 +- .../StakingBalance/StakingBalance.tsx | 6 +- .../UI/Stake/hooks/useStakingInput.ts | 14 +- .../TokenList/PortfolioBalance/index.test.tsx | 8 +- app/components/UI/Tokens/index.test.tsx | 10 +- .../components/TransactionEditor/index.js | 3 +- .../confirmations/SendFlow/Amount/index.js | 3 +- .../SendFlow/Confirm/validation.test.ts | 2 +- .../SendFlow/Confirm/validation.ts | 12 +- .../useAddressBalance.test.tsx | 4 +- .../useAddressBalance/useAddressBalance.ts | 4 +- app/components/hooks/useTokenBalance.tsx | 12 +- .../useTokenBalancesController.test.tsx | 8 +- app/constants/transaction.ts | 2 +- app/util/confirmation/transactions.test.ts | 2 +- app/util/conversion/index.js | 3 +- app/util/custom-gas/index.js | 2 +- app/util/dappTransactions/index.test.ts | 2 +- app/util/dappTransactions/index.ts | 30 ++-- app/util/number/index.js | 57 ++++--- app/util/number/index.test.ts | 157 +++++++++--------- app/util/transaction-reducer-helpers.ts | 2 +- app/util/transactions/index.js | 3 +- app/util/transactions/index.test.ts | 2 +- package.json | 5 +- yarn.lock | 26 ++- 35 files changed, 237 insertions(+), 196 deletions(-) diff --git a/app/components/Nav/Main/RootRPCMethodsUI.js b/app/components/Nav/Main/RootRPCMethodsUI.js index 086d3c3a61f7..310fa254e2e6 100644 --- a/app/components/Nav/Main/RootRPCMethodsUI.js +++ b/app/components/Nav/Main/RootRPCMethodsUI.js @@ -25,7 +25,7 @@ import { getIsSwapApproveOrSwapTransaction, isApprovalTransaction, } from '../../../util/transactions'; -import { BN } from 'ethereumjs-util'; +import BN from 'bnjs4'; import Logger from '../../../util/Logger'; import TransactionTypes from '../../../core/TransactionTypes'; import { swapsUtils } from '@metamask/swaps-controller'; diff --git a/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx b/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx index ed1a2f5fdc3a..b3109f95aa86 100644 --- a/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx +++ b/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx @@ -7,7 +7,7 @@ import renderWithProvider, { import useBalance from '../Ramp/hooks/useBalance'; import { toTokenMinimalUnit } from '../../../util/number'; import { fireEvent } from '@testing-library/react-native'; -import { BN } from 'ethereumjs-util'; +import BN4 from 'bnjs4'; import { RootState } from '../../../reducers'; import { mockNetworkState } from '../../../util/test/network'; import { CHAIN_IDS } from '@metamask/transaction-controller'; @@ -48,7 +48,7 @@ jest.mock('../../../util/navigation/navUtils', () => ({ const mockUseBalanceInitialValue: Partial> = { balanceFiat: '$27.02', - balanceBN: toTokenMinimalUnit('5.36385', 18) as BN, + balanceBN: toTokenMinimalUnit('5.36385', 18) as BN4, }; const mockUseBalanceValues: Partial> = { diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx index 9fb61eadebcf..0a1eaf582210 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Limits, Payment } from '@consensys/on-ramp-sdk'; import { act, fireEvent, screen } from '@testing-library/react-native'; -import { BN } from 'ethereumjs-util'; +import type BN4 from 'bnjs4'; import { renderScreen } from '../../../../../util/test/renderWithProvider'; import BuildQuote from './BuildQuote'; import useRegions from '../../hooks/useRegions'; @@ -191,7 +191,7 @@ jest.mock('../../../../hooks/useAddressBalance/useAddressBalance', () => const mockUseBalanceInitialValue: Partial> = { balanceFiat: '$27.02', - balanceBN: toTokenMinimalUnit('5.36385', 18) as BN, + balanceBN: toTokenMinimalUnit('5.36385', 18) as BN4, }; let mockUseBalanceValues: Partial> = { @@ -242,7 +242,7 @@ const mockUseGasPriceEstimationInitialValue: ReturnType< estimatedGasFee: toTokenMinimalUnit( '0.01', mockUseRampSDKInitialValues.selectedAsset?.decimals || 18, - ) as BN, + ) as BN4, }; let mockUseGasPriceEstimationValue: ReturnType = @@ -669,7 +669,7 @@ describe('BuildQuote View', () => { mockUseBalanceValues.balanceBN = toTokenMinimalUnit( '5', mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN; + ) as BN4; render(BuildQuote); const initialAmount = '0'; const overBalanceAmout = '6'; @@ -688,7 +688,7 @@ describe('BuildQuote View', () => { mockUseBalanceValues.balanceBN = toTokenMinimalUnit( '1', mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN; + ) as BN4; const symbol = mockUseRampSDKValues.selectedAsset?.symbol; fireEvent.press(getByRoleButton(`${initialAmount} ${symbol}`)); fireEvent.press(getByRoleButton('25%')); @@ -719,13 +719,13 @@ describe('BuildQuote View', () => { balanceBN: toTokenMinimalUnit( '1', mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN, + ) as BN4, }; mockUseGasPriceEstimationValue = { estimatedGasFee: toTokenMinimalUnit( '0.27', mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN, + ) as BN4, }; const symbol = mockUseRampSDKValues.selectedAsset?.symbol; fireEvent.press(getByRoleButton(`${initialAmount} ${symbol}`)); @@ -752,13 +752,13 @@ describe('BuildQuote View', () => { balanceBN: toTokenMinimalUnit( '1', mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN, + ) as BN4, }; mockUseGasPriceEstimationValue = { estimatedGasFee: toTokenMinimalUnit( '0.27', mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN, + ) as BN4, }; const symbol = mockUseRampSDKValues.selectedAsset?.symbol; fireEvent.press(getByRoleButton(`${initialAmount} ${symbol}`)); diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx index 04727253c4be..565210a8e3d9 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx @@ -12,7 +12,7 @@ import Animated, { withTiming, } from 'react-native-reanimated'; import { useNavigation } from '@react-navigation/native'; -import { BN } from 'ethereumjs-util'; +import BN4 from 'bnjs4'; import { useRampSDK } from '../../sdk'; import usePaymentMethods from '../../hooks/usePaymentMethods'; @@ -104,7 +104,7 @@ const BuildQuote = () => { const [amountFocused, setAmountFocused] = useState(false); const [amount, setAmount] = useState('0'); const [amountNumber, setAmountNumber] = useState(0); - const [amountBNMinimalUnit, setAmountBNMinimalUnit] = useState(); + const [amountBNMinimalUnit, setAmountBNMinimalUnit] = useState(); const [error, setError] = useState(null); const keyboardHeight = useRef(1000); const keypadOffset = useSharedValue(1000); @@ -341,7 +341,7 @@ const BuildQuote = () => { setAmountNumber(valueAsNumber); if (isSell) { setAmountBNMinimalUnit( - toTokenMinimalUnit(`${value}`, selectedAsset?.decimals ?? 0) as BN, + toTokenMinimalUnit(`${value}`, selectedAsset?.decimals ?? 0) as BN4, ); } }, @@ -356,8 +356,8 @@ const BuildQuote = () => { } else { const percentage = value * 100; const amountPercentage = balanceBN - ?.mul(new BN(percentage)) - .div(new BN(100)); + ?.mul(new BN4(percentage)) + .div(new BN4(100)); if (!amountPercentage) { return; @@ -698,7 +698,7 @@ const BuildQuote = () => { value: quickAmount, label: currentFiatCurrency?.denomSymbol + quickAmount.toString(), })) ?? []; - } else if (balanceBN && !balanceBN.isZero() && maxSellAmount?.gt(new BN(0))) { + } else if (balanceBN && !balanceBN.isZero() && maxSellAmount?.gt(new BN4(0))) { quickAmounts = [ { value: 0.25, label: '25%' }, { value: 0.5, label: '50%' }, diff --git a/app/components/UI/Ramp/Views/SendTransaction/SendTransaction.tsx b/app/components/UI/Ramp/Views/SendTransaction/SendTransaction.tsx index ac4927aa503e..a0197dad4a26 100644 --- a/app/components/UI/Ramp/Views/SendTransaction/SendTransaction.tsx +++ b/app/components/UI/Ramp/Views/SendTransaction/SendTransaction.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { ImageSourcePropType, View } from 'react-native'; import { useDispatch, useSelector } from 'react-redux'; import { useNavigation } from '@react-navigation/native'; -import { BN } from 'ethereumjs-util'; +import BN4 from 'bnjs4'; import { SellOrder } from '@consensys/on-ramp-sdk/dist/API'; import { TransactionParams, @@ -132,7 +132,7 @@ function SendTransaction() { setIsConfirming(true); let transactionParams: TransactionParams; const amount = addHexPrefix( - new BN( + new BN4( toTokenMinimalUnit( orderData.cryptoAmount || '0', orderData.cryptoCurrency.decimals, diff --git a/app/components/UI/Ramp/hooks/useBalance.ts b/app/components/UI/Ramp/hooks/useBalance.ts index 4c2e52afecb6..93d9ee02ff82 100644 --- a/app/components/UI/Ramp/hooks/useBalance.ts +++ b/app/components/UI/Ramp/hooks/useBalance.ts @@ -1,5 +1,4 @@ import { useSelector } from 'react-redux'; -import { hexToBN } from '@metamask/controller-utils'; import { NATIVE_ADDRESS } from '../../../../constants/on-ramp'; import { selectAccountsByChainId } from '../../../../selectors/accountTrackerController'; import { @@ -13,6 +12,7 @@ import { selectChainId } from '../../../../selectors/networkController'; import { safeToChecksumAddress } from '../../../../util/address'; import { balanceToFiat, + hexToBN, renderFromTokenMinimalUnit, renderFromWei, toHexadecimal, diff --git a/app/components/UI/Ramp/hooks/useGasPriceEstimation.ts b/app/components/UI/Ramp/hooks/useGasPriceEstimation.ts index 6c9565b94f6f..f0c6b69ad825 100644 --- a/app/components/UI/Ramp/hooks/useGasPriceEstimation.ts +++ b/app/components/UI/Ramp/hooks/useGasPriceEstimation.ts @@ -5,7 +5,7 @@ import { type GasFeeController as GasFeeControllerType, } from '@metamask/gas-fee-controller'; -import { BN } from 'ethereumjs-util'; +import BN from 'bnjs4'; import Engine from '../../../../core/Engine'; import { decGWEIToHexWEI } from '../../../../util/conversions'; import { selectGasFeeControllerState } from '../../../../selectors/gasFeeController'; diff --git a/app/components/UI/Ramp/hooks/useIntentAmount.ts b/app/components/UI/Ramp/hooks/useIntentAmount.ts index 7b024731c3db..6d5aaf6f474b 100644 --- a/app/components/UI/Ramp/hooks/useIntentAmount.ts +++ b/app/components/UI/Ramp/hooks/useIntentAmount.ts @@ -1,5 +1,5 @@ import { useEffect } from 'react'; -import { type BN } from 'ethereumjs-util'; +import type BN from 'bnjs4'; import { useRampSDK } from '../sdk'; import parseAmount from '../utils/parseAmount'; import { toTokenMinimalUnit } from '../../../../util/number'; diff --git a/app/components/UI/Stake/Views/StakeInputView/StakeInputView.test.tsx b/app/components/UI/Stake/Views/StakeInputView/StakeInputView.test.tsx index 906391284715..fd7a9f4b211d 100644 --- a/app/components/UI/Stake/Views/StakeInputView/StakeInputView.test.tsx +++ b/app/components/UI/Stake/Views/StakeInputView/StakeInputView.test.tsx @@ -4,7 +4,7 @@ import StakeInputView from './StakeInputView'; import { renderScreen } from '../../../../../util/test/renderWithProvider'; import Routes from '../../../../../constants/navigation/Routes'; import { backgroundState } from '../../../../../util/test/initial-root-state'; -import { BN } from 'ethereumjs-util'; +import BN5 from 'bnjs5'; import { Stake } from '../../sdk/stakeSdkProvider'; import { ChainId, PooledStakingContract } from '@metamask/stake-sdk'; import { Contract } from 'ethers'; @@ -54,7 +54,7 @@ jest.mock('../../../../../selectors/currencyRateController.ts', () => ({ selectCurrentCurrency: jest.fn(() => 'USD'), })); -const mockBalanceBN = new BN('1500000000000000000'); +const mockBalanceBN = new BN5('1500000000000000000'); const mockPooledStakingContractService: PooledStakingContract = { chainId: ChainId.ETHEREUM, diff --git a/app/components/UI/Stake/Views/UnstakeInputView/UnstakeInputView.tsx b/app/components/UI/Stake/Views/UnstakeInputView/UnstakeInputView.tsx index ddfa676d158e..801db04ccb3c 100644 --- a/app/components/UI/Stake/Views/UnstakeInputView/UnstakeInputView.tsx +++ b/app/components/UI/Stake/Views/UnstakeInputView/UnstakeInputView.tsx @@ -1,6 +1,6 @@ import { useNavigation } from '@react-navigation/native'; import React, { useCallback, useEffect } from 'react'; -import { BN } from 'ethereumjs-util'; +import BN4 from 'bnjs4'; import UnstakeInputViewBanner from './UnstakeBanner'; import { strings } from '../../../../../../locales/i18n'; import Button, { @@ -43,7 +43,7 @@ const UnstakeInputView = () => { handleAmountPress, handleKeypadChange, conversionRate, - } = useStakingInputHandlers(new BN(stakedBalanceWei)); + } = useStakingInputHandlers(new BN4(stakedBalanceWei)); const stakeBalanceInEth = renderFromWei(stakedBalanceWei, 5); const stakeBalanceFiatNumber = weiToFiatNumber( diff --git a/app/components/UI/Stake/components/StakingBalance/StakingBalance.tsx b/app/components/UI/Stake/components/StakingBalance/StakingBalance.tsx index e70630ab9016..1f5dd15f15f2 100644 --- a/app/components/UI/Stake/components/StakingBalance/StakingBalance.tsx +++ b/app/components/UI/Stake/components/StakingBalance/StakingBalance.tsx @@ -24,7 +24,7 @@ import { strings } from '../../../../../../locales/i18n'; import { renderFromWei } from '../../../../../util/number'; import { getTimeDifferenceFromNow } from '../../../../../util/date'; import { filterExitRequests } from './utils'; -import { BN } from 'ethereumjs-util'; +import BN4 from 'bnjs4'; import bn from 'bignumber.js'; import { CommonPercentageInputUnits, @@ -82,8 +82,8 @@ const StakingBalanceContent = ({ asset }: StakingBalanceProps) => { renderFromWei( claimableRequests.reduce( (acc, { claimedAssets }) => - claimedAssets ? acc.add(new BN(claimedAssets)) : acc, - new BN(0), + claimedAssets ? acc.add(new BN4(claimedAssets)) : acc, + new BN4(0), ), ), [claimableRequests], diff --git a/app/components/UI/Stake/hooks/useStakingInput.ts b/app/components/UI/Stake/hooks/useStakingInput.ts index 7424703e0f1f..5f2d53ee57d1 100644 --- a/app/components/UI/Stake/hooks/useStakingInput.ts +++ b/app/components/UI/Stake/hooks/useStakingInput.ts @@ -1,4 +1,4 @@ -import { BN } from 'ethereumjs-util'; +import BN4 from 'bnjs4'; import { useState, useMemo, useCallback } from 'react'; import { useSelector } from 'react-redux'; import { @@ -17,15 +17,15 @@ import { import { strings } from '../../../../../locales/i18n'; import useVaultData from './useVaultData'; -const useStakingInputHandlers = (balance: BN) => { +const useStakingInputHandlers = (balance: BN4) => { const [amountEth, setAmountEth] = useState('0'); - const [amountWei, setAmountWei] = useState(new BN(0)); + const [amountWei, setAmountWei] = useState(new BN4(0)); const [estimatedAnnualRewards, setEstimatedAnnualRewards] = useState('-'); - const isNonZeroAmount = useMemo(() => amountWei.gt(new BN(0)), [amountWei]); + const isNonZeroAmount = useMemo(() => amountWei.gt(new BN4(0)), [amountWei]); const isOverMaximum = useMemo(() => { - const additionalFundsRequired = amountWei.sub(balance || new BN(0)); - return isNonZeroAmount && additionalFundsRequired.gt(new BN(0)); + const additionalFundsRequired = amountWei.sub(balance || new BN4(0)); + return isNonZeroAmount && additionalFundsRequired.gt(new BN4(0)); }, [amountWei, balance, isNonZeroAmount]); const [fiatAmount, setFiatAmount] = useState('0'); @@ -92,7 +92,7 @@ const useStakingInputHandlers = (balance: BN) => { ({ value }: { value: number }) => { if (!balance) return; const percentage = value * 100; - const amountPercentage = balance.mul(new BN(percentage)).div(new BN(100)); + const amountPercentage = balance.mul(new BN4(percentage)).div(new BN4(100)); const newAmountString = fromTokenMinimalUnitString( amountPercentage.toString(10), diff --git a/app/components/UI/Tokens/TokenList/PortfolioBalance/index.test.tsx b/app/components/UI/Tokens/TokenList/PortfolioBalance/index.test.tsx index e1e1f6943769..680d81843003 100644 --- a/app/components/UI/Tokens/TokenList/PortfolioBalance/index.test.tsx +++ b/app/components/UI/Tokens/TokenList/PortfolioBalance/index.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent } from '@testing-library/react-native'; -import { BN } from 'ethereumjs-util'; +import BN5 from 'bnjs5'; import renderWithProvider from '../../../../../util/test/renderWithProvider'; import { backgroundState } from '../../../../../util/test/initial-root-state'; import AppConstants from '../../../../../../app/core/AppConstants'; @@ -70,9 +70,9 @@ const initialState = { }, TokenBalancesController: { contractBalances: { - '0x00': new BN(2), - '0x01': new BN(2), - '0x02': new BN(0), + '0x00': new BN5(2), + '0x01': new BN5(2), + '0x02': new BN5(0), }, }, }, diff --git a/app/components/UI/Tokens/index.test.tsx b/app/components/UI/Tokens/index.test.tsx index 60b1fb20eceb..379384746e01 100644 --- a/app/components/UI/Tokens/index.test.tsx +++ b/app/components/UI/Tokens/index.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; // eslint-disable-next-line @typescript-eslint/no-shadow import { fireEvent, waitFor } from '@testing-library/react-native'; import Tokens from './'; -import { BN } from 'ethereumjs-util'; +import BN5 from 'bnjs5'; import renderWithProvider from '../../../util/test/renderWithProvider'; import { createStackNavigator } from '@react-navigation/stack'; import { getAssetTestId } from '../../../../wdio/screen-objects/testIDs/Screens/WalletView.testIds'; @@ -109,9 +109,9 @@ const initialState = { }, TokenBalancesController: { contractBalances: { - '0x00': new BN(2), - '0x01': new BN(2), - '0x02': new BN(0), + '0x00': new BN5(2), + '0x01': new BN5(2), + '0x02': new BN5(0), }, }, }, @@ -262,7 +262,7 @@ describe('Tokens', () => { }, TokenBalancesController: { contractBalances: { - '0x02': new BN(1), + '0x02': new BN5(1), }, }, }, diff --git a/app/components/Views/confirmations/Approval/components/TransactionEditor/index.js b/app/components/Views/confirmations/Approval/components/TransactionEditor/index.js index 5e607dfbef88..69863ccdfb18 100644 --- a/app/components/Views/confirmations/Approval/components/TransactionEditor/index.js +++ b/app/components/Views/confirmations/Approval/components/TransactionEditor/index.js @@ -9,7 +9,8 @@ import { renderFromWei, toHexadecimal, } from '../../../../../../util/number'; -import { isValidAddress, BN, addHexPrefix } from 'ethereumjs-util'; +import { isValidAddress, addHexPrefix } from 'ethereumjs-util'; +import BN from 'bnjs4'; import { strings } from '../../../../../../../locales/i18n'; import { connect } from 'react-redux'; import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'; diff --git a/app/components/Views/confirmations/SendFlow/Amount/index.js b/app/components/Views/confirmations/SendFlow/Amount/index.js index f2bd09ddc3a9..7b8837653214 100644 --- a/app/components/Views/confirmations/SendFlow/Amount/index.js +++ b/app/components/Views/confirmations/SendFlow/Amount/index.js @@ -60,7 +60,6 @@ import CollectibleMedia from '../../../../UI/CollectibleMedia'; import collectiblesTransferInformation from '../../../../../util/collectibles-transfer'; import { strings } from '../../../../../../locales/i18n'; import Device from '../../../../../util/device'; -import { BN } from 'ethereumjs-util'; import { MetaMetricsEvents } from '../../../../../core/Analytics'; import dismissKeyboard from 'react-native/Libraries/Utilities/dismissKeyboard'; import NetworkMainAssetLogo from '../../../../UI/NetworkMainAssetLogo'; @@ -893,7 +892,7 @@ class Amount extends PureComponent { const balanceBN = hexToBN(accounts[selectedAddress].balance); const realMaxValue = balanceBN.sub(estimatedTotalGas); const maxValue = - balanceBN.isZero() || realMaxValue.isNeg() ? new BN(0) : realMaxValue; + balanceBN.isZero() || realMaxValue.isNeg() ? hexToBN('0x0') : realMaxValue; if (internalPrimaryCurrencyIsCrypto) { input = fromWei(maxValue); } else { diff --git a/app/components/Views/confirmations/SendFlow/Confirm/validation.test.ts b/app/components/Views/confirmations/SendFlow/Confirm/validation.test.ts index e9ed1b98278d..8da1c4c3ac3e 100644 --- a/app/components/Views/confirmations/SendFlow/Confirm/validation.test.ts +++ b/app/components/Views/confirmations/SendFlow/Confirm/validation.test.ts @@ -1,4 +1,4 @@ -import { BN } from 'ethereumjs-util'; +import BN from 'bnjs4'; import { validateSufficientBalance, validateSufficientTokenBalance } from './validation'; import { renderFromWei, hexToBN } from '../../../../../util/number'; import { diff --git a/app/components/Views/confirmations/SendFlow/Confirm/validation.ts b/app/components/Views/confirmations/SendFlow/Confirm/validation.ts index 884c939441ed..461ffd62e966 100644 --- a/app/components/Views/confirmations/SendFlow/Confirm/validation.ts +++ b/app/components/Views/confirmations/SendFlow/Confirm/validation.ts @@ -4,7 +4,7 @@ import { decodeTransferData, } from '../../../../../util/transactions'; import { strings } from '../../../../../../locales/i18n'; -import { BN } from 'ethereumjs-util'; +import type BN4 from 'bnjs4'; interface SelectedAsset { address: string; @@ -13,8 +13,8 @@ interface SelectedAsset { } export const generateInsufficientBalanceMessage = ( - weiBalance: BN, - transactionValue: BN, + weiBalance: BN4, + transactionValue: BN4, ticker: string, ) => { const amount = renderFromWei(transactionValue.sub(weiBalance)); @@ -25,7 +25,7 @@ export const generateInsufficientBalanceMessage = ( }); }; -export const validateBalance = (weiBalance: BN, transactionValue: BN) => +export const validateBalance = (weiBalance: BN4, transactionValue: BN4) => !weiBalance.gte(transactionValue) || weiBalance.isZero(); export const validateSufficientTokenBalance = ( @@ -49,8 +49,8 @@ export const validateSufficientTokenBalance = ( }; export const validateSufficientBalance = ( - weiBalance: BN, - totalTransactionValue: BN, + weiBalance: BN4, + totalTransactionValue: BN4, ticker: string, ) => { if (validateBalance(weiBalance, totalTransactionValue)) { diff --git a/app/components/hooks/useAddressBalance/useAddressBalance.test.tsx b/app/components/hooks/useAddressBalance/useAddressBalance.test.tsx index f3f8592d8a8f..769ce5db0678 100644 --- a/app/components/hooks/useAddressBalance/useAddressBalance.test.tsx +++ b/app/components/hooks/useAddressBalance/useAddressBalance.test.tsx @@ -8,7 +8,7 @@ import { Asset } from './useAddressBalance.types'; import useAddressBalance from './useAddressBalance'; import backgroundState from '../../../util/test/initial-root-state'; import { createMockAccountsControllerState } from '../../../util/test/accountsControllerTestUtils'; -import { BN } from 'ethereumjs-util'; +import type BN5 from 'bnjs5'; const MOCK_ADDRESS_1 = '0x0'; const MOCK_ADDRESS_2 = '0x1'; @@ -65,7 +65,7 @@ describe('useAddressBalance', () => { address: string, selectedAddress: string, networkClientId?: string | undefined, - ) => Promise; + ) => Promise; beforeEach(() => { mockGetERC20BalanceOf = jest .fn() diff --git a/app/components/hooks/useAddressBalance/useAddressBalance.ts b/app/components/hooks/useAddressBalance/useAddressBalance.ts index af95e0187e32..dcdf9e1acc5f 100644 --- a/app/components/hooks/useAddressBalance/useAddressBalance.ts +++ b/app/components/hooks/useAddressBalance/useAddressBalance.ts @@ -1,6 +1,7 @@ import { ERC1155, ERC721 } from '@metamask/controller-utils'; import { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; +import BN4 from 'bnjs4'; import Engine from '../../../core/Engine'; import { getTicker } from '../../../util/transactions'; @@ -110,7 +111,8 @@ const useAddressBalance = ( address, ); fromAccBalance = `${renderFromTokenMinimalUnit( - fromAccBalance || '0', + // This is to work around incompatibility between bn.js v4/v5 - should be removed when migration to v5 is complete + new BN4(fromAccBalance?.toString(10) || '0', 10), decimals, )} ${symbol}`; setAddressBalance(fromAccBalance); diff --git a/app/components/hooks/useTokenBalance.tsx b/app/components/hooks/useTokenBalance.tsx index 8962c9ce352f..f4d84786a613 100644 --- a/app/components/hooks/useTokenBalance.tsx +++ b/app/components/hooks/useTokenBalance.tsx @@ -1,6 +1,6 @@ import { useState, useEffect, Dispatch, SetStateAction } from 'react'; import Engine from '../../core/Engine'; -import { BN } from 'ethereumjs-util'; +import type BN4 from 'bnjs4'; /** * Hook to handle the balance of ERC20 tokens @@ -12,12 +12,12 @@ import { BN } from 'ethereumjs-util'; const useTokenBalance = ( requestedTokenAddress: string, userCurrentAddress: string, -): [BN | null, boolean, boolean] => { +): [BN4 | null, boolean, boolean] => { // This hook should be only used with ERC20 tokens const [tokenBalance, setTokenBalance]: [ - BN | null, - Dispatch>, - ] = useState(null); + BN4 | null, + Dispatch>, + ] = useState(null); const [loading, setLoading]: [boolean, Dispatch>] = useState(true); const [error, setError]: [boolean, Dispatch>] = @@ -31,7 +31,7 @@ const useTokenBalance = ( userAddress: string, ): Promise => { AssetsContractController.getERC20BalanceOf(tokenAddress, userAddress) - .then((balance: BN) => setTokenBalance(balance)) + .then((balance: BN4) => setTokenBalance(balance)) .catch(() => setError(true)) .finally(() => setLoading(false)); }; diff --git a/app/components/hooks/useTokenBalancesController/useTokenBalancesController.test.tsx b/app/components/hooks/useTokenBalancesController/useTokenBalancesController.test.tsx index b575c66c4cc8..aaf33d56db3b 100644 --- a/app/components/hooks/useTokenBalancesController/useTokenBalancesController.test.tsx +++ b/app/components/hooks/useTokenBalancesController/useTokenBalancesController.test.tsx @@ -4,7 +4,7 @@ import { Provider } from 'react-redux'; import { createStore, Store } from 'redux'; import { act, render, waitFor } from '@testing-library/react-native'; import useTokenBalancesController from './useTokenBalancesController'; -import { BN } from 'ethereumjs-util'; +import BN4 from 'bnjs4'; import { cloneDeep } from 'lodash'; import { backgroundState } from '../../../util/test/initial-root-state'; @@ -15,7 +15,7 @@ const mockInitialState = { ...backgroundState, TokenBalancesController: { contractBalances: { - '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': new BN(0x2a), + '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': new BN4(0x2a), }, }, }, @@ -104,7 +104,7 @@ describe('useTokenBalancesController()', () => { testStore.dispatch({ type: 'add-balances', value: { - '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b96': new BN(0x539), + '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b96': new BN4(0x539), }, }); }); @@ -122,7 +122,7 @@ describe('useTokenBalancesController()', () => { testStore.dispatch({ type: 'add-balances', value: { - '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': new BN(0x2a), + '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': new BN4(0x2a), }, }); }); diff --git a/app/constants/transaction.ts b/app/constants/transaction.ts index 92bde7b16483..38612646e437 100644 --- a/app/constants/transaction.ts +++ b/app/constants/transaction.ts @@ -1,4 +1,4 @@ -import { BN } from 'ethereumjs-util'; +import BN from 'bnjs4'; // Transaction Status export const TX_UNAPPROVED = 'unapproved'; diff --git a/app/util/confirmation/transactions.test.ts b/app/util/confirmation/transactions.test.ts index 1c124ff1fd68..1bda3144e944 100644 --- a/app/util/confirmation/transactions.test.ts +++ b/app/util/confirmation/transactions.test.ts @@ -1,4 +1,4 @@ -import { BN } from 'ethereumjs-util'; +import BN from 'bnjs4'; import { buildTransactionParams } from './transactions'; import { GAS_ESTIMATE_TYPES } from '@metamask/gas-fee-controller'; import { TransactionEnvelopeType } from '@metamask/transaction-controller'; diff --git a/app/util/conversion/index.js b/app/util/conversion/index.js index 4046c7277244..d65cb6853974 100644 --- a/app/util/conversion/index.js +++ b/app/util/conversion/index.js @@ -22,8 +22,9 @@ */ import BigNumber from 'bignumber.js'; +import BN from 'bnjs4'; -import { stripHexPrefix, BN } from 'ethereumjs-util'; +import { stripHexPrefix } from 'ethereumjs-util'; // Big Number Constants const BIG_NUMBER_WEI_MULTIPLIER = new BigNumber('1000000000000000000'); diff --git a/app/util/custom-gas/index.js b/app/util/custom-gas/index.js index 3583b88fab3c..b8c611c6be9d 100644 --- a/app/util/custom-gas/index.js +++ b/app/util/custom-gas/index.js @@ -1,4 +1,4 @@ -import { BN } from 'ethereumjs-util'; +import BN from 'bnjs4'; import { renderFromWei, weiToFiat, toWei, conversionUtil } from '../number'; import { strings } from '../../../locales/i18n'; import TransactionTypes from '../../core/TransactionTypes'; diff --git a/app/util/dappTransactions/index.test.ts b/app/util/dappTransactions/index.test.ts index f4c625d0518b..150e559b98db 100644 --- a/app/util/dappTransactions/index.test.ts +++ b/app/util/dappTransactions/index.test.ts @@ -1,4 +1,4 @@ -import { BN } from 'ethereumjs-util'; +import BN from 'bnjs4'; import { strings } from '../../../locales/i18n'; import Engine from '../../core/Engine'; diff --git a/app/util/dappTransactions/index.ts b/app/util/dappTransactions/index.ts index d2d93d8fd74e..3629203a35ff 100644 --- a/app/util/dappTransactions/index.ts +++ b/app/util/dappTransactions/index.ts @@ -4,7 +4,7 @@ import Engine from '../../core/Engine'; import TransactionTypes from '../../core/TransactionTypes'; import { toLowerCaseEquals } from '../general'; import { strings } from '../../../locales/i18n'; -import { BN } from 'ethereumjs-util'; +import BN4 from 'bnjs4'; import { lt } from '../lodash'; import { estimateGas as controllerEstimateGas } from '../transaction-controller'; @@ -25,8 +25,8 @@ interface Transaction { data: string; ensRecipient: string | undefined; from: string; - gas: BN; - gasPrice: BN; + gas: BN4; + gasPrice: BN4; id: string; nonce: string | undefined; origin: string; @@ -97,7 +97,7 @@ export const estimateGas = async ( * @returns {string} - String containing error message whether the Ether transaction amount is valid or not */ export const validateEtherAmount = ( - value: BN, + value: BN4, from: string, allowEmpty = true, ): string | undefined => { @@ -122,8 +122,8 @@ interface ContractBalances { * @returns {string} - String containing error message whether the Ether transaction amount is valid or not */ export const validateTokenAmount = async ( - value: BN, - gas: BN, + value: BN4, + gas: BN4, from: string, selectedAsset: SelectedAsset, selectedAddress: string, @@ -146,7 +146,7 @@ export const validateTokenAmount = async ( } // If user trying to send a token that doesn't own, validate balance querying contract // If it fails, skip validation - let contractBalanceForAddress: BN | undefined | number; + let contractBalanceForAddress: BN4 | undefined | number; if (selectedAddress === from && contractBalances[selectedAsset.address]) { contractBalanceForAddress = hexToBN( contractBalances[selectedAsset.address].toString(), @@ -154,11 +154,11 @@ export const validateTokenAmount = async ( } else { try { const { AssetsContractController } = Engine.context; - contractBalanceForAddress = - await AssetsContractController.getERC20BalanceOf( + contractBalanceForAddress = new BN4( + (await AssetsContractController.getERC20BalanceOf( selectedAsset.address, checksummedFrom, - ); + )).toString()); } catch (e) { // Don't validate balance if error } @@ -216,10 +216,10 @@ export const validateAmount = async ( const { value, from, gas, selectedAsset } = transaction; const validations: Validations = { - ETH: () => validateEtherAmount(value as unknown as BN, from, allowEmpty), + ETH: () => validateEtherAmount(value as unknown as BN4, from, allowEmpty), ERC20: async () => await validateTokenAmount( - value as unknown as BN, + value as unknown as BN4, gas, from, selectedAsset, @@ -276,8 +276,8 @@ type setTransactionObjectType = ( * @param {function} setTransactionObject - Sets any attribute in transaction object */ export const handleGasFeeSelection = ( - gasLimit: BN, - gasPrice: BN, + gasLimit: BN4, + gasPrice: BN4, setTransactionObject: setTransactionObjectType, ): void => { const transactionObject = { @@ -297,5 +297,5 @@ export const handleGetGasLimit = async ( ): Promise => { if (!Object.keys(transaction.selectedAsset).length) return; const { gas } = await estimateGas({}, transaction); - setTransactionObject({ gas: hexToBN(gas) as BN }); + setTransactionObject({ gas: hexToBN(gas) as BN4 }); }; diff --git a/app/util/number/index.js b/app/util/number/index.js index 28027c52b7ae..c3a76e42206d 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -1,20 +1,17 @@ /** * Collection of utility functions for consistent formatting and conversion */ -import { BN, stripHexPrefix } from 'ethereumjs-util'; +import { stripHexPrefix } from 'ethereumjs-util'; +import BN4 from 'bnjs4'; import { utils as ethersUtils } from 'ethers'; import convert from '@metamask/ethjs-unit'; -import { - BNToHex, - hexToBN as controllerHexToBN, -} from '@metamask/controller-utils'; +import { add0x, remove0x } from '@metamask/utils'; import numberToBN from 'number-to-bn'; import BigNumber from 'bignumber.js'; import currencySymbols from '../currency-symbols.json'; import { isZero } from '../lodash'; import { regex } from '../regex'; -export { BNToHex }; // Big Number Constants const BIG_NUMBER_WEI_MULTIPLIER = new BigNumber('1000000000000000000'); @@ -30,8 +27,20 @@ const BIG_NUMBER_ETH_MULTIPLIER = new BigNumber('1'); */ export const hexToBN = (inputHex) => typeof inputHex !== 'string' - ? new BN(inputHex, 16) - : controllerHexToBN(inputHex); + ? new BN4(inputHex, 16) + : (inputHex ? new BN4(remove0x(inputHex), 16) : new BN4(0)); + +/** + * Converts a BN object to a hex string with a '0x' prefix. + * + * @param inputBn - BN instance to convert to a hex string. + * @returns A '0x'-prefixed hex string. + */ +// TODO: Either fix this lint violation or explain why it's necessary to ignore. +// eslint-disable-next-line @typescript-eslint/naming-convention +export function BNToHex(inputBn) { + return add0x(inputBn.toString(16)); +} // Setter Maps const toBigNumber = { @@ -55,7 +64,7 @@ const toSpecifiedDenomination = { const baseChange = { hex: (n) => n.toString(16), dec: (n) => new BigNumber(n).toString(10), - BN: (n) => new BN(n.toString(16)), + BN: (n) => new BN4(n.toString(16)), }; /** @@ -107,7 +116,7 @@ export function fromTokenMinimalUnit( minimalInput = isRounding ? Number(minimalInput) : minimalInput; const prefixedInput = addHexPrefix(minimalInput.toString(16)); let minimal = safeNumberToBN(prefixedInput); - const negative = minimal.lt(new BN(0)); + const negative = minimal.lt(new BN4(0)); const base = toBN(Math.pow(10, decimals).toString()); if (negative) { @@ -151,7 +160,7 @@ export function fromTokenMinimalUnitString(minimalInput, decimals) { /** * Converts some unit to token minimal unit * - * @param {number|string|BN} tokenValue - Value to convert + * @param {number|string|BN4} tokenValue - Value to convert * @param {number} decimals - Unit to convert from, ether by default * @returns {Object} - BN instance containing the new number */ @@ -196,19 +205,19 @@ export function toTokenMinimalUnit(tokenValue, decimals) { while (fraction.length < decimals) { fraction += '0'; } - whole = new BN(whole); - fraction = new BN(fraction); + whole = new BN4(whole); + fraction = new BN4(fraction); let tokenMinimal = whole.mul(base).add(fraction); if (negative) { tokenMinimal = tokenMinimal.mul(negative); } - return new BN(tokenMinimal.toString(10), 10); + return new BN4(tokenMinimal.toString(10), 10); } /** * Converts some token minimal unit to render format string, showing 5 decimals * - * @param {Number|String|BN} tokenValue - Token value to convert + * @param {Number|String|BN4} tokenValue - Token value to convert * @param {Number} decimals - Token decimals to convert * @param {Number} decimalsToShow - Decimals to 5 * @returns {String} - Number of token minimal unit, in render format @@ -304,7 +313,7 @@ export function fiatNumberToTokenMinimalUnit( /** * Converts wei to render format string, showing 5 decimals * - * @param {Number|String|BN} value - Wei to convert + * @param {Number|String|BN4} value - Wei to convert * @param {Number} decimalsToShow - Decimals to 5 * @returns {String} - Number of token minimal unit, in render format * If value is less than 5 precision decimals will show '< 0.00001' @@ -343,7 +352,7 @@ export function calcTokenValueToSend(value, decimals) { * @returns {boolean} - True if the value is a BN instance */ export function isBN(value) { - return BN.isBN(value); + return BN4.isBN(value); } /** @@ -367,7 +376,7 @@ export function isDecimal(value) { * @returns {Object} - BN instance */ export function toBN(value) { - return new BN(value); + return new BN4(value); } /** @@ -408,9 +417,9 @@ export const isNumberScientificNotationWhenString = (value) => { /** * Converts some unit to wei * - * @param {number|string|BN} value - Value to convert + * @param {number|string|BN4} value - Value to convert * @param {string} unit - Unit to convert from, ether by default - * @returns {BN} - BN instance containing the new number + * @returns {BN4} - BN instance containing the new number */ export function toWei(value, unit = 'ether') { // check the posibilty to convert to BN @@ -424,7 +433,7 @@ export function toWei(value, unit = 'ether') { /** * Converts some unit to Gwei * - * @param {number|string|BN} value - Value to convert + * @param {number|string|BN4} value - Value to convert * @param {string} unit - Unit to convert from, ether by default * @returns {Object} - BN instance containing the new number */ @@ -435,7 +444,7 @@ export function toGwei(value, unit = 'ether') { /** * Converts some unit to Gwei and return it in render format * - * @param {number|string|BN} value - Value to convert + * @param {number|string|BN4} value - Value to convert * @param {string} unit - Unit to convert from, ether by default * @returns {string} - String instance containing the renderable number */ @@ -450,7 +459,7 @@ export function renderToGwei(value, unit = 'ether') { * Converts wei expressed as a BN instance into a human-readable fiat string * TODO: wei should be a BN instance, but we're not sure if it's always the case // - * @param {number | BN} wei - BN corresponding to an amount of wei + * @param {number | BN4} wei - BN corresponding to an amount of wei * @param {number | null} conversionRate - ETH to current currency conversion rate * @param {string} currencyCode - Current currency code to display * @returns {string} - Currency-formatted string @@ -528,7 +537,7 @@ export function addCurrencySymbol( /** * Converts wei expressed as a BN instance into a human-readable fiat string * - * @param {number|string|BN} wei - BN corresponding to an amount of wei + * @param {number|string|BN4} wei - BN corresponding to an amount of wei * @param {number} conversionRate - ETH to current currency conversion rate * @param {Number} decimalsToShow - Decimals to 5 * @returns {Number} - The converted balance diff --git a/app/util/number/index.test.ts b/app/util/number/index.test.ts index 436f18c0c29f..db8904ef7a91 100644 --- a/app/util/number/index.test.ts +++ b/app/util/number/index.test.ts @@ -1,4 +1,5 @@ -import { BN } from 'ethereumjs-util'; +import BN4 from 'bnjs4'; +import BN5 from 'bnjs5'; import { addCurrencySymbol, @@ -39,7 +40,7 @@ import { describe('Number utils :: BNToHex', () => { it('BNToHex', () => { - expect(BNToHex(new BN('1337'))).toEqual('0x539'); + expect(BNToHex(new BN5('1337'))).toEqual('0x539'); }); }); @@ -53,7 +54,7 @@ describe('Number utils :: fromWei', () => { }); it('fromWei using BN number', () => { - expect(fromWei(new BN('1337'))).toEqual('0.000000000000001337'); + expect(fromWei(new BN4('1337'))).toEqual('0.000000000000001337'); }); }); @@ -87,19 +88,19 @@ describe('Number utils :: toWei', () => { expect(() => toWei('1.337e-15')).toThrow(Error); }); - // bn.js do not support decimals, so tests here only cover integers + // bnjs4 do not support decimals, so tests here only cover integers it('toWei using BN number', () => { - expect(toWei(new BN(1337)).toString()).toEqual('1337000000000000000000'); + expect(toWei(new BN4(1337)).toString()).toEqual('1337000000000000000000'); // Tests for expected limitations of BN.js // BN.js do not support decimals - expect(toWei(new BN(1.337e-15)).toString()).toEqual('0'); + expect(toWei(new BN4(1.337e-15)).toString()).toEqual('0'); // BN.js do not support such big numbers - expect(() => toWei(new BN(1.337e18))).toThrow(Error); - expect(() => toWei(new BN(1337000000000000000))).toThrow(Error); + expect(() => toWei(new BN4(1.337e18))).toThrow(Error); + expect(() => toWei(new BN4(1337000000000000000))).toThrow(Error); // For some reason this returns 8338418000000000000000000 wei - expect(toWei(new BN('1.337e18'))).not.toEqual( + expect(toWei(new BN4('1.337e18'))).not.toEqual( '1337000000000000000000000000000000000', ); }); @@ -119,9 +120,9 @@ describe('Number utils :: fromTokenMinimalUnit', () => { }); it('fromTokenMinimalUnit using BN number', () => { - expect(fromTokenMinimalUnit(new BN('1337'), 6)).toEqual('0.001337'); - expect(fromTokenMinimalUnit(new BN('1337'), 0)).toEqual('1337'); - expect(fromTokenMinimalUnit(new BN('1337'), 18)).toEqual( + expect(fromTokenMinimalUnit(new BN4('1337'), 6)).toEqual('0.001337'); + expect(fromTokenMinimalUnit(new BN4('1337'), 0)).toEqual('1337'); + expect(fromTokenMinimalUnit(new BN4('1337'), 18)).toEqual( '0.000000000000001337', ); }); @@ -134,24 +135,24 @@ describe('Number utils :: fromTokenMinimalUnit', () => { }); it('rounds number by default', () => { - expect(fromTokenMinimalUnit(new BN('1000000000000000000'), 18)).toEqual( + expect(fromTokenMinimalUnit(new BN4('1000000000000000000'), 18)).toEqual( '1', ); - expect(fromTokenMinimalUnit(new BN('10000000000000000000'), 18)).toEqual( + expect(fromTokenMinimalUnit(new BN4('10000000000000000000'), 18)).toEqual( '10', ); - expect(fromTokenMinimalUnit(new BN('100000000000000000000'), 18)).toEqual( + expect(fromTokenMinimalUnit(new BN4('100000000000000000000'), 18)).toEqual( '100', ); - expect(fromTokenMinimalUnit(new BN('1000000000000000000000'), 18)).toEqual( + expect(fromTokenMinimalUnit(new BN4('1000000000000000000000'), 18)).toEqual( '1000', ); - expect(fromTokenMinimalUnit(new BN('10000000000000000000000'), 18)).toEqual( + expect(fromTokenMinimalUnit(new BN4('10000000000000000000000'), 18)).toEqual( '10000', ); // test decimal greater than 30,000 - expect(fromTokenMinimalUnit(new BN('50000000000000000000000'), 18)).toEqual( + expect(fromTokenMinimalUnit(new BN4('50000000000000000000000'), 18)).toEqual( '49999.999999999995805696', ); @@ -163,24 +164,24 @@ describe('Number utils :: fromTokenMinimalUnit', () => { it('does not round number if isRounding is false', () => { expect( - fromTokenMinimalUnit(new BN('1000000000000000000'), 18, false), + fromTokenMinimalUnit(new BN4('1000000000000000000'), 18, false), ).toEqual('1'); expect( - fromTokenMinimalUnit(new BN('10000000000000000000'), 18, false), + fromTokenMinimalUnit(new BN4('10000000000000000000'), 18, false), ).toEqual('10'); expect( - fromTokenMinimalUnit(new BN('100000000000000000000'), 18, false), + fromTokenMinimalUnit(new BN4('100000000000000000000'), 18, false), ).toEqual('100'); expect( - fromTokenMinimalUnit(new BN('1000000000000000000000'), 18, false), + fromTokenMinimalUnit(new BN4('1000000000000000000000'), 18, false), ).toEqual('1000'); expect( - fromTokenMinimalUnit(new BN('10000000000000000000000'), 18, false), + fromTokenMinimalUnit(new BN4('10000000000000000000000'), 18, false), ).toEqual('10000'); // test decimal greater than 30,000 expect( - fromTokenMinimalUnit(new BN('50000000000000000000000'), 18, false), + fromTokenMinimalUnit(new BN4('50000000000000000000000'), 18, false), ).toEqual('50000'); // test decimal less than 1e-14 @@ -281,67 +282,67 @@ describe('Number utils :: fromTokenMinimalUnitString', () => { }); it('fromTokenMinimalUnitString using BN number', () => { - expect(fromTokenMinimalUnitString(new BN('1337').toString(10), 6)).toEqual( + expect(fromTokenMinimalUnitString(new BN4('1337').toString(10), 6)).toEqual( '0.001337', ); - expect(fromTokenMinimalUnitString(new BN('1337').toString(10), 0)).toEqual( + expect(fromTokenMinimalUnitString(new BN4('1337').toString(10), 0)).toEqual( '1337', ); - expect(fromTokenMinimalUnitString(new BN('1337').toString(10), 18)).toEqual( + expect(fromTokenMinimalUnitString(new BN4('1337').toString(10), 18)).toEqual( '0.000000000000001337', ); - expect(fromTokenMinimalUnitString(new BN('123456').toString(), 5)).toEqual( + expect(fromTokenMinimalUnitString(new BN4('123456').toString(), 5)).toEqual( '1.23456', ); - expect(fromTokenMinimalUnitString(new BN('123456').toString(), 5)).toEqual( + expect(fromTokenMinimalUnitString(new BN4('123456').toString(), 5)).toEqual( '1.23456', ); expect( - fromTokenMinimalUnitString(new BN('1234560000000000000').toString(), 18), + fromTokenMinimalUnitString(new BN4('1234560000000000000').toString(), 18), ).toEqual('1.23456'); expect( - fromTokenMinimalUnitString(new BN('1000000000000000000').toString(), 18), + fromTokenMinimalUnitString(new BN4('1000000000000000000').toString(), 18), ).toEqual('1'); - expect(fromTokenMinimalUnitString(new BN('1').toString(), 18)).toEqual( + expect(fromTokenMinimalUnitString(new BN4('1').toString(), 18)).toEqual( '0.000000000000000001', ); - expect(fromTokenMinimalUnitString(new BN('0').toString(), 18)).toEqual('0'); + expect(fromTokenMinimalUnitString(new BN4('0').toString(), 18)).toEqual('0'); expect( - fromTokenMinimalUnitString(new BN('123456789').toString(), 5), + fromTokenMinimalUnitString(new BN4('123456789').toString(), 5), ).toEqual('1234.56789'); expect( fromTokenMinimalUnitString( - new BN('1234567890000000000987654321').toString(), + new BN4('1234567890000000000987654321').toString(), 18, ), ).toEqual('1234567890.000000000987654321'); expect( fromTokenMinimalUnitString( - new BN('10000000000000000000000000000001').toString(), + new BN4('10000000000000000000000000000001').toString(), 18, ), ).toEqual('10000000000000.000000000000000001'); expect( fromTokenMinimalUnitString( - new BN('10000000000000000000000000000000').toString(), + new BN4('10000000000000000000000000000000').toString(), 18, ), ).toEqual('10000000000000'); expect( - fromTokenMinimalUnitString(new BN('3900229504248293869').toString(), 18), + fromTokenMinimalUnitString(new BN4('3900229504248293869').toString(), 18), ).toEqual('3.900229504248293869'); expect( fromTokenMinimalUnitString( - new BN('92836465327282987373728723').toString(), + new BN4('92836465327282987373728723').toString(), 18, ), ).toEqual('92836465.327282987373728723'); expect( - fromTokenMinimalUnitString(new BN('6123512631253').toString(), 16), + fromTokenMinimalUnitString(new BN4('6123512631253').toString(), 16), ).toEqual('0.0006123512631253'); expect( fromTokenMinimalUnitString( - new BN('92836465327282987373728723').toString(), + new BN4('92836465327282987373728723').toString(), 0, ), ).toEqual('92836465327282987373728723'); @@ -350,20 +351,20 @@ describe('Number utils :: fromTokenMinimalUnitString', () => { describe('Number utils :: toTokenMinimalUnit', () => { it('toTokenMinimalUnit using number', () => { - expect(toTokenMinimalUnit(1337, 6)).toEqual(new BN('1337000000', 10)); - expect(toTokenMinimalUnit(1337, 0)).toEqual(new BN('1337')); - expect(toTokenMinimalUnit(1337.1, 1)).toEqual(new BN('13371')); + expect(toTokenMinimalUnit(1337, 6)).toEqual(new BN4('1337000000', 10)); + expect(toTokenMinimalUnit(1337, 0)).toEqual(new BN4('1337')); + expect(toTokenMinimalUnit(1337.1, 1)).toEqual(new BN4('13371')); }); it('toTokenMinimalUnit using string', () => { - expect(toTokenMinimalUnit('1337', 6)).toEqual(new BN('1337000000')); - expect(toTokenMinimalUnit('1337', 0)).toEqual(new BN('1337')); - expect(toTokenMinimalUnit('1337.1', 2)).toEqual(new BN('133710')); + expect(toTokenMinimalUnit('1337', 6)).toEqual(new BN4('1337000000')); + expect(toTokenMinimalUnit('1337', 0)).toEqual(new BN4('1337')); + expect(toTokenMinimalUnit('1337.1', 2)).toEqual(new BN4('133710')); }); it('toTokenMinimalUnit using BN number', () => { - expect(toTokenMinimalUnit(new BN('1337'), 0)).toEqual(new BN('1337')); - expect(toTokenMinimalUnit(new BN('1337'), 6)).toEqual(new BN('1337000000')); + expect(toTokenMinimalUnit(new BN4('1337'), 0)).toEqual(new BN4('1337')); + expect(toTokenMinimalUnit(new BN4('1337'), 6)).toEqual(new BN4('1337000000')); }); it('toTokenMinimalUnit using invalid inputs', () => { @@ -389,10 +390,10 @@ describe('Number utils :: renderFromTokenMinimalUnit', () => { }); it('renderFromTokenMinimalUnit using BN number', () => { - expect(renderFromTokenMinimalUnit(new BN('1337'), 0)).toEqual('1337'); - expect(renderFromTokenMinimalUnit(new BN('1337'), 6)).toEqual('0.00134'); - expect(renderFromTokenMinimalUnit(new BN('1337'), 10)).toEqual('< 0.00001'); - expect(renderFromTokenMinimalUnit(new BN('0'), 10)).toEqual('0'); + expect(renderFromTokenMinimalUnit(new BN4('1337'), 0)).toEqual('1337'); + expect(renderFromTokenMinimalUnit(new BN4('1337'), 6)).toEqual('0.00134'); + expect(renderFromTokenMinimalUnit(new BN4('1337'), 10)).toEqual('< 0.00001'); + expect(renderFromTokenMinimalUnit(new BN4('0'), 10)).toEqual('0'); }); }); @@ -410,9 +411,9 @@ describe('Number utils :: renderFromWei', () => { }); it('renderFromWei using BN number', () => { - expect(renderFromWei(new BN('133700000000000000'))).toEqual('0.1337'); - expect(renderFromWei(new BN('1337'))).toEqual('< 0.00001'); - expect(renderFromWei(new BN('0'))).toEqual('0'); + expect(renderFromWei(new BN4('133700000000000000'))).toEqual('0.1337'); + expect(renderFromWei(new BN4('1337'))).toEqual('< 0.00001'); + expect(renderFromWei(new BN4('0'))).toEqual('0'); }); }); @@ -478,9 +479,9 @@ describe('Number utils :: localizeLargeNumber', () => { describe('Number utils :: calcTokenValueToSend', () => { it('calcTokenValueToSend', () => { - expect(calcTokenValueToSend(new BN(1337), 0)).toEqual('539'); - expect(calcTokenValueToSend(new BN(1337), 9)).toEqual('1374b68fa00'); - expect(calcTokenValueToSend(new BN(1337), 18)).toEqual( + expect(calcTokenValueToSend(new BN4(1337), 0)).toEqual('539'); + expect(calcTokenValueToSend(new BN4(1337), 9)).toEqual('1374b68fa00'); + expect(calcTokenValueToSend(new BN4(1337), 18)).toEqual( '487a9a304539440000', ); }); @@ -491,7 +492,7 @@ describe('Number utils :: hexToBN', () => { expect(hexToBN('0x539').toNumber()).toBe(1337); }); it('should handle non string values', () => { - const newBN = new BN(1); + const newBN = new BN4(1); expect(hexToBN(newBN)).toBe(newBN); }); }); @@ -500,7 +501,7 @@ describe('Number utils :: isBN', () => { it('isBN', () => { const notABN = '0x539'; expect(isBN(notABN)).toEqual(false); - expect(isBN(new BN(1337))).toEqual(true); + expect(isBN(new BN4(1337))).toEqual(true); }); }); @@ -697,7 +698,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('1650000007.7'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('1650000007'); + const expected: any = new BN4('1650000007'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -710,7 +711,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN(1650000007.7); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('1650000007'); + const expected: any = new BN4('1650000007'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -723,7 +724,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('16500'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('16500'); + const expected: any = new BN4('16500'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -736,7 +737,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN(16500); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('16500'); + const expected: any = new BN4('16500'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -749,7 +750,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('-1650000007.7'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('-1650000007'); + const expected: any = new BN4('-1650000007'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -762,7 +763,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN(-1650000007.7); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('-1650000007'); + const expected: any = new BN4('-1650000007'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -775,7 +776,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('-16500'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('-16500'); + const expected: any = new BN4('-16500'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -788,7 +789,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN(-16500); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('-16500'); + const expected: any = new BN4('-16500'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -801,7 +802,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('75BCD15'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('123456789'); + const expected: any = new BN4('123456789'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -814,7 +815,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('0x75BCD15'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('123456789'); + const expected: any = new BN4('123456789'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -827,7 +828,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('-75BCD15'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('-123456789'); + const expected: any = new BN4('-123456789'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -840,7 +841,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('-0x75BCD15'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('-123456789'); + const expected: any = new BN4('-123456789'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -853,7 +854,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('0'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('0'); + const expected: any = new BN4('0'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -866,7 +867,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('0x0'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('0'); + const expected: any = new BN4('0'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -879,7 +880,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('0xNaN'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('0'); + const expected: any = new BN4('0'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -892,7 +893,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN(NaN); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN('0'); + const expected: any = new BN4('0'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -1053,7 +1054,7 @@ describe('Number utils :: formatValueToMatchTokenDecimals', () => { describe('Number utils :: safeBNToHex', () => { it('returns hex string', () => { - expect(safeBNToHex(new BN('255'))).toBe('0xff'); + expect(safeBNToHex(new BN4('255'))).toBe('0xff'); }); it.each([undefined, null])( diff --git a/app/util/transaction-reducer-helpers.ts b/app/util/transaction-reducer-helpers.ts index 562fa6db9a7a..769b4ae05e09 100644 --- a/app/util/transaction-reducer-helpers.ts +++ b/app/util/transaction-reducer-helpers.ts @@ -1,5 +1,5 @@ import { SecurityAlertResponse } from '@metamask/transaction-controller'; -import { BN } from 'ethereumjs-util'; +import type BN from 'bnjs4'; interface TxMeta { data?: string; diff --git a/app/util/transactions/index.js b/app/util/transactions/index.js index 71614e75e976..c78a43790c39 100644 --- a/app/util/transactions/index.js +++ b/app/util/transactions/index.js @@ -1,4 +1,5 @@ -import { addHexPrefix, toChecksumAddress, BN } from 'ethereumjs-util'; +import { addHexPrefix, toChecksumAddress } from 'ethereumjs-util'; +import BN from 'bnjs4'; import { rawEncode, rawDecode } from 'ethereumjs-abi'; import BigNumber from 'bignumber.js'; import humanizeDuration from 'humanize-duration'; diff --git a/app/util/transactions/index.test.ts b/app/util/transactions/index.test.ts index 2f8415f8871d..67192fa591a4 100644 --- a/app/util/transactions/index.test.ts +++ b/app/util/transactions/index.test.ts @@ -1,5 +1,5 @@ import { swapsUtils } from '@metamask/swaps-controller'; -import { BN } from 'ethereumjs-util'; +import BN from 'bnjs4'; /* eslint-disable-next-line import/no-namespace */ import * as controllerUtilsModule from '@metamask/controller-utils'; diff --git a/package.json b/package.json index aad6dff4ffba..5fdc2b23558e 100644 --- a/package.json +++ b/package.json @@ -228,6 +228,8 @@ "axios": "^1.6.8", "base-64": "1.0.0", "bignumber.js": "^9.0.1", + "bnjs4": "npm:bn.js@^4.12.0", + "bnjs5": "npm:bn.js@^5.2.1", "buffer": "6.0.3", "cockatiel": "^3.1.2", "compare-versions": "^3.6.0", @@ -392,7 +394,8 @@ "@testing-library/react": "14.0.0", "@testing-library/react-hooks": "^8.0.1", "@testing-library/react-native": "12.1.2", - "@types/bn.js": "^4.11.6", + "@types/bnjs4": "npm:@types/bn.js@^4.11.6", + "@types/bnjs5": "npm:@types/bn.js@^5.1.6", "@types/crypto-js": "^4.1.1", "@types/enzyme": "^3.10.12", "@types/eth-url-parser": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index d93dedffd85d..ba6b8d8a0c0f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9471,7 +9471,7 @@ dependencies: "@types/node" "*" -"@types/bn.js@^4.11.3", "@types/bn.js@^4.11.6": +"@types/bn.js@^4.11.3": version "4.11.6" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== @@ -9485,6 +9485,20 @@ dependencies: "@types/node" "*" +"@types/bnjs4@npm:@types/bn.js@^4.11.6": + version "4.11.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" + integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== + dependencies: + "@types/node" "*" + +"@types/bnjs5@npm:@types/bn.js@^5.1.6": + version "5.1.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.6.tgz#9ba818eec0c85e4d3c679518428afdf611d03203" + integrity sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w== + dependencies: + "@types/node" "*" + "@types/body-parser@*": version "1.19.2" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" @@ -13390,6 +13404,16 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== +"bnjs4@npm:bn.js@^4.12.0": + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +"bnjs5@npm:bn.js@^5.2.1": + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + body-parser@1.20.3, body-parser@^1.15.2, body-parser@^1.18.2, body-parser@^1.19.0: version "1.20.3" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" From 3d55e254b1066b1b8044e8bf619810522cb9de5a Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Wed, 23 Oct 2024 13:37:24 +0000 Subject: [PATCH 04/57] fix: validateTokenAmount fix --- app/util/dappTransactions/index.ts | 63 +++++++++++++++++------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/app/util/dappTransactions/index.ts b/app/util/dappTransactions/index.ts index 3629203a35ff..bb208a965109 100644 --- a/app/util/dappTransactions/index.ts +++ b/app/util/dappTransactions/index.ts @@ -1,3 +1,4 @@ +import { remove0x } from '@metamask/utils'; import { isBN, hexToBN } from '../number'; import { safeToChecksumAddress } from '../address'; import Engine from '../../core/Engine'; @@ -5,7 +6,6 @@ import TransactionTypes from '../../core/TransactionTypes'; import { toLowerCaseEquals } from '../general'; import { strings } from '../../../locales/i18n'; import BN4 from 'bnjs4'; -import { lt } from '../lodash'; import { estimateGas as controllerEstimateGas } from '../transaction-controller'; interface opts { @@ -115,6 +115,32 @@ interface ContractBalances { [key: string]: string; } +const getTokenBalance = async ( + from: string, + selectedAsset: SelectedAsset, + selectedAddress: string, + contractBalances: ContractBalances, +): Promise => { + const checksummedFrom = safeToChecksumAddress(from) || ''; + if (selectedAddress === from && contractBalances[selectedAsset.address]) { + return hexToBN( + remove0x(contractBalances[selectedAsset.address].toString()), + ); + } + try { + const { AssetsContractController } = Engine.context; + // TODO: Roundtrip string conversion can be removed when bn.js v4 is superseded with v5 + const contractBalanceForAddress = await AssetsContractController.getERC20BalanceOf( + selectedAsset.address, + checksummedFrom, + ); + const contractBalanceForAddressBN = hexToBN(contractBalanceForAddress.toString(16)); + return contractBalanceForAddressBN; + } catch (e) { + // Don't validate balance if error + } +} + /** * Validates asset (ERC20) transaction amount * @@ -131,7 +157,6 @@ export const validateTokenAmount = async ( allowEmpty = true, ): Promise => { if (!allowEmpty) { - const checksummedFrom = safeToChecksumAddress(from) || ''; if (!value) { return strings('transaction.invalid_amount'); @@ -144,33 +169,15 @@ export const validateTokenAmount = async ( if (!from) { return strings('transaction.invalid_from_address'); } - // If user trying to send a token that doesn't own, validate balance querying contract - // If it fails, skip validation - let contractBalanceForAddress: BN4 | undefined | number; - if (selectedAddress === from && contractBalances[selectedAsset.address]) { - contractBalanceForAddress = hexToBN( - contractBalances[selectedAsset.address].toString(), - ); - } else { - try { - const { AssetsContractController } = Engine.context; - contractBalanceForAddress = new BN4( - (await AssetsContractController.getERC20BalanceOf( - selectedAsset.address, - checksummedFrom, - )).toString()); - } catch (e) { - // Don't validate balance if error - } + + if (value && !isBN(value)) { + return strings('transaction.invalid_amount'); + } + + const contractBalanceForAddress = await getTokenBalance(from, selectedAsset, selectedAddress, contractBalances); + if (contractBalanceForAddress?.lt(value)) { + return strings('transaction.insufficient'); } - if (value && !isBN(value)) return strings('transaction.invalid_amount'); - const validateAssetAmount = - contractBalanceForAddress && - lt( - contractBalanceForAddress as unknown as number, - value as unknown as number, - ); - if (validateAssetAmount) return strings('transaction.insufficient'); } }; From cd7a42e6602bfbd4655d73866bd9b4f9dc8e6eeb Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Wed, 23 Oct 2024 13:40:18 +0000 Subject: [PATCH 05/57] lint:fix --- app/util/dappTransactions/index.ts | 2 +- e2e/specs/ramps/offramp.spec.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/util/dappTransactions/index.ts b/app/util/dappTransactions/index.ts index bb208a965109..62f438f291ac 100644 --- a/app/util/dappTransactions/index.ts +++ b/app/util/dappTransactions/index.ts @@ -139,7 +139,7 @@ const getTokenBalance = async ( } catch (e) { // Don't validate balance if error } -} +}; /** * Validates asset (ERC20) transaction amount diff --git a/e2e/specs/ramps/offramp.spec.js b/e2e/specs/ramps/offramp.spec.js index d990ed0993ba..0af763e1fc64 100644 --- a/e2e/specs/ramps/offramp.spec.js +++ b/e2e/specs/ramps/offramp.spec.js @@ -32,7 +32,7 @@ const PaymentMethods = { DEBIT_OR_CREDIT: 'Debit or Credit', INSTANT_ACH_BANK_TRANSFER: 'Insant ACH Bank Transfer', ACH_BANK_TRANSFER: 'ACH Bank Transfer', -} +}; describe(SmokeAssets('Off-Ramp'), () => { beforeAll(async () => { @@ -67,7 +67,7 @@ describe(SmokeAssets('Off-Ramp'), () => { await SelectRegionView.tapRegionOption(Regions.CALIFORNIA); await SelectRegionView.tapContinueButton(); await SelectPaymentMethodView.tapPaymentMethodOption(PaymentMethods.DEBIT_OR_CREDIT); - await SelectPaymentMethodView.tapContinueButton(); + await SelectPaymentMethodView.tapContinueButton(); await Assertions.checkIfVisible(BuildQuoteView.amountToSellLabel); await Assertions.checkIfVisible(BuildQuoteView.getQuotesButton); }); From 5745eabf0f1032573a672a4c18045661847f1512 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 11:38:31 +0000 Subject: [PATCH 06/57] chore: remove redundant depcheckrc entry --- .depcheckrc.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.depcheckrc.yml b/.depcheckrc.yml index 00959f049235..36e2bc04bb1b 100644 --- a/.depcheckrc.yml +++ b/.depcheckrc.yml @@ -9,8 +9,6 @@ ignores: - 'babel-plugin-inline-import' # This is used on the patch for TokenRatesController of Assets controllers, for we to be able to use the last version of it - cockatiel - # Force intended major version of @types/bn.js used by TypeScript - - '@types/bn.js' # Note: Everything below this line should be removed after investigation # TODO: Investigate each dependency to see whether it's used From 8b419546108962e645c9dc7ab9863e99ed25bf15 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 11:41:45 +0000 Subject: [PATCH 07/57] chore: rename BN to BN4 --- app/components/UI/Ramp/hooks/useIntentAmount.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/components/UI/Ramp/hooks/useIntentAmount.ts b/app/components/UI/Ramp/hooks/useIntentAmount.ts index 6d5aaf6f474b..6a084053c3a7 100644 --- a/app/components/UI/Ramp/hooks/useIntentAmount.ts +++ b/app/components/UI/Ramp/hooks/useIntentAmount.ts @@ -1,5 +1,5 @@ import { useEffect } from 'react'; -import type BN from 'bnjs4'; +import type BN4 from 'bnjs4'; import { useRampSDK } from '../sdk'; import parseAmount from '../utils/parseAmount'; import { toTokenMinimalUnit } from '../../../../util/number'; @@ -21,7 +21,7 @@ export default function useIntentAmount( setAmount: (amount: React.SetStateAction) => void, setAmountNumber: (amount: React.SetStateAction) => void, setAmountBNMinimalUnit: ( - amount: React.SetStateAction, + amount: React.SetStateAction, ) => void, currentFiatCurrency: FiatCurrency | null, ) { @@ -53,7 +53,7 @@ export default function useIntentAmount( toTokenMinimalUnit( `${parsedAmount}`, selectedAsset?.decimals ?? 0, - ) as BN, + ) as BN4, ); } } From 28ec999da94272c46fdc71416ea446b1cd283e0a Mon Sep 17 00:00:00 2001 From: legobeat <109787230+legobeat@users.noreply.github.com> Date: Mon, 28 Oct 2024 21:00:34 +0000 Subject: [PATCH 08/57] chore(devDeps): detox@20.27.2->^20.27.5 (#12039) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** - bump `detox` - migrate detox patch Silence `patch-package` setup warning ## **Related issues** ## **Manual testing steps** ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [x] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. --- package.json | 2 +- ...detox+20.23.1.patch => detox+20.27.5.patch} | 0 yarn.lock | 18 +++++++++--------- 3 files changed, 10 insertions(+), 10 deletions(-) rename patches/{detox+20.23.1.patch => detox+20.27.5.patch} (100%) diff --git a/package.json b/package.json index 5fdc2b23558e..86a24a990174 100644 --- a/package.json +++ b/package.json @@ -438,7 +438,7 @@ "browserstack-local": "^1.5.1", "chromedriver": "^123.0.1", "depcheck": "^1.4.7", - "detox": "20.27.2", + "detox": "^20.27.5", "dotenv": "^16.0.3", "enzyme": "3.9.0", "enzyme-adapter-react-16": "1.10.0", diff --git a/patches/detox+20.23.1.patch b/patches/detox+20.27.5.patch similarity index 100% rename from patches/detox+20.23.1.patch rename to patches/detox+20.27.5.patch diff --git a/yarn.lock b/yarn.lock index ba6b8d8a0c0f..5125711e4d0e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15707,15 +15707,15 @@ detect-node@^2.0.4: resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== -detox-copilot@^0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/detox-copilot/-/detox-copilot-0.0.9.tgz#cc1ddd869868987d3527c93d2604b5d66f3c8466" - integrity sha512-Wk2fuisD8EH+349b0ysNWvZ7UEsThAChbYFlLqOR1jWkDaonEvgf6IOUlmxjvyTl9ENtl8ckd1U7k94yCBYwqw== +detox-copilot@^0.0.23: + version "0.0.23" + resolved "https://registry.yarnpkg.com/detox-copilot/-/detox-copilot-0.0.23.tgz#724aeb62424018b4b6d5620bb0dc7e800e4e4f6b" + integrity sha512-qDSdLwgPUMVawpE0R3agNWd2U69ilTnhf+SodSqqrkmTI0oG67IfkACvwox+K9Slcc8ki6y0Bw6QVBi54MqpaA== -detox@20.27.2: - version "20.27.2" - resolved "https://registry.yarnpkg.com/detox/-/detox-20.27.2.tgz#aa22a146b968b6e5f78687557081cf32d26ca066" - integrity sha512-cC6S40v7ix+uA5jYzG8eazSs7YtOWgc2aCwWLZIIzfE5Kvo0gfHgtqeRhrYWCMZaj/irKKs39h2B070oNQOIrA== +detox@^20.27.5: + version "20.27.5" + resolved "https://registry.yarnpkg.com/detox/-/detox-20.27.5.tgz#f67d1a0c9ddbb2b6edb838e1b32c63b486be66ea" + integrity sha512-JBe3fONwaSxYubd/36SZh3c2MaYs+Cx7sOA4GJfh16QTyoB7XvvbGrSlQDTbag/f0j5RZt4judPtg5A3P1/Uhg== dependencies: ajv "^8.6.3" bunyan "^1.8.12" @@ -15723,7 +15723,7 @@ detox@20.27.2: caf "^15.0.1" chalk "^4.0.0" child-process-promise "^2.2.0" - detox-copilot "^0.0.9" + detox-copilot "^0.0.23" execa "^5.1.1" find-up "^5.0.0" fs-extra "^11.0.0" From f993c51d8f784407971802b0262d00550ebce48b Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 21 Oct 2024 23:17:33 +0000 Subject: [PATCH 09/57] fix(deps): ethereumjs-util@^6.2.1->^7.1.5 --- app/store/migrations/029.ts | 3 +-- app/store/migrations/031.ts | 1 - app/util/address/index.ts | 1 - package.json | 2 +- yarn.lock | 4 ++-- 5 files changed, 4 insertions(+), 7 deletions(-) diff --git a/app/store/migrations/029.ts b/app/store/migrations/029.ts index af4f1ebf1ba1..28f56e470928 100644 --- a/app/store/migrations/029.ts +++ b/app/store/migrations/029.ts @@ -2,7 +2,6 @@ import { toHex } from '@metamask/controller-utils'; import { Hex, hasProperty, isObject } from '@metamask/utils'; import { regex } from '../../../app/util/regex'; -//@ts-expect-error - This error is expected, but ethereumjs-util exports this function import { isHexString } from 'ethereumjs-util'; import { TransactionParams } from '@metamask/transaction-controller'; import { captureException } from '@sentry/react-native'; @@ -466,7 +465,7 @@ export default async function migrate(stateAsync: unknown) { if (Array.isArray(transactionControllerState.transactions)) { transactionControllerState.transactions.forEach( (transaction: TransactionParams, index: number) => { - if (transaction && !isHexString(transaction.chainId)) { + if (transaction && (!transaction.chainId || (transaction.chainId && !isHexString(transaction.chainId)))) { if ( Array.isArray(transactionControllerState.transactions) && isObject(transactionControllerState.transactions[index]) diff --git a/app/store/migrations/031.ts b/app/store/migrations/031.ts index ba4b06ca1192..0ad5dcdf64e3 100644 --- a/app/store/migrations/031.ts +++ b/app/store/migrations/031.ts @@ -6,7 +6,6 @@ import { TokensControllerState, } from '@metamask/assets-controllers'; import { toHex } from '@metamask/controller-utils'; -//@ts-expect-error - This error is expected, but ethereumjs-util exports this function import { isHexString } from 'ethereumjs-util'; /** diff --git a/app/util/address/index.ts b/app/util/address/index.ts index 34071c0579ae..10c09ebae639 100644 --- a/app/util/address/index.ts +++ b/app/util/address/index.ts @@ -3,7 +3,6 @@ import { isValidAddress, addHexPrefix, isValidChecksumAddress, - //@ts-expect-error - This error is expected, but ethereumjs-util exports this function isHexPrefixed, } from 'ethereumjs-util'; import punycode from 'punycode/punycode'; diff --git a/package.json b/package.json index 86a24a990174..c835afeb1d44 100644 --- a/package.json +++ b/package.json @@ -245,7 +245,7 @@ "eth-json-rpc-middleware": "9.0.1", "eth-url-parser": "1.0.4", "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.0", + "ethereumjs-util": "^7.1.5", "ethers": "^5.0.14", "ethjs-ens": "2.0.1", "eventemitter2": "^6.4.9", diff --git a/yarn.lock b/yarn.lock index 5125711e4d0e..60b9cc450c29 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17139,7 +17139,7 @@ ethereumjs-abi@^0.6.8: bn.js "^4.11.8" ethereumjs-util "^6.0.0" -ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.0: +ethereumjs-util@^6.0.0: version "6.2.1" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== @@ -17152,7 +17152,7 @@ ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.0: ethjs-util "0.1.6" rlp "^2.2.3" -ethereumjs-util@^7.0.10, ethereumjs-util@^7.0.8, ethereumjs-util@^7.1.2: +ethereumjs-util@^7.0.10, ethereumjs-util@^7.0.8, ethereumjs-util@^7.1.2, ethereumjs-util@^7.1.5: version "7.1.5" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== From 71dd460f5e7a821d51e169e7b56e420454cc4b17 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Wed, 23 Oct 2024 09:10:16 +0000 Subject: [PATCH 10/57] chore: testfix --- app/util/transactions/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/util/transactions/index.test.ts b/app/util/transactions/index.test.ts index 67192fa591a4..d6040f10f353 100644 --- a/app/util/transactions/index.test.ts +++ b/app/util/transactions/index.test.ts @@ -1082,7 +1082,7 @@ describe('Transactions utils :: isApprovalTransaction', () => { }); describe('Transactions utils :: getTransactionReviewActionKey', () => { - const transaction = { to: '0xContractAddress' }; + const transaction = { to: '0xdeadbeef' }; const chainId = '1'; it('returns `Unknown Method` review action key when transaction action key exists', async () => { const expectedReviewActionKey = 'Unknown Method'; From 68d5431c23d08404e6128bc1a07c9cb0b92fc1d6 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 05:16:08 +0000 Subject: [PATCH 11/57] chore: remove usage of bn.js v4 --- app/components/Nav/Main/RootRPCMethodsUI.js | 2 +- .../ConfirmAddAsset/ConfirmAddAsset.test.tsx | 4 +- .../Ramp/Views/BuildQuote/BuildQuote.test.tsx | 18 +- .../UI/Ramp/Views/BuildQuote/BuildQuote.tsx | 12 +- .../Views/SendTransaction/SendTransaction.tsx | 4 +- .../UI/Ramp/hooks/useGasPriceEstimation.ts | 2 +- .../UI/Ramp/hooks/useIntentAmount.ts | 6 +- .../StakeInputView/StakeInputView.test.tsx | 4 +- .../UnstakeInputView/UnstakeInputView.tsx | 4 +- .../StakingBalance/StakingBalance.tsx | 6 +- .../UI/Stake/hooks/useStakingInput.ts | 14 +- .../TokenList/PortfolioBalance/index.test.tsx | 8 +- app/components/UI/Tokens/index.test.tsx | 10 +- .../components/TransactionEditor/index.js | 2 +- .../SendFlow/Confirm/validation.test.ts | 2 +- .../SendFlow/Confirm/validation.ts | 12 +- .../useAddressBalance.test.tsx | 4 +- .../useAddressBalance/useAddressBalance.ts | 4 +- app/components/hooks/useTokenBalance.tsx | 12 +- .../useTokenBalancesController.test.tsx | 8 +- app/constants/transaction.ts | 2 +- app/util/confirmation/transactions.test.ts | 2 +- app/util/conversion/index.js | 2 +- app/util/custom-gas/index.js | 2 +- app/util/dappTransactions/index.test.ts | 2 +- app/util/dappTransactions/index.ts | 24 +-- app/util/number/index.js | 38 ++--- app/util/number/index.test.ts | 157 +++++++++--------- app/util/transaction-reducer-helpers.ts | 2 +- app/util/transactions/index.js | 2 +- app/util/transactions/index.test.ts | 2 +- package.json | 6 +- yarn.lock | 26 +-- 33 files changed, 189 insertions(+), 216 deletions(-) diff --git a/app/components/Nav/Main/RootRPCMethodsUI.js b/app/components/Nav/Main/RootRPCMethodsUI.js index 310fa254e2e6..5c4837095a7d 100644 --- a/app/components/Nav/Main/RootRPCMethodsUI.js +++ b/app/components/Nav/Main/RootRPCMethodsUI.js @@ -25,7 +25,7 @@ import { getIsSwapApproveOrSwapTransaction, isApprovalTransaction, } from '../../../util/transactions'; -import BN from 'bnjs4'; +import BN from 'bn.js'; import Logger from '../../../util/Logger'; import TransactionTypes from '../../../core/TransactionTypes'; import { swapsUtils } from '@metamask/swaps-controller'; diff --git a/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx b/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx index b3109f95aa86..fa651057ec64 100644 --- a/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx +++ b/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx @@ -7,7 +7,7 @@ import renderWithProvider, { import useBalance from '../Ramp/hooks/useBalance'; import { toTokenMinimalUnit } from '../../../util/number'; import { fireEvent } from '@testing-library/react-native'; -import BN4 from 'bnjs4'; +import BN from 'bn.js'; import { RootState } from '../../../reducers'; import { mockNetworkState } from '../../../util/test/network'; import { CHAIN_IDS } from '@metamask/transaction-controller'; @@ -48,7 +48,7 @@ jest.mock('../../../util/navigation/navUtils', () => ({ const mockUseBalanceInitialValue: Partial> = { balanceFiat: '$27.02', - balanceBN: toTokenMinimalUnit('5.36385', 18) as BN4, + balanceBN: toTokenMinimalUnit('5.36385', 18) as BN, }; const mockUseBalanceValues: Partial> = { diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx index 0a1eaf582210..1e99e0e6abb7 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Limits, Payment } from '@consensys/on-ramp-sdk'; import { act, fireEvent, screen } from '@testing-library/react-native'; -import type BN4 from 'bnjs4'; +import type BN from 'bn.js'; import { renderScreen } from '../../../../../util/test/renderWithProvider'; import BuildQuote from './BuildQuote'; import useRegions from '../../hooks/useRegions'; @@ -191,7 +191,7 @@ jest.mock('../../../../hooks/useAddressBalance/useAddressBalance', () => const mockUseBalanceInitialValue: Partial> = { balanceFiat: '$27.02', - balanceBN: toTokenMinimalUnit('5.36385', 18) as BN4, + balanceBN: toTokenMinimalUnit('5.36385', 18) as BN, }; let mockUseBalanceValues: Partial> = { @@ -242,7 +242,7 @@ const mockUseGasPriceEstimationInitialValue: ReturnType< estimatedGasFee: toTokenMinimalUnit( '0.01', mockUseRampSDKInitialValues.selectedAsset?.decimals || 18, - ) as BN4, + ) as BN, }; let mockUseGasPriceEstimationValue: ReturnType = @@ -669,7 +669,7 @@ describe('BuildQuote View', () => { mockUseBalanceValues.balanceBN = toTokenMinimalUnit( '5', mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN4; + ) as BN; render(BuildQuote); const initialAmount = '0'; const overBalanceAmout = '6'; @@ -688,7 +688,7 @@ describe('BuildQuote View', () => { mockUseBalanceValues.balanceBN = toTokenMinimalUnit( '1', mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN4; + ) as BN; const symbol = mockUseRampSDKValues.selectedAsset?.symbol; fireEvent.press(getByRoleButton(`${initialAmount} ${symbol}`)); fireEvent.press(getByRoleButton('25%')); @@ -719,13 +719,13 @@ describe('BuildQuote View', () => { balanceBN: toTokenMinimalUnit( '1', mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN4, + ) as BN, }; mockUseGasPriceEstimationValue = { estimatedGasFee: toTokenMinimalUnit( '0.27', mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN4, + ) as BN, }; const symbol = mockUseRampSDKValues.selectedAsset?.symbol; fireEvent.press(getByRoleButton(`${initialAmount} ${symbol}`)); @@ -752,13 +752,13 @@ describe('BuildQuote View', () => { balanceBN: toTokenMinimalUnit( '1', mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN4, + ) as BN, }; mockUseGasPriceEstimationValue = { estimatedGasFee: toTokenMinimalUnit( '0.27', mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN4, + ) as BN, }; const symbol = mockUseRampSDKValues.selectedAsset?.symbol; fireEvent.press(getByRoleButton(`${initialAmount} ${symbol}`)); diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx index 565210a8e3d9..2efec4ed2cb6 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx @@ -12,7 +12,7 @@ import Animated, { withTiming, } from 'react-native-reanimated'; import { useNavigation } from '@react-navigation/native'; -import BN4 from 'bnjs4'; +import BN from 'bn.js'; import { useRampSDK } from '../../sdk'; import usePaymentMethods from '../../hooks/usePaymentMethods'; @@ -104,7 +104,7 @@ const BuildQuote = () => { const [amountFocused, setAmountFocused] = useState(false); const [amount, setAmount] = useState('0'); const [amountNumber, setAmountNumber] = useState(0); - const [amountBNMinimalUnit, setAmountBNMinimalUnit] = useState(); + const [amountBNMinimalUnit, setAmountBNMinimalUnit] = useState(); const [error, setError] = useState(null); const keyboardHeight = useRef(1000); const keypadOffset = useSharedValue(1000); @@ -341,7 +341,7 @@ const BuildQuote = () => { setAmountNumber(valueAsNumber); if (isSell) { setAmountBNMinimalUnit( - toTokenMinimalUnit(`${value}`, selectedAsset?.decimals ?? 0) as BN4, + toTokenMinimalUnit(`${value}`, selectedAsset?.decimals ?? 0) as BN, ); } }, @@ -356,8 +356,8 @@ const BuildQuote = () => { } else { const percentage = value * 100; const amountPercentage = balanceBN - ?.mul(new BN4(percentage)) - .div(new BN4(100)); + ?.mul(new BN(percentage)) + .div(new BN(100)); if (!amountPercentage) { return; @@ -698,7 +698,7 @@ const BuildQuote = () => { value: quickAmount, label: currentFiatCurrency?.denomSymbol + quickAmount.toString(), })) ?? []; - } else if (balanceBN && !balanceBN.isZero() && maxSellAmount?.gt(new BN4(0))) { + } else if (balanceBN && !balanceBN.isZero() && maxSellAmount?.gt(new BN(0))) { quickAmounts = [ { value: 0.25, label: '25%' }, { value: 0.5, label: '50%' }, diff --git a/app/components/UI/Ramp/Views/SendTransaction/SendTransaction.tsx b/app/components/UI/Ramp/Views/SendTransaction/SendTransaction.tsx index a0197dad4a26..8fdee41cb16f 100644 --- a/app/components/UI/Ramp/Views/SendTransaction/SendTransaction.tsx +++ b/app/components/UI/Ramp/Views/SendTransaction/SendTransaction.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { ImageSourcePropType, View } from 'react-native'; import { useDispatch, useSelector } from 'react-redux'; import { useNavigation } from '@react-navigation/native'; -import BN4 from 'bnjs4'; +import BN from 'bn.js'; import { SellOrder } from '@consensys/on-ramp-sdk/dist/API'; import { TransactionParams, @@ -132,7 +132,7 @@ function SendTransaction() { setIsConfirming(true); let transactionParams: TransactionParams; const amount = addHexPrefix( - new BN4( + new BN( toTokenMinimalUnit( orderData.cryptoAmount || '0', orderData.cryptoCurrency.decimals, diff --git a/app/components/UI/Ramp/hooks/useGasPriceEstimation.ts b/app/components/UI/Ramp/hooks/useGasPriceEstimation.ts index f0c6b69ad825..18182dea4722 100644 --- a/app/components/UI/Ramp/hooks/useGasPriceEstimation.ts +++ b/app/components/UI/Ramp/hooks/useGasPriceEstimation.ts @@ -5,7 +5,7 @@ import { type GasFeeController as GasFeeControllerType, } from '@metamask/gas-fee-controller'; -import BN from 'bnjs4'; +import BN from 'bn.js'; import Engine from '../../../../core/Engine'; import { decGWEIToHexWEI } from '../../../../util/conversions'; import { selectGasFeeControllerState } from '../../../../selectors/gasFeeController'; diff --git a/app/components/UI/Ramp/hooks/useIntentAmount.ts b/app/components/UI/Ramp/hooks/useIntentAmount.ts index 6a084053c3a7..d07472685afc 100644 --- a/app/components/UI/Ramp/hooks/useIntentAmount.ts +++ b/app/components/UI/Ramp/hooks/useIntentAmount.ts @@ -1,5 +1,5 @@ import { useEffect } from 'react'; -import type BN4 from 'bnjs4'; +import type BN from 'bn.js'; import { useRampSDK } from '../sdk'; import parseAmount from '../utils/parseAmount'; import { toTokenMinimalUnit } from '../../../../util/number'; @@ -21,7 +21,7 @@ export default function useIntentAmount( setAmount: (amount: React.SetStateAction) => void, setAmountNumber: (amount: React.SetStateAction) => void, setAmountBNMinimalUnit: ( - amount: React.SetStateAction, + amount: React.SetStateAction, ) => void, currentFiatCurrency: FiatCurrency | null, ) { @@ -53,7 +53,7 @@ export default function useIntentAmount( toTokenMinimalUnit( `${parsedAmount}`, selectedAsset?.decimals ?? 0, - ) as BN4, + ) as BN, ); } } diff --git a/app/components/UI/Stake/Views/StakeInputView/StakeInputView.test.tsx b/app/components/UI/Stake/Views/StakeInputView/StakeInputView.test.tsx index fd7a9f4b211d..0e2c2e7e2c43 100644 --- a/app/components/UI/Stake/Views/StakeInputView/StakeInputView.test.tsx +++ b/app/components/UI/Stake/Views/StakeInputView/StakeInputView.test.tsx @@ -4,7 +4,7 @@ import StakeInputView from './StakeInputView'; import { renderScreen } from '../../../../../util/test/renderWithProvider'; import Routes from '../../../../../constants/navigation/Routes'; import { backgroundState } from '../../../../../util/test/initial-root-state'; -import BN5 from 'bnjs5'; +import BN from 'bn.js'; import { Stake } from '../../sdk/stakeSdkProvider'; import { ChainId, PooledStakingContract } from '@metamask/stake-sdk'; import { Contract } from 'ethers'; @@ -54,7 +54,7 @@ jest.mock('../../../../../selectors/currencyRateController.ts', () => ({ selectCurrentCurrency: jest.fn(() => 'USD'), })); -const mockBalanceBN = new BN5('1500000000000000000'); +const mockBalanceBN = new BN('1500000000000000000'); const mockPooledStakingContractService: PooledStakingContract = { chainId: ChainId.ETHEREUM, diff --git a/app/components/UI/Stake/Views/UnstakeInputView/UnstakeInputView.tsx b/app/components/UI/Stake/Views/UnstakeInputView/UnstakeInputView.tsx index 801db04ccb3c..376d171901dc 100644 --- a/app/components/UI/Stake/Views/UnstakeInputView/UnstakeInputView.tsx +++ b/app/components/UI/Stake/Views/UnstakeInputView/UnstakeInputView.tsx @@ -1,6 +1,6 @@ import { useNavigation } from '@react-navigation/native'; import React, { useCallback, useEffect } from 'react'; -import BN4 from 'bnjs4'; +import BN from 'bn.js'; import UnstakeInputViewBanner from './UnstakeBanner'; import { strings } from '../../../../../../locales/i18n'; import Button, { @@ -43,7 +43,7 @@ const UnstakeInputView = () => { handleAmountPress, handleKeypadChange, conversionRate, - } = useStakingInputHandlers(new BN4(stakedBalanceWei)); + } = useStakingInputHandlers(new BN(stakedBalanceWei)); const stakeBalanceInEth = renderFromWei(stakedBalanceWei, 5); const stakeBalanceFiatNumber = weiToFiatNumber( diff --git a/app/components/UI/Stake/components/StakingBalance/StakingBalance.tsx b/app/components/UI/Stake/components/StakingBalance/StakingBalance.tsx index 1f5dd15f15f2..a33e3794f8e5 100644 --- a/app/components/UI/Stake/components/StakingBalance/StakingBalance.tsx +++ b/app/components/UI/Stake/components/StakingBalance/StakingBalance.tsx @@ -24,7 +24,7 @@ import { strings } from '../../../../../../locales/i18n'; import { renderFromWei } from '../../../../../util/number'; import { getTimeDifferenceFromNow } from '../../../../../util/date'; import { filterExitRequests } from './utils'; -import BN4 from 'bnjs4'; +import BN from 'bn.js'; import bn from 'bignumber.js'; import { CommonPercentageInputUnits, @@ -82,8 +82,8 @@ const StakingBalanceContent = ({ asset }: StakingBalanceProps) => { renderFromWei( claimableRequests.reduce( (acc, { claimedAssets }) => - claimedAssets ? acc.add(new BN4(claimedAssets)) : acc, - new BN4(0), + claimedAssets ? acc.add(new BN(claimedAssets)) : acc, + new BN(0), ), ), [claimableRequests], diff --git a/app/components/UI/Stake/hooks/useStakingInput.ts b/app/components/UI/Stake/hooks/useStakingInput.ts index 5f2d53ee57d1..a6daadf07c5f 100644 --- a/app/components/UI/Stake/hooks/useStakingInput.ts +++ b/app/components/UI/Stake/hooks/useStakingInput.ts @@ -1,4 +1,4 @@ -import BN4 from 'bnjs4'; +import BN from 'bn.js'; import { useState, useMemo, useCallback } from 'react'; import { useSelector } from 'react-redux'; import { @@ -17,15 +17,15 @@ import { import { strings } from '../../../../../locales/i18n'; import useVaultData from './useVaultData'; -const useStakingInputHandlers = (balance: BN4) => { +const useStakingInputHandlers = (balance: BN) => { const [amountEth, setAmountEth] = useState('0'); - const [amountWei, setAmountWei] = useState(new BN4(0)); + const [amountWei, setAmountWei] = useState(new BN(0)); const [estimatedAnnualRewards, setEstimatedAnnualRewards] = useState('-'); - const isNonZeroAmount = useMemo(() => amountWei.gt(new BN4(0)), [amountWei]); + const isNonZeroAmount = useMemo(() => amountWei.gt(new BN(0)), [amountWei]); const isOverMaximum = useMemo(() => { - const additionalFundsRequired = amountWei.sub(balance || new BN4(0)); - return isNonZeroAmount && additionalFundsRequired.gt(new BN4(0)); + const additionalFundsRequired = amountWei.sub(balance || new BN(0)); + return isNonZeroAmount && additionalFundsRequired.gt(new BN(0)); }, [amountWei, balance, isNonZeroAmount]); const [fiatAmount, setFiatAmount] = useState('0'); @@ -92,7 +92,7 @@ const useStakingInputHandlers = (balance: BN4) => { ({ value }: { value: number }) => { if (!balance) return; const percentage = value * 100; - const amountPercentage = balance.mul(new BN4(percentage)).div(new BN4(100)); + const amountPercentage = balance.mul(new BN(percentage)).div(new BN(100)); const newAmountString = fromTokenMinimalUnitString( amountPercentage.toString(10), diff --git a/app/components/UI/Tokens/TokenList/PortfolioBalance/index.test.tsx b/app/components/UI/Tokens/TokenList/PortfolioBalance/index.test.tsx index 680d81843003..f1b5333e93c6 100644 --- a/app/components/UI/Tokens/TokenList/PortfolioBalance/index.test.tsx +++ b/app/components/UI/Tokens/TokenList/PortfolioBalance/index.test.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { fireEvent } from '@testing-library/react-native'; -import BN5 from 'bnjs5'; +import BN from 'bn.js'; import renderWithProvider from '../../../../../util/test/renderWithProvider'; import { backgroundState } from '../../../../../util/test/initial-root-state'; import AppConstants from '../../../../../../app/core/AppConstants'; @@ -70,9 +70,9 @@ const initialState = { }, TokenBalancesController: { contractBalances: { - '0x00': new BN5(2), - '0x01': new BN5(2), - '0x02': new BN5(0), + '0x00': new BN(2), + '0x01': new BN(2), + '0x02': new BN(0), }, }, }, diff --git a/app/components/UI/Tokens/index.test.tsx b/app/components/UI/Tokens/index.test.tsx index 379384746e01..88819c3bd671 100644 --- a/app/components/UI/Tokens/index.test.tsx +++ b/app/components/UI/Tokens/index.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; // eslint-disable-next-line @typescript-eslint/no-shadow import { fireEvent, waitFor } from '@testing-library/react-native'; import Tokens from './'; -import BN5 from 'bnjs5'; +import BN from 'bn.js'; import renderWithProvider from '../../../util/test/renderWithProvider'; import { createStackNavigator } from '@react-navigation/stack'; import { getAssetTestId } from '../../../../wdio/screen-objects/testIDs/Screens/WalletView.testIds'; @@ -109,9 +109,9 @@ const initialState = { }, TokenBalancesController: { contractBalances: { - '0x00': new BN5(2), - '0x01': new BN5(2), - '0x02': new BN5(0), + '0x00': new BN(2), + '0x01': new BN(2), + '0x02': new BN(0), }, }, }, @@ -262,7 +262,7 @@ describe('Tokens', () => { }, TokenBalancesController: { contractBalances: { - '0x02': new BN5(1), + '0x02': new BN(1), }, }, }, diff --git a/app/components/Views/confirmations/Approval/components/TransactionEditor/index.js b/app/components/Views/confirmations/Approval/components/TransactionEditor/index.js index 69863ccdfb18..d8d9ff414a33 100644 --- a/app/components/Views/confirmations/Approval/components/TransactionEditor/index.js +++ b/app/components/Views/confirmations/Approval/components/TransactionEditor/index.js @@ -10,7 +10,7 @@ import { toHexadecimal, } from '../../../../../../util/number'; import { isValidAddress, addHexPrefix } from 'ethereumjs-util'; -import BN from 'bnjs4'; +import BN from 'bn.js'; import { strings } from '../../../../../../../locales/i18n'; import { connect } from 'react-redux'; import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view'; diff --git a/app/components/Views/confirmations/SendFlow/Confirm/validation.test.ts b/app/components/Views/confirmations/SendFlow/Confirm/validation.test.ts index 8da1c4c3ac3e..f90a6542d9f5 100644 --- a/app/components/Views/confirmations/SendFlow/Confirm/validation.test.ts +++ b/app/components/Views/confirmations/SendFlow/Confirm/validation.test.ts @@ -1,4 +1,4 @@ -import BN from 'bnjs4'; +import BN from 'bn.js'; import { validateSufficientBalance, validateSufficientTokenBalance } from './validation'; import { renderFromWei, hexToBN } from '../../../../../util/number'; import { diff --git a/app/components/Views/confirmations/SendFlow/Confirm/validation.ts b/app/components/Views/confirmations/SendFlow/Confirm/validation.ts index 461ffd62e966..c50a2057196f 100644 --- a/app/components/Views/confirmations/SendFlow/Confirm/validation.ts +++ b/app/components/Views/confirmations/SendFlow/Confirm/validation.ts @@ -4,7 +4,7 @@ import { decodeTransferData, } from '../../../../../util/transactions'; import { strings } from '../../../../../../locales/i18n'; -import type BN4 from 'bnjs4'; +import type BN from 'bn.js'; interface SelectedAsset { address: string; @@ -13,8 +13,8 @@ interface SelectedAsset { } export const generateInsufficientBalanceMessage = ( - weiBalance: BN4, - transactionValue: BN4, + weiBalance: BN, + transactionValue: BN, ticker: string, ) => { const amount = renderFromWei(transactionValue.sub(weiBalance)); @@ -25,7 +25,7 @@ export const generateInsufficientBalanceMessage = ( }); }; -export const validateBalance = (weiBalance: BN4, transactionValue: BN4) => +export const validateBalance = (weiBalance: BN, transactionValue: BN) => !weiBalance.gte(transactionValue) || weiBalance.isZero(); export const validateSufficientTokenBalance = ( @@ -49,8 +49,8 @@ export const validateSufficientTokenBalance = ( }; export const validateSufficientBalance = ( - weiBalance: BN4, - totalTransactionValue: BN4, + weiBalance: BN, + totalTransactionValue: BN, ticker: string, ) => { if (validateBalance(weiBalance, totalTransactionValue)) { diff --git a/app/components/hooks/useAddressBalance/useAddressBalance.test.tsx b/app/components/hooks/useAddressBalance/useAddressBalance.test.tsx index 769ce5db0678..fba9711d3a8e 100644 --- a/app/components/hooks/useAddressBalance/useAddressBalance.test.tsx +++ b/app/components/hooks/useAddressBalance/useAddressBalance.test.tsx @@ -8,7 +8,7 @@ import { Asset } from './useAddressBalance.types'; import useAddressBalance from './useAddressBalance'; import backgroundState from '../../../util/test/initial-root-state'; import { createMockAccountsControllerState } from '../../../util/test/accountsControllerTestUtils'; -import type BN5 from 'bnjs5'; +import type BN from 'bn.js'; const MOCK_ADDRESS_1 = '0x0'; const MOCK_ADDRESS_2 = '0x1'; @@ -65,7 +65,7 @@ describe('useAddressBalance', () => { address: string, selectedAddress: string, networkClientId?: string | undefined, - ) => Promise; + ) => Promise; beforeEach(() => { mockGetERC20BalanceOf = jest .fn() diff --git a/app/components/hooks/useAddressBalance/useAddressBalance.ts b/app/components/hooks/useAddressBalance/useAddressBalance.ts index dcdf9e1acc5f..d0b301bdb17c 100644 --- a/app/components/hooks/useAddressBalance/useAddressBalance.ts +++ b/app/components/hooks/useAddressBalance/useAddressBalance.ts @@ -1,7 +1,7 @@ import { ERC1155, ERC721 } from '@metamask/controller-utils'; import { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; -import BN4 from 'bnjs4'; +import BN from 'bn.js'; import Engine from '../../../core/Engine'; import { getTicker } from '../../../util/transactions'; @@ -112,7 +112,7 @@ const useAddressBalance = ( ); fromAccBalance = `${renderFromTokenMinimalUnit( // This is to work around incompatibility between bn.js v4/v5 - should be removed when migration to v5 is complete - new BN4(fromAccBalance?.toString(10) || '0', 10), + new BN(fromAccBalance?.toString(10) || '0', 10), decimals, )} ${symbol}`; setAddressBalance(fromAccBalance); diff --git a/app/components/hooks/useTokenBalance.tsx b/app/components/hooks/useTokenBalance.tsx index f4d84786a613..f3e166fc3927 100644 --- a/app/components/hooks/useTokenBalance.tsx +++ b/app/components/hooks/useTokenBalance.tsx @@ -1,6 +1,6 @@ import { useState, useEffect, Dispatch, SetStateAction } from 'react'; import Engine from '../../core/Engine'; -import type BN4 from 'bnjs4'; +import type BN from 'bn.js'; /** * Hook to handle the balance of ERC20 tokens @@ -12,12 +12,12 @@ import type BN4 from 'bnjs4'; const useTokenBalance = ( requestedTokenAddress: string, userCurrentAddress: string, -): [BN4 | null, boolean, boolean] => { +): [BN | null, boolean, boolean] => { // This hook should be only used with ERC20 tokens const [tokenBalance, setTokenBalance]: [ - BN4 | null, - Dispatch>, - ] = useState(null); + BN | null, + Dispatch>, + ] = useState(null); const [loading, setLoading]: [boolean, Dispatch>] = useState(true); const [error, setError]: [boolean, Dispatch>] = @@ -31,7 +31,7 @@ const useTokenBalance = ( userAddress: string, ): Promise => { AssetsContractController.getERC20BalanceOf(tokenAddress, userAddress) - .then((balance: BN4) => setTokenBalance(balance)) + .then((balance: BN) => setTokenBalance(balance)) .catch(() => setError(true)) .finally(() => setLoading(false)); }; diff --git a/app/components/hooks/useTokenBalancesController/useTokenBalancesController.test.tsx b/app/components/hooks/useTokenBalancesController/useTokenBalancesController.test.tsx index aaf33d56db3b..b0839cb3c8da 100644 --- a/app/components/hooks/useTokenBalancesController/useTokenBalancesController.test.tsx +++ b/app/components/hooks/useTokenBalancesController/useTokenBalancesController.test.tsx @@ -4,7 +4,7 @@ import { Provider } from 'react-redux'; import { createStore, Store } from 'redux'; import { act, render, waitFor } from '@testing-library/react-native'; import useTokenBalancesController from './useTokenBalancesController'; -import BN4 from 'bnjs4'; +import BN from 'bn.js'; import { cloneDeep } from 'lodash'; import { backgroundState } from '../../../util/test/initial-root-state'; @@ -15,7 +15,7 @@ const mockInitialState = { ...backgroundState, TokenBalancesController: { contractBalances: { - '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': new BN4(0x2a), + '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': new BN(0x2a), }, }, }, @@ -104,7 +104,7 @@ describe('useTokenBalancesController()', () => { testStore.dispatch({ type: 'add-balances', value: { - '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b96': new BN4(0x539), + '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b96': new BN(0x539), }, }); }); @@ -122,7 +122,7 @@ describe('useTokenBalancesController()', () => { testStore.dispatch({ type: 'add-balances', value: { - '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': new BN4(0x2a), + '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': new BN(0x2a), }, }); }); diff --git a/app/constants/transaction.ts b/app/constants/transaction.ts index 38612646e437..bf1f3b973acb 100644 --- a/app/constants/transaction.ts +++ b/app/constants/transaction.ts @@ -1,4 +1,4 @@ -import BN from 'bnjs4'; +import BN from 'bn.js'; // Transaction Status export const TX_UNAPPROVED = 'unapproved'; diff --git a/app/util/confirmation/transactions.test.ts b/app/util/confirmation/transactions.test.ts index 1bda3144e944..a21dfb8dcb5c 100644 --- a/app/util/confirmation/transactions.test.ts +++ b/app/util/confirmation/transactions.test.ts @@ -1,4 +1,4 @@ -import BN from 'bnjs4'; +import BN from 'bn.js'; import { buildTransactionParams } from './transactions'; import { GAS_ESTIMATE_TYPES } from '@metamask/gas-fee-controller'; import { TransactionEnvelopeType } from '@metamask/transaction-controller'; diff --git a/app/util/conversion/index.js b/app/util/conversion/index.js index d65cb6853974..462345574646 100644 --- a/app/util/conversion/index.js +++ b/app/util/conversion/index.js @@ -22,7 +22,7 @@ */ import BigNumber from 'bignumber.js'; -import BN from 'bnjs4'; +import BN from 'bn.js'; import { stripHexPrefix } from 'ethereumjs-util'; diff --git a/app/util/custom-gas/index.js b/app/util/custom-gas/index.js index b8c611c6be9d..e2950eb58caf 100644 --- a/app/util/custom-gas/index.js +++ b/app/util/custom-gas/index.js @@ -1,4 +1,4 @@ -import BN from 'bnjs4'; +import BN from 'bn.js'; import { renderFromWei, weiToFiat, toWei, conversionUtil } from '../number'; import { strings } from '../../../locales/i18n'; import TransactionTypes from '../../core/TransactionTypes'; diff --git a/app/util/dappTransactions/index.test.ts b/app/util/dappTransactions/index.test.ts index 150e559b98db..b7444f91bb54 100644 --- a/app/util/dappTransactions/index.test.ts +++ b/app/util/dappTransactions/index.test.ts @@ -1,4 +1,4 @@ -import BN from 'bnjs4'; +import BN from 'bn.js'; import { strings } from '../../../locales/i18n'; import Engine from '../../core/Engine'; diff --git a/app/util/dappTransactions/index.ts b/app/util/dappTransactions/index.ts index 62f438f291ac..8a10390cf400 100644 --- a/app/util/dappTransactions/index.ts +++ b/app/util/dappTransactions/index.ts @@ -5,7 +5,7 @@ import Engine from '../../core/Engine'; import TransactionTypes from '../../core/TransactionTypes'; import { toLowerCaseEquals } from '../general'; import { strings } from '../../../locales/i18n'; -import BN4 from 'bnjs4'; +import BN from 'bn.js'; import { estimateGas as controllerEstimateGas } from '../transaction-controller'; interface opts { @@ -25,8 +25,8 @@ interface Transaction { data: string; ensRecipient: string | undefined; from: string; - gas: BN4; - gasPrice: BN4; + gas: BN; + gasPrice: BN; id: string; nonce: string | undefined; origin: string; @@ -97,7 +97,7 @@ export const estimateGas = async ( * @returns {string} - String containing error message whether the Ether transaction amount is valid or not */ export const validateEtherAmount = ( - value: BN4, + value: BN, from: string, allowEmpty = true, ): string | undefined => { @@ -120,7 +120,7 @@ const getTokenBalance = async ( selectedAsset: SelectedAsset, selectedAddress: string, contractBalances: ContractBalances, -): Promise => { +): Promise => { const checksummedFrom = safeToChecksumAddress(from) || ''; if (selectedAddress === from && contractBalances[selectedAsset.address]) { return hexToBN( @@ -148,8 +148,8 @@ const getTokenBalance = async ( * @returns {string} - String containing error message whether the Ether transaction amount is valid or not */ export const validateTokenAmount = async ( - value: BN4, - gas: BN4, + value: BN, + gas: BN, from: string, selectedAsset: SelectedAsset, selectedAddress: string, @@ -223,10 +223,10 @@ export const validateAmount = async ( const { value, from, gas, selectedAsset } = transaction; const validations: Validations = { - ETH: () => validateEtherAmount(value as unknown as BN4, from, allowEmpty), + ETH: () => validateEtherAmount(value as unknown as BN, from, allowEmpty), ERC20: async () => await validateTokenAmount( - value as unknown as BN4, + value as unknown as BN, gas, from, selectedAsset, @@ -283,8 +283,8 @@ type setTransactionObjectType = ( * @param {function} setTransactionObject - Sets any attribute in transaction object */ export const handleGasFeeSelection = ( - gasLimit: BN4, - gasPrice: BN4, + gasLimit: BN, + gasPrice: BN, setTransactionObject: setTransactionObjectType, ): void => { const transactionObject = { @@ -304,5 +304,5 @@ export const handleGetGasLimit = async ( ): Promise => { if (!Object.keys(transaction.selectedAsset).length) return; const { gas } = await estimateGas({}, transaction); - setTransactionObject({ gas: hexToBN(gas) as BN4 }); + setTransactionObject({ gas: hexToBN(gas) as BN }); }; diff --git a/app/util/number/index.js b/app/util/number/index.js index c3a76e42206d..625177ab1437 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -2,7 +2,7 @@ * Collection of utility functions for consistent formatting and conversion */ import { stripHexPrefix } from 'ethereumjs-util'; -import BN4 from 'bnjs4'; +import BN from 'bn.js'; import { utils as ethersUtils } from 'ethers'; import convert from '@metamask/ethjs-unit'; import { add0x, remove0x } from '@metamask/utils'; @@ -27,8 +27,8 @@ const BIG_NUMBER_ETH_MULTIPLIER = new BigNumber('1'); */ export const hexToBN = (inputHex) => typeof inputHex !== 'string' - ? new BN4(inputHex, 16) - : (inputHex ? new BN4(remove0x(inputHex), 16) : new BN4(0)); + ? new BN(inputHex, 16) + : (inputHex ? new BN(remove0x(inputHex), 16) : new BN(0)); /** * Converts a BN object to a hex string with a '0x' prefix. @@ -64,7 +64,7 @@ const toSpecifiedDenomination = { const baseChange = { hex: (n) => n.toString(16), dec: (n) => new BigNumber(n).toString(10), - BN: (n) => new BN4(n.toString(16)), + BN: (n) => new BN(n.toString(16)), }; /** @@ -116,7 +116,7 @@ export function fromTokenMinimalUnit( minimalInput = isRounding ? Number(minimalInput) : minimalInput; const prefixedInput = addHexPrefix(minimalInput.toString(16)); let minimal = safeNumberToBN(prefixedInput); - const negative = minimal.lt(new BN4(0)); + const negative = minimal.lt(new BN(0)); const base = toBN(Math.pow(10, decimals).toString()); if (negative) { @@ -160,7 +160,7 @@ export function fromTokenMinimalUnitString(minimalInput, decimals) { /** * Converts some unit to token minimal unit * - * @param {number|string|BN4} tokenValue - Value to convert + * @param {number|string|BN} tokenValue - Value to convert * @param {number} decimals - Unit to convert from, ether by default * @returns {Object} - BN instance containing the new number */ @@ -205,19 +205,19 @@ export function toTokenMinimalUnit(tokenValue, decimals) { while (fraction.length < decimals) { fraction += '0'; } - whole = new BN4(whole); - fraction = new BN4(fraction); + whole = new BN(whole); + fraction = new BN(fraction); let tokenMinimal = whole.mul(base).add(fraction); if (negative) { tokenMinimal = tokenMinimal.mul(negative); } - return new BN4(tokenMinimal.toString(10), 10); + return new BN(tokenMinimal.toString(10), 10); } /** * Converts some token minimal unit to render format string, showing 5 decimals * - * @param {Number|String|BN4} tokenValue - Token value to convert + * @param {Number|String|BN} tokenValue - Token value to convert * @param {Number} decimals - Token decimals to convert * @param {Number} decimalsToShow - Decimals to 5 * @returns {String} - Number of token minimal unit, in render format @@ -313,7 +313,7 @@ export function fiatNumberToTokenMinimalUnit( /** * Converts wei to render format string, showing 5 decimals * - * @param {Number|String|BN4} value - Wei to convert + * @param {Number|String|BN} value - Wei to convert * @param {Number} decimalsToShow - Decimals to 5 * @returns {String} - Number of token minimal unit, in render format * If value is less than 5 precision decimals will show '< 0.00001' @@ -352,7 +352,7 @@ export function calcTokenValueToSend(value, decimals) { * @returns {boolean} - True if the value is a BN instance */ export function isBN(value) { - return BN4.isBN(value); + return BN.isBN(value); } /** @@ -376,7 +376,7 @@ export function isDecimal(value) { * @returns {Object} - BN instance */ export function toBN(value) { - return new BN4(value); + return new BN(value); } /** @@ -417,9 +417,9 @@ export const isNumberScientificNotationWhenString = (value) => { /** * Converts some unit to wei * - * @param {number|string|BN4} value - Value to convert + * @param {number|string|BN} value - Value to convert * @param {string} unit - Unit to convert from, ether by default - * @returns {BN4} - BN instance containing the new number + * @returns {BN} - BN instance containing the new number */ export function toWei(value, unit = 'ether') { // check the posibilty to convert to BN @@ -433,7 +433,7 @@ export function toWei(value, unit = 'ether') { /** * Converts some unit to Gwei * - * @param {number|string|BN4} value - Value to convert + * @param {number|string|BN} value - Value to convert * @param {string} unit - Unit to convert from, ether by default * @returns {Object} - BN instance containing the new number */ @@ -444,7 +444,7 @@ export function toGwei(value, unit = 'ether') { /** * Converts some unit to Gwei and return it in render format * - * @param {number|string|BN4} value - Value to convert + * @param {number|string|BN} value - Value to convert * @param {string} unit - Unit to convert from, ether by default * @returns {string} - String instance containing the renderable number */ @@ -459,7 +459,7 @@ export function renderToGwei(value, unit = 'ether') { * Converts wei expressed as a BN instance into a human-readable fiat string * TODO: wei should be a BN instance, but we're not sure if it's always the case // - * @param {number | BN4} wei - BN corresponding to an amount of wei + * @param {number | BN} wei - BN corresponding to an amount of wei * @param {number | null} conversionRate - ETH to current currency conversion rate * @param {string} currencyCode - Current currency code to display * @returns {string} - Currency-formatted string @@ -537,7 +537,7 @@ export function addCurrencySymbol( /** * Converts wei expressed as a BN instance into a human-readable fiat string * - * @param {number|string|BN4} wei - BN corresponding to an amount of wei + * @param {number|string|BN} wei - BN corresponding to an amount of wei * @param {number} conversionRate - ETH to current currency conversion rate * @param {Number} decimalsToShow - Decimals to 5 * @returns {Number} - The converted balance diff --git a/app/util/number/index.test.ts b/app/util/number/index.test.ts index db8904ef7a91..50af9bd15898 100644 --- a/app/util/number/index.test.ts +++ b/app/util/number/index.test.ts @@ -1,5 +1,4 @@ -import BN4 from 'bnjs4'; -import BN5 from 'bnjs5'; +import BN from 'bn.js'; import { addCurrencySymbol, @@ -40,7 +39,7 @@ import { describe('Number utils :: BNToHex', () => { it('BNToHex', () => { - expect(BNToHex(new BN5('1337'))).toEqual('0x539'); + expect(BNToHex(new BN('1337'))).toEqual('0x539'); }); }); @@ -54,7 +53,7 @@ describe('Number utils :: fromWei', () => { }); it('fromWei using BN number', () => { - expect(fromWei(new BN4('1337'))).toEqual('0.000000000000001337'); + expect(fromWei(new BN('1337'))).toEqual('0.000000000000001337'); }); }); @@ -88,19 +87,19 @@ describe('Number utils :: toWei', () => { expect(() => toWei('1.337e-15')).toThrow(Error); }); - // bnjs4 do not support decimals, so tests here only cover integers + // bn.js do not support decimals, so tests here only cover integers it('toWei using BN number', () => { - expect(toWei(new BN4(1337)).toString()).toEqual('1337000000000000000000'); + expect(toWei(new BN(1337)).toString()).toEqual('1337000000000000000000'); // Tests for expected limitations of BN.js // BN.js do not support decimals - expect(toWei(new BN4(1.337e-15)).toString()).toEqual('0'); + expect(toWei(new BN(1.337e-15)).toString()).toEqual('0'); // BN.js do not support such big numbers - expect(() => toWei(new BN4(1.337e18))).toThrow(Error); - expect(() => toWei(new BN4(1337000000000000000))).toThrow(Error); + expect(() => toWei(new BN(1.337e18))).toThrow(Error); + expect(() => toWei(new BN(1337000000000000000))).toThrow(Error); // For some reason this returns 8338418000000000000000000 wei - expect(toWei(new BN4('1.337e18'))).not.toEqual( + expect(toWei(new BN('1.337e18'))).not.toEqual( '1337000000000000000000000000000000000', ); }); @@ -120,9 +119,9 @@ describe('Number utils :: fromTokenMinimalUnit', () => { }); it('fromTokenMinimalUnit using BN number', () => { - expect(fromTokenMinimalUnit(new BN4('1337'), 6)).toEqual('0.001337'); - expect(fromTokenMinimalUnit(new BN4('1337'), 0)).toEqual('1337'); - expect(fromTokenMinimalUnit(new BN4('1337'), 18)).toEqual( + expect(fromTokenMinimalUnit(new BN('1337'), 6)).toEqual('0.001337'); + expect(fromTokenMinimalUnit(new BN('1337'), 0)).toEqual('1337'); + expect(fromTokenMinimalUnit(new BN('1337'), 18)).toEqual( '0.000000000000001337', ); }); @@ -135,24 +134,24 @@ describe('Number utils :: fromTokenMinimalUnit', () => { }); it('rounds number by default', () => { - expect(fromTokenMinimalUnit(new BN4('1000000000000000000'), 18)).toEqual( + expect(fromTokenMinimalUnit(new BN('1000000000000000000'), 18)).toEqual( '1', ); - expect(fromTokenMinimalUnit(new BN4('10000000000000000000'), 18)).toEqual( + expect(fromTokenMinimalUnit(new BN('10000000000000000000'), 18)).toEqual( '10', ); - expect(fromTokenMinimalUnit(new BN4('100000000000000000000'), 18)).toEqual( + expect(fromTokenMinimalUnit(new BN('100000000000000000000'), 18)).toEqual( '100', ); - expect(fromTokenMinimalUnit(new BN4('1000000000000000000000'), 18)).toEqual( + expect(fromTokenMinimalUnit(new BN('1000000000000000000000'), 18)).toEqual( '1000', ); - expect(fromTokenMinimalUnit(new BN4('10000000000000000000000'), 18)).toEqual( + expect(fromTokenMinimalUnit(new BN('10000000000000000000000'), 18)).toEqual( '10000', ); // test decimal greater than 30,000 - expect(fromTokenMinimalUnit(new BN4('50000000000000000000000'), 18)).toEqual( + expect(fromTokenMinimalUnit(new BN('50000000000000000000000'), 18)).toEqual( '49999.999999999995805696', ); @@ -164,24 +163,24 @@ describe('Number utils :: fromTokenMinimalUnit', () => { it('does not round number if isRounding is false', () => { expect( - fromTokenMinimalUnit(new BN4('1000000000000000000'), 18, false), + fromTokenMinimalUnit(new BN('1000000000000000000'), 18, false), ).toEqual('1'); expect( - fromTokenMinimalUnit(new BN4('10000000000000000000'), 18, false), + fromTokenMinimalUnit(new BN('10000000000000000000'), 18, false), ).toEqual('10'); expect( - fromTokenMinimalUnit(new BN4('100000000000000000000'), 18, false), + fromTokenMinimalUnit(new BN('100000000000000000000'), 18, false), ).toEqual('100'); expect( - fromTokenMinimalUnit(new BN4('1000000000000000000000'), 18, false), + fromTokenMinimalUnit(new BN('1000000000000000000000'), 18, false), ).toEqual('1000'); expect( - fromTokenMinimalUnit(new BN4('10000000000000000000000'), 18, false), + fromTokenMinimalUnit(new BN('10000000000000000000000'), 18, false), ).toEqual('10000'); // test decimal greater than 30,000 expect( - fromTokenMinimalUnit(new BN4('50000000000000000000000'), 18, false), + fromTokenMinimalUnit(new BN('50000000000000000000000'), 18, false), ).toEqual('50000'); // test decimal less than 1e-14 @@ -282,67 +281,67 @@ describe('Number utils :: fromTokenMinimalUnitString', () => { }); it('fromTokenMinimalUnitString using BN number', () => { - expect(fromTokenMinimalUnitString(new BN4('1337').toString(10), 6)).toEqual( + expect(fromTokenMinimalUnitString(new BN('1337').toString(10), 6)).toEqual( '0.001337', ); - expect(fromTokenMinimalUnitString(new BN4('1337').toString(10), 0)).toEqual( + expect(fromTokenMinimalUnitString(new BN('1337').toString(10), 0)).toEqual( '1337', ); - expect(fromTokenMinimalUnitString(new BN4('1337').toString(10), 18)).toEqual( + expect(fromTokenMinimalUnitString(new BN('1337').toString(10), 18)).toEqual( '0.000000000000001337', ); - expect(fromTokenMinimalUnitString(new BN4('123456').toString(), 5)).toEqual( + expect(fromTokenMinimalUnitString(new BN('123456').toString(), 5)).toEqual( '1.23456', ); - expect(fromTokenMinimalUnitString(new BN4('123456').toString(), 5)).toEqual( + expect(fromTokenMinimalUnitString(new BN('123456').toString(), 5)).toEqual( '1.23456', ); expect( - fromTokenMinimalUnitString(new BN4('1234560000000000000').toString(), 18), + fromTokenMinimalUnitString(new BN('1234560000000000000').toString(), 18), ).toEqual('1.23456'); expect( - fromTokenMinimalUnitString(new BN4('1000000000000000000').toString(), 18), + fromTokenMinimalUnitString(new BN('1000000000000000000').toString(), 18), ).toEqual('1'); - expect(fromTokenMinimalUnitString(new BN4('1').toString(), 18)).toEqual( + expect(fromTokenMinimalUnitString(new BN('1').toString(), 18)).toEqual( '0.000000000000000001', ); - expect(fromTokenMinimalUnitString(new BN4('0').toString(), 18)).toEqual('0'); + expect(fromTokenMinimalUnitString(new BN('0').toString(), 18)).toEqual('0'); expect( - fromTokenMinimalUnitString(new BN4('123456789').toString(), 5), + fromTokenMinimalUnitString(new BN('123456789').toString(), 5), ).toEqual('1234.56789'); expect( fromTokenMinimalUnitString( - new BN4('1234567890000000000987654321').toString(), + new BN('1234567890000000000987654321').toString(), 18, ), ).toEqual('1234567890.000000000987654321'); expect( fromTokenMinimalUnitString( - new BN4('10000000000000000000000000000001').toString(), + new BN('10000000000000000000000000000001').toString(), 18, ), ).toEqual('10000000000000.000000000000000001'); expect( fromTokenMinimalUnitString( - new BN4('10000000000000000000000000000000').toString(), + new BN('10000000000000000000000000000000').toString(), 18, ), ).toEqual('10000000000000'); expect( - fromTokenMinimalUnitString(new BN4('3900229504248293869').toString(), 18), + fromTokenMinimalUnitString(new BN('3900229504248293869').toString(), 18), ).toEqual('3.900229504248293869'); expect( fromTokenMinimalUnitString( - new BN4('92836465327282987373728723').toString(), + new BN('92836465327282987373728723').toString(), 18, ), ).toEqual('92836465.327282987373728723'); expect( - fromTokenMinimalUnitString(new BN4('6123512631253').toString(), 16), + fromTokenMinimalUnitString(new BN('6123512631253').toString(), 16), ).toEqual('0.0006123512631253'); expect( fromTokenMinimalUnitString( - new BN4('92836465327282987373728723').toString(), + new BN('92836465327282987373728723').toString(), 0, ), ).toEqual('92836465327282987373728723'); @@ -351,20 +350,20 @@ describe('Number utils :: fromTokenMinimalUnitString', () => { describe('Number utils :: toTokenMinimalUnit', () => { it('toTokenMinimalUnit using number', () => { - expect(toTokenMinimalUnit(1337, 6)).toEqual(new BN4('1337000000', 10)); - expect(toTokenMinimalUnit(1337, 0)).toEqual(new BN4('1337')); - expect(toTokenMinimalUnit(1337.1, 1)).toEqual(new BN4('13371')); + expect(toTokenMinimalUnit(1337, 6)).toEqual(new BN('1337000000', 10)); + expect(toTokenMinimalUnit(1337, 0)).toEqual(new BN('1337')); + expect(toTokenMinimalUnit(1337.1, 1)).toEqual(new BN('13371')); }); it('toTokenMinimalUnit using string', () => { - expect(toTokenMinimalUnit('1337', 6)).toEqual(new BN4('1337000000')); - expect(toTokenMinimalUnit('1337', 0)).toEqual(new BN4('1337')); - expect(toTokenMinimalUnit('1337.1', 2)).toEqual(new BN4('133710')); + expect(toTokenMinimalUnit('1337', 6)).toEqual(new BN('1337000000')); + expect(toTokenMinimalUnit('1337', 0)).toEqual(new BN('1337')); + expect(toTokenMinimalUnit('1337.1', 2)).toEqual(new BN('133710')); }); it('toTokenMinimalUnit using BN number', () => { - expect(toTokenMinimalUnit(new BN4('1337'), 0)).toEqual(new BN4('1337')); - expect(toTokenMinimalUnit(new BN4('1337'), 6)).toEqual(new BN4('1337000000')); + expect(toTokenMinimalUnit(new BN('1337'), 0)).toEqual(new BN('1337')); + expect(toTokenMinimalUnit(new BN('1337'), 6)).toEqual(new BN('1337000000')); }); it('toTokenMinimalUnit using invalid inputs', () => { @@ -390,10 +389,10 @@ describe('Number utils :: renderFromTokenMinimalUnit', () => { }); it('renderFromTokenMinimalUnit using BN number', () => { - expect(renderFromTokenMinimalUnit(new BN4('1337'), 0)).toEqual('1337'); - expect(renderFromTokenMinimalUnit(new BN4('1337'), 6)).toEqual('0.00134'); - expect(renderFromTokenMinimalUnit(new BN4('1337'), 10)).toEqual('< 0.00001'); - expect(renderFromTokenMinimalUnit(new BN4('0'), 10)).toEqual('0'); + expect(renderFromTokenMinimalUnit(new BN('1337'), 0)).toEqual('1337'); + expect(renderFromTokenMinimalUnit(new BN('1337'), 6)).toEqual('0.00134'); + expect(renderFromTokenMinimalUnit(new BN('1337'), 10)).toEqual('< 0.00001'); + expect(renderFromTokenMinimalUnit(new BN('0'), 10)).toEqual('0'); }); }); @@ -411,9 +410,9 @@ describe('Number utils :: renderFromWei', () => { }); it('renderFromWei using BN number', () => { - expect(renderFromWei(new BN4('133700000000000000'))).toEqual('0.1337'); - expect(renderFromWei(new BN4('1337'))).toEqual('< 0.00001'); - expect(renderFromWei(new BN4('0'))).toEqual('0'); + expect(renderFromWei(new BN('133700000000000000'))).toEqual('0.1337'); + expect(renderFromWei(new BN('1337'))).toEqual('< 0.00001'); + expect(renderFromWei(new BN('0'))).toEqual('0'); }); }); @@ -479,9 +478,9 @@ describe('Number utils :: localizeLargeNumber', () => { describe('Number utils :: calcTokenValueToSend', () => { it('calcTokenValueToSend', () => { - expect(calcTokenValueToSend(new BN4(1337), 0)).toEqual('539'); - expect(calcTokenValueToSend(new BN4(1337), 9)).toEqual('1374b68fa00'); - expect(calcTokenValueToSend(new BN4(1337), 18)).toEqual( + expect(calcTokenValueToSend(new BN(1337), 0)).toEqual('539'); + expect(calcTokenValueToSend(new BN(1337), 9)).toEqual('1374b68fa00'); + expect(calcTokenValueToSend(new BN(1337), 18)).toEqual( '487a9a304539440000', ); }); @@ -492,7 +491,7 @@ describe('Number utils :: hexToBN', () => { expect(hexToBN('0x539').toNumber()).toBe(1337); }); it('should handle non string values', () => { - const newBN = new BN4(1); + const newBN = new BN(1); expect(hexToBN(newBN)).toBe(newBN); }); }); @@ -501,7 +500,7 @@ describe('Number utils :: isBN', () => { it('isBN', () => { const notABN = '0x539'; expect(isBN(notABN)).toEqual(false); - expect(isBN(new BN4(1337))).toEqual(true); + expect(isBN(new BN(1337))).toEqual(true); }); }); @@ -698,7 +697,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('1650000007.7'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('1650000007'); + const expected: any = new BN('1650000007'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -711,7 +710,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN(1650000007.7); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('1650000007'); + const expected: any = new BN('1650000007'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -724,7 +723,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('16500'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('16500'); + const expected: any = new BN('16500'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -737,7 +736,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN(16500); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('16500'); + const expected: any = new BN('16500'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -750,7 +749,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('-1650000007.7'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('-1650000007'); + const expected: any = new BN('-1650000007'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -763,7 +762,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN(-1650000007.7); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('-1650000007'); + const expected: any = new BN('-1650000007'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -776,7 +775,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('-16500'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('-16500'); + const expected: any = new BN('-16500'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -789,7 +788,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN(-16500); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('-16500'); + const expected: any = new BN('-16500'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -802,7 +801,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('75BCD15'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('123456789'); + const expected: any = new BN('123456789'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -815,7 +814,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('0x75BCD15'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('123456789'); + const expected: any = new BN('123456789'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -828,7 +827,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('-75BCD15'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('-123456789'); + const expected: any = new BN('-123456789'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -841,7 +840,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('-0x75BCD15'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('-123456789'); + const expected: any = new BN('-123456789'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -854,7 +853,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('0'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('0'); + const expected: any = new BN('0'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -867,7 +866,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('0x0'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('0'); + const expected: any = new BN('0'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -880,7 +879,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN('0xNaN'); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('0'); + const expected: any = new BN('0'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -893,7 +892,7 @@ describe('Number utils :: safeNumberToBN', () => { const result: any = safeNumberToBN(NaN); // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any - const expected: any = new BN4('0'); + const expected: any = new BN('0'); expect(result.words[0]).toEqual(expected.words[0]); expect(result.words[1]).toEqual(expected.words[1]); expect(result.negative).toEqual(expected.negative); @@ -1054,7 +1053,7 @@ describe('Number utils :: formatValueToMatchTokenDecimals', () => { describe('Number utils :: safeBNToHex', () => { it('returns hex string', () => { - expect(safeBNToHex(new BN4('255'))).toBe('0xff'); + expect(safeBNToHex(new BN('255'))).toBe('0xff'); }); it.each([undefined, null])( diff --git a/app/util/transaction-reducer-helpers.ts b/app/util/transaction-reducer-helpers.ts index 769b4ae05e09..7dc03b5eb20f 100644 --- a/app/util/transaction-reducer-helpers.ts +++ b/app/util/transaction-reducer-helpers.ts @@ -1,5 +1,5 @@ import { SecurityAlertResponse } from '@metamask/transaction-controller'; -import type BN from 'bnjs4'; +import type BN from 'bn.js'; interface TxMeta { data?: string; diff --git a/app/util/transactions/index.js b/app/util/transactions/index.js index c78a43790c39..7f2e55c1e4d6 100644 --- a/app/util/transactions/index.js +++ b/app/util/transactions/index.js @@ -1,5 +1,5 @@ import { addHexPrefix, toChecksumAddress } from 'ethereumjs-util'; -import BN from 'bnjs4'; +import BN from 'bn.js'; import { rawEncode, rawDecode } from 'ethereumjs-abi'; import BigNumber from 'bignumber.js'; import humanizeDuration from 'humanize-duration'; diff --git a/app/util/transactions/index.test.ts b/app/util/transactions/index.test.ts index d6040f10f353..762bce0683ec 100644 --- a/app/util/transactions/index.test.ts +++ b/app/util/transactions/index.test.ts @@ -1,5 +1,5 @@ import { swapsUtils } from '@metamask/swaps-controller'; -import BN from 'bnjs4'; +import BN from 'bn.js'; /* eslint-disable-next-line import/no-namespace */ import * as controllerUtilsModule from '@metamask/controller-utils'; diff --git a/package.json b/package.json index c835afeb1d44..02def2778b3e 100644 --- a/package.json +++ b/package.json @@ -228,8 +228,7 @@ "axios": "^1.6.8", "base-64": "1.0.0", "bignumber.js": "^9.0.1", - "bnjs4": "npm:bn.js@^4.12.0", - "bnjs5": "npm:bn.js@^5.2.1", + "bn.js": "^5.2.1", "buffer": "6.0.3", "cockatiel": "^3.1.2", "compare-versions": "^3.6.0", @@ -394,8 +393,7 @@ "@testing-library/react": "14.0.0", "@testing-library/react-hooks": "^8.0.1", "@testing-library/react-native": "12.1.2", - "@types/bnjs4": "npm:@types/bn.js@^4.11.6", - "@types/bnjs5": "npm:@types/bn.js@^5.1.6", + "@types/bn.js": "^5.1.6", "@types/crypto-js": "^4.1.1", "@types/enzyme": "^3.10.12", "@types/eth-url-parser": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index 60b9cc450c29..5f8592fad6c1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9478,21 +9478,7 @@ dependencies: "@types/node" "*" -"@types/bn.js@^5.1.0", "@types/bn.js@^5.1.5": - version "5.1.5" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.5.tgz#2e0dacdcce2c0f16b905d20ff87aedbc6f7b4bf0" - integrity sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A== - dependencies: - "@types/node" "*" - -"@types/bnjs4@npm:@types/bn.js@^4.11.6": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== - dependencies: - "@types/node" "*" - -"@types/bnjs5@npm:@types/bn.js@^5.1.6": +"@types/bn.js@^5.1.0", "@types/bn.js@^5.1.5", "@types/bn.js@^5.1.6": version "5.1.6" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.6.tgz#9ba818eec0c85e4d3c679518428afdf611d03203" integrity sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w== @@ -13404,16 +13390,6 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -"bnjs4@npm:bn.js@^4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - -"bnjs5@npm:bn.js@^5.2.1": - version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - body-parser@1.20.3, body-parser@^1.15.2, body-parser@^1.18.2, body-parser@^1.19.0: version "1.20.3" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" From fca7026b7e5d2084985d190cd1761cd989aa2aaf Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 05:29:53 +0000 Subject: [PATCH 12/57] fix: toBN handle 0x-prefixed strings --- app/util/number/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 625177ab1437..c6c6dad0d787 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -376,7 +376,9 @@ export function isDecimal(value) { * @returns {Object} - BN instance */ export function toBN(value) { - return new BN(value); + return value?.startsWith('0x') + ? hexToBN(value) + : new BN(value || '0'); } /** From b1e0cf9d6759bb2de981a6e793499a7925aa3b15 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 06:18:18 +0000 Subject: [PATCH 13/57] fix: keep treating NaN as 0 --- app/util/number/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/util/number/index.js b/app/util/number/index.js index c6c6dad0d787..831335468987 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -376,6 +376,10 @@ export function isDecimal(value) { * @returns {Object} - BN instance */ export function toBN(value) { + // TODO: Throw on NaN input + if (isNaN(value)) { + return new BN(0); + } return value?.startsWith('0x') ? hexToBN(value) : new BN(value || '0'); From 5dff7dcb5ed4d3b60a0364353d21d1112038e5c3 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 06:42:10 +0000 Subject: [PATCH 14/57] deps: number-to-bn -> @metamask/number-to-bn --- app/util/number/index.js | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 831335468987..76dfef8ee347 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -5,8 +5,8 @@ import { stripHexPrefix } from 'ethereumjs-util'; import BN from 'bn.js'; import { utils as ethersUtils } from 'ethers'; import convert from '@metamask/ethjs-unit'; +import numberToBN from '@metamask/number-to-bn'; import { add0x, remove0x } from '@metamask/utils'; -import numberToBN from 'number-to-bn'; import BigNumber from 'bignumber.js'; import currencySymbols from '../currency-symbols.json'; @@ -377,7 +377,7 @@ export function isDecimal(value) { */ export function toBN(value) { // TODO: Throw on NaN input - if (isNaN(value)) { + if (typeof value === 'number' && isNaN(value)) { return new BN(0); } return value?.startsWith('0x') diff --git a/package.json b/package.json index 02def2778b3e..3ed82b4ea44d 100644 --- a/package.json +++ b/package.json @@ -164,6 +164,7 @@ "@metamask/message-signing-snap": "^0.3.3", "@metamask/network-controller": "^21.0.0", "@metamask/notification-services-controller": "^0.8.2", + "@metamask/number-to-bn": "^1.7.1", "@metamask/permission-controller": "^11.0.0", "@metamask/phishing-controller": "^12.0.3", "@metamask/post-message-stream": "^8.0.0", @@ -261,7 +262,6 @@ "lottie-react-native": "5.1.5", "mockttp": "^3.15.2", "multihashes": "0.4.14", - "number-to-bn": "1.7.0", "path": "0.12.7", "pbkdf2": "3.1.2", "pify": "6.1.0", From 4887e4a1f0b2ab0e3a74ddd973b83217e152c064 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 06:50:54 +0000 Subject: [PATCH 15/57] hexToBN backwards-compatibility --- app/util/number/index.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 76dfef8ee347..4d57890d2cdb 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -25,10 +25,15 @@ const BIG_NUMBER_ETH_MULTIPLIER = new BigNumber('1'); * @param inputHex - Number represented as a hex string. * @returns A BN instance. */ -export const hexToBN = (inputHex) => - typeof inputHex !== 'string' - ? new BN(inputHex, 16) - : (inputHex ? new BN(remove0x(inputHex), 16) : new BN(0)); +export function hexToBN(inputHex) { + if (typeof inputHex === 'number' && isNaN(inputHex) || !inputHex) { + return new BN(0); + } + + return typeof inputHex === 'string' + ? new BN(remove0x(inputHex), 16) + : new BN(inputHex, 16); +} /** * Converts a BN object to a hex string with a '0x' prefix. From 341884c32d7c2bc76e5b4b294d9690cf24648c25 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 06:55:21 +0000 Subject: [PATCH 16/57] toBN backwards-compat: falsey means 0 --- app/util/number/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 4d57890d2cdb..1e88c1d46157 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -382,7 +382,7 @@ export function isDecimal(value) { */ export function toBN(value) { // TODO: Throw on NaN input - if (typeof value === 'number' && isNaN(value)) { + if (typeof value === 'number' && isNaN(value) || !value) { return new BN(0); } return value?.startsWith('0x') From c0bbd6fc189f228b8d90370433ae4960e9c81c2b Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 06:59:44 +0000 Subject: [PATCH 17/57] fix: treat string "NaN" as 0 --- app/util/number/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 1e88c1d46157..a6b85bfe0f31 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -382,7 +382,7 @@ export function isDecimal(value) { */ export function toBN(value) { // TODO: Throw on NaN input - if (typeof value === 'number' && isNaN(value) || !value) { + if (typeof value === 'number' && isNaN(value) || !value || value === 'NaN') { return new BN(0); } return value?.startsWith('0x') From 6a86289356e4ebd85202477803289dbdfbdb3cb3 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 07:28:00 +0000 Subject: [PATCH 18/57] fix: default decimals=0 to prevent NaN calculation --- app/util/number/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index a6b85bfe0f31..209aa7d750d8 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -115,7 +115,7 @@ export function fromWei(value = 0, unit = 'ether') { */ export function fromTokenMinimalUnit( minimalInput, - decimals, + decimals = 0, isRounding = true, ) { minimalInput = isRounding ? Number(minimalInput) : minimalInput; From f2dc7e4c1023b6d23a179626227e492d1e599416 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 07:30:34 +0000 Subject: [PATCH 19/57] fix(test): bn.js does not support scientific notation input --- app/util/number/index.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/util/number/index.test.ts b/app/util/number/index.test.ts index 50af9bd15898..ce02a0672c47 100644 --- a/app/util/number/index.test.ts +++ b/app/util/number/index.test.ts @@ -98,10 +98,6 @@ describe('Number utils :: toWei', () => { // BN.js do not support such big numbers expect(() => toWei(new BN(1.337e18))).toThrow(Error); expect(() => toWei(new BN(1337000000000000000))).toThrow(Error); - // For some reason this returns 8338418000000000000000000 wei - expect(toWei(new BN('1.337e18'))).not.toEqual( - '1337000000000000000000000000000000000', - ); }); }); From 8561783c77469c0725e4187632c95ae1ca512ca3 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 07:45:13 +0000 Subject: [PATCH 20/57] fix: toGwei, renderToGwei --- app/util/number/index.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 209aa7d750d8..993f1ef43783 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -449,7 +449,7 @@ export function toWei(value, unit = 'ether') { * @returns {Object} - BN instance containing the new number */ export function toGwei(value, unit = 'ether') { - return fromWei(value, unit) * 1000000000; + return fromWei(toBN(value), unit).mul(1000000000); } /** @@ -460,10 +460,8 @@ export function toGwei(value, unit = 'ether') { * @returns {string} - String instance containing the renderable number */ export function renderToGwei(value, unit = 'ether') { - const gwei = fromWei(value, unit) * 1000000000; - let gweiFixed = parseFloat(Math.round(gwei)); - gweiFixed = isNaN(gweiFixed) ? 0 : gweiFixed; - return gweiFixed; + const gwei = toGwei(value, unit); + return gwei.toString(); } /** From b31de2de1e9dd9dfbcb7d33435389f4600be6b57 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 08:02:22 +0000 Subject: [PATCH 21/57] wip: simplify fromTokenMinimalUnit --- app/util/number/index.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 993f1ef43783..49563383703d 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -116,8 +116,14 @@ export function fromWei(value = 0, unit = 'ether') { export function fromTokenMinimalUnit( minimalInput, decimals = 0, - isRounding = true, + _isRounding = true, ) { + const value = new BigNumber( + (isBN(minimalInput) ? minimalInput.toString(10) : minimalInput), + 10, + ) + return value.shiftedBy(parseInt(-decimals, 10)).toString(10, decimals); + /* minimalInput = isRounding ? Number(minimalInput) : minimalInput; const prefixedInput = addHexPrefix(minimalInput.toString(16)); let minimal = safeNumberToBN(prefixedInput); @@ -138,6 +144,7 @@ export function fromTokenMinimalUnit( value = '-' + value; } return value; + */ } /** @@ -385,6 +392,9 @@ export function toBN(value) { if (typeof value === 'number' && isNaN(value) || !value || value === 'NaN') { return new BN(0); } + if (isBN(value)) { + return value; + } return value?.startsWith('0x') ? hexToBN(value) : new BN(value || '0'); From a240931a749eac459aedde67b72cd678973aaded Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 08:16:44 +0000 Subject: [PATCH 22/57] chore: update expected results for incorrectly rounding cases --- app/util/number/index.test.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/util/number/index.test.ts b/app/util/number/index.test.ts index ce02a0672c47..1faf39c776eb 100644 --- a/app/util/number/index.test.ts +++ b/app/util/number/index.test.ts @@ -148,12 +148,17 @@ describe('Number utils :: fromTokenMinimalUnit', () => { // test decimal greater than 30,000 expect(fromTokenMinimalUnit(new BN('50000000000000000000000'), 18)).toEqual( - '49999.999999999995805696', + '50000', + ); + expect(fromTokenMinimalUnit(parseFloat('69999999999999999999999'), 18)).toEqual( + '69999.999999999996', ); // test decimal less than 1e-14 expect(fromTokenMinimalUnit(hexToBN('576129d2d21d64a5'), 18)).toEqual( - '6.296359739485676544', + // exactly correct: + // '6.296359739485677000', + '6.296359739485676709', ); }); From 6cc0955d6514dadec702cbd1dde30c49230cfeb8 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 08:26:12 +0000 Subject: [PATCH 23/57] fixup --- app/util/number/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 49563383703d..923e4acc08cc 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -459,7 +459,7 @@ export function toWei(value, unit = 'ether') { * @returns {Object} - BN instance containing the new number */ export function toGwei(value, unit = 'ether') { - return fromWei(toBN(value), unit).mul(1000000000); + return toBN(fromWei(toBN(value), unit)).mul(1000000000); } /** From 6b53e86fbb0869a9440ec42ab54944bdb67030c6 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 08:54:51 +0000 Subject: [PATCH 24/57] use bignum.js for weiToFiatNumber --- app/util/number/index.js | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 923e4acc08cc..8c60be7836fb 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -121,7 +121,7 @@ export function fromTokenMinimalUnit( const value = new BigNumber( (isBN(minimalInput) ? minimalInput.toString(10) : minimalInput), 10, - ) + ); return value.shiftedBy(parseInt(-decimals, 10)).toString(10, decimals); /* minimalInput = isRounding ? Number(minimalInput) : minimalInput; @@ -562,11 +562,8 @@ export function addCurrencySymbol( * @returns {Number} - The converted balance */ export function weiToFiatNumber(wei, conversionRate, decimalsToShow = 5) { - const base = Math.pow(10, decimalsToShow); - const eth = fromWei(wei).toString(); - let value = parseFloat(Math.floor(eth * conversionRate * base) / base); - value = isNaN(value) ? 0.0 : value; - return value; + const eth = new BigNumber(fromWei(wei), 10); + return eth.multipliedBy(new BigNumber(conversionRate, 10)).toString(10, decimalsToShow); } /** From b2dd6bf00aa6e89e5c47081a98b88d6343612a29 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 09:10:58 +0000 Subject: [PATCH 25/57] fixup --- app/util/number/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 8c60be7836fb..214981f933dd 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -459,7 +459,7 @@ export function toWei(value, unit = 'ether') { * @returns {Object} - BN instance containing the new number */ export function toGwei(value, unit = 'ether') { - return toBN(fromWei(toBN(value), unit)).mul(1000000000); + return toBN(fromWei(value, unit)).mul(1000000000); } /** From 24c82e6bd9234151a1bc6591edfd25b31b3c8c15 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 09:15:18 +0000 Subject: [PATCH 26/57] fix --- app/util/number/index.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 214981f933dd..9a222c909c05 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -554,7 +554,7 @@ export function addCurrencySymbol( } /** - * Converts wei expressed as a BN instance into a human-readable fiat string + * Converts wei expressed as a BN instance into a fiat number * * @param {number|string|BN} wei - BN corresponding to an amount of wei * @param {number} conversionRate - ETH to current currency conversion rate @@ -563,7 +563,8 @@ export function addCurrencySymbol( */ export function weiToFiatNumber(wei, conversionRate, decimalsToShow = 5) { const eth = new BigNumber(fromWei(wei), 10); - return eth.multipliedBy(new BigNumber(conversionRate, 10)).toString(10, decimalsToShow); + const value = parseFloat(eth.multipliedBy(new BigNumber(conversionRate, 10)).toPrecision(decimalsToShow)); + return isNaN(value) ? '0.0' : value; } /** From 523eba2d0fbc04f37f20d245b4f6096b11b7d0ac Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 09:34:30 +0000 Subject: [PATCH 27/57] fix: toGwei use BigNumber, not BN --- app/components/UI/TransactionElement/utils.test.js | 2 +- app/util/number/index.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/components/UI/TransactionElement/utils.test.js b/app/components/UI/TransactionElement/utils.test.js index 5e85a9abdbbd..9b9f761e2e1d 100644 --- a/app/components/UI/TransactionElement/utils.test.js +++ b/app/components/UI/TransactionElement/utils.test.js @@ -160,7 +160,7 @@ describe('Utils', () => { hash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', renderFrom: '0xABcdEFABcdEFabcdEfAbCdefabcdeFABcDEFabCD', renderGas: '21000', - renderGasPrice: 1, + renderGasPrice: '1', renderTo: '0x1234567890AbcdEF1234567890aBcdef12345678', renderTotalGas: '0.00002 ETH', renderValue: '0 ETH', diff --git a/app/util/number/index.js b/app/util/number/index.js index 9a222c909c05..581a14f0ad9a 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -456,10 +456,10 @@ export function toWei(value, unit = 'ether') { * * @param {number|string|BN} value - Value to convert * @param {string} unit - Unit to convert from, ether by default - * @returns {Object} - BN instance containing the new number + * @returns {Object} - BIgNumber instance containing the new number */ export function toGwei(value, unit = 'ether') { - return toBN(fromWei(value, unit)).mul(1000000000); + return new BigNumber(fromWei(value, unit)).multipliedBy(1000000000); } /** @@ -467,11 +467,11 @@ export function toGwei(value, unit = 'ether') { * * @param {number|string|BN} value - Value to convert * @param {string} unit - Unit to convert from, ether by default - * @returns {string} - String instance containing the renderable number + * @returns {string} - String representation of the converted value */ export function renderToGwei(value, unit = 'ether') { const gwei = toGwei(value, unit); - return gwei.toString(); + return gwei.toString(10); } /** From db0ac07fa33c23cc1b3be04a1fc9aa06e85d0d8d Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 09:41:55 +0000 Subject: [PATCH 28/57] fix weiToFiat --- app/util/number/index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 581a14f0ad9a..4eecb96def99 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -489,8 +489,10 @@ export function weiToFiat( currencyCode, decimalsToShow = 5, ) { - if (!conversionRate) return undefined; - if (!wei || !isBN(wei) || !conversionRate) { + if (typeof wei === 'undefined' || !conversionRate || typeof wei === 'number' && isNaN(wei) || !conversionRate) { + return undefined; + } + if (!wei || typeof wei !== 'number' && !isBN(wei)) { return addCurrencySymbol(0, currencyCode); } decimalsToShow = (currencyCode === 'usd' && 2) || undefined; From 96b490c8e988ec48381cbad4562883567dab00fa Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 09:45:28 +0000 Subject: [PATCH 29/57] fix weiToFiat --- app/util/number/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 4eecb96def99..4903f43d184d 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -489,10 +489,10 @@ export function weiToFiat( currencyCode, decimalsToShow = 5, ) { - if (typeof wei === 'undefined' || !conversionRate || typeof wei === 'number' && isNaN(wei) || !conversionRate) { + if (typeof wei === 'undefined' || !conversionRate || typeof wei === 'number' && isNaN(wei) || !conversionRate || typeof wei !== 'number' && !isBN(wei)) { return undefined; } - if (!wei || typeof wei !== 'number' && !isBN(wei)) { + if (!wei) { return addCurrencySymbol(0, currencyCode); } decimalsToShow = (currencyCode === 'usd' && 2) || undefined; From f5c47879c3df22aab6d10c33c5740de7a7a3a654 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 09:52:34 +0000 Subject: [PATCH 30/57] fix weiToFiat --- app/util/number/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 4903f43d184d..07def5c59c21 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -489,7 +489,7 @@ export function weiToFiat( currencyCode, decimalsToShow = 5, ) { - if (typeof wei === 'undefined' || !conversionRate || typeof wei === 'number' && isNaN(wei) || !conversionRate || typeof wei !== 'number' && !isBN(wei)) { + if (typeof wei === 'undefined' || !conversionRate || (typeof wei === 'number' || isNaN(wei)) && isNaN(wei) || typeof wei !== 'number' && !isBN(wei)) { return undefined; } if (!wei) { From d7acee3e59e2b6fbe32dad2b7b4b6c79a2229348 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 09:58:02 +0000 Subject: [PATCH 31/57] fix weiToFiatNumber --- app/util/number/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 07def5c59c21..1f4062444e17 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -564,9 +564,12 @@ export function addCurrencySymbol( * @returns {Number} - The converted balance */ export function weiToFiatNumber(wei, conversionRate, decimalsToShow = 5) { + if (!conversionRate) { + return undefined; + } const eth = new BigNumber(fromWei(wei), 10); const value = parseFloat(eth.multipliedBy(new BigNumber(conversionRate, 10)).toPrecision(decimalsToShow)); - return isNaN(value) ? '0.0' : value; + return value; } /** From 6b4ce3ed1f7346cc71af37e76c6205b54bcb8279 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 10:21:13 +0000 Subject: [PATCH 32/57] fix weiToFiatNumber --- app/components/UI/Stake/hooks/useBalance.test.tsx | 2 +- app/util/number/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/components/UI/Stake/hooks/useBalance.test.tsx b/app/components/UI/Stake/hooks/useBalance.test.tsx index 17c73f1685ce..15423d89db71 100644 --- a/app/components/UI/Stake/hooks/useBalance.test.tsx +++ b/app/components/UI/Stake/hooks/useBalance.test.tsx @@ -77,7 +77,7 @@ describe('useBalance', () => { expect(result.current.balanceFiatNumber).toBe(39506172511.6); // Fiat number balance expect(result.current.stakedBalanceWei).toBe('5791332670714232000'); // No staked assets expect(result.current.formattedStakedBalanceETH).toBe('5.79133 ETH'); // Formatted ETH balance - expect(result.current.stakedBalanceFiatNumber).toBe(18532.26454); // Staked balance in fiat number + expect(result.current.stakedBalanceFiatNumber).toBe(18532.26455); // Staked balance in fiat number expect(result.current.formattedStakedBalanceFiat).toBe('$18532.26'); // }); diff --git a/app/util/number/index.js b/app/util/number/index.js index 1f4062444e17..67f4a41849a6 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -568,7 +568,7 @@ export function weiToFiatNumber(wei, conversionRate, decimalsToShow = 5) { return undefined; } const eth = new BigNumber(fromWei(wei), 10); - const value = parseFloat(eth.multipliedBy(new BigNumber(conversionRate, 10)).toPrecision(decimalsToShow)); + const value = parseFloat(eth.multipliedBy(new BigNumber(conversionRate, 10)).decimalPlaces(decimalsToShow).toString()); return value; } From 85cb7d6f700761e99253998bc662bd8ccf840d5c Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 10:27:29 +0000 Subject: [PATCH 33/57] fix: update test case that was asserting incorrect behavior defaulted decimals to 1 instead of 0 --- app/util/transactions/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/util/transactions/index.test.ts b/app/util/transactions/index.test.ts index 762bce0683ec..e1a0798b0485 100644 --- a/app/util/transactions/index.test.ts +++ b/app/util/transactions/index.test.ts @@ -238,7 +238,7 @@ describe('Transactions utils :: parseTransactionLegacy', () => { const expectedResult = createExpectedResult({ totalHexValue: totalHexValueMocked, - transactionTotalAmount: '0.2 ERC20 + 0 tBNB', + transactionTotalAmount: '2 ERC20 + 0 tBNB', transactionTotalAmountFiat: '0 USD', transactionFee: '0 tBNB', }); From d0b509845b6e8fa2f81b2fef28524b6b2c314e50 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 22:18:57 +0000 Subject: [PATCH 34/57] chore: fix incorrectly typed controller messages in test --- .../useTokenBalancesController.test.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/components/hooks/useTokenBalancesController/useTokenBalancesController.test.tsx b/app/components/hooks/useTokenBalancesController/useTokenBalancesController.test.tsx index b0839cb3c8da..c187e1696da1 100644 --- a/app/components/hooks/useTokenBalancesController/useTokenBalancesController.test.tsx +++ b/app/components/hooks/useTokenBalancesController/useTokenBalancesController.test.tsx @@ -4,7 +4,6 @@ import { Provider } from 'react-redux'; import { createStore, Store } from 'redux'; import { act, render, waitFor } from '@testing-library/react-native'; import useTokenBalancesController from './useTokenBalancesController'; -import BN from 'bn.js'; import { cloneDeep } from 'lodash'; import { backgroundState } from '../../../util/test/initial-root-state'; @@ -15,7 +14,7 @@ const mockInitialState = { ...backgroundState, TokenBalancesController: { contractBalances: { - '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': new BN(0x2a), + '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': '0x2a', }, }, }, @@ -104,7 +103,7 @@ describe('useTokenBalancesController()', () => { testStore.dispatch({ type: 'add-balances', value: { - '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b96': new BN(0x539), + '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b96': '0x539', }, }); }); @@ -122,7 +121,7 @@ describe('useTokenBalancesController()', () => { testStore.dispatch({ type: 'add-balances', value: { - '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': new BN(0x2a), + '0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95': '0x2a', }, }); }); From 89ab6bd0524553e023d6d55f5a1b8efe9e444471 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 23:33:05 +0000 Subject: [PATCH 35/57] fix(ramps): use single internal representation of amount instead of 3 --- .../UI/Ramp/Views/BuildQuote/BuildQuote.tsx | 81 +++++-------- .../UI/Ramp/Views/Quotes/Quotes.tsx | 2 +- .../UI/Ramp/hooks/useIntentAmount.test.ts | 111 ------------------ .../UI/Ramp/hooks/useIntentAmount.ts | 17 ++- app/components/UI/Ramp/hooks/useLimits.ts | 15 ++- app/util/smart-transactions/index.test.ts | 24 ++-- app/util/smart-transactions/index.ts | 4 +- 7 files changed, 65 insertions(+), 189 deletions(-) diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx index 2efec4ed2cb6..2ddaffb75879 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx @@ -12,7 +12,7 @@ import Animated, { withTiming, } from 'react-native-reanimated'; import { useNavigation } from '@react-navigation/native'; -import BN from 'bn.js'; +import { BigNumber } from 'bignumber.js'; import { useRampSDK } from '../../sdk'; import usePaymentMethods from '../../hooks/usePaymentMethods'; @@ -65,7 +65,6 @@ import { useStyles } from '../../../../../component-library/hooks'; import styleSheet from './BuildQuote.styles'; import { - toTokenMinimalUnit, fromTokenMinimalUnitString, } from '../../../../../util/number'; import useGasPriceEstimation from '../../hooks/useGasPriceEstimation'; @@ -103,8 +102,6 @@ const BuildQuote = () => { const trackEvent = useAnalytics(); const [amountFocused, setAmountFocused] = useState(false); const [amount, setAmount] = useState('0'); - const [amountNumber, setAmountNumber] = useState(0); - const [amountBNMinimalUnit, setAmountBNMinimalUnit] = useState(); const [error, setError] = useState(null); const keyboardHeight = useRef(1000); const keypadOffset = useSharedValue(1000); @@ -191,8 +188,6 @@ const BuildQuote = () => { useIntentAmount( setAmount, - setAmountNumber, - setAmountBNMinimalUnit, currentFiatCurrency, ); @@ -229,40 +224,43 @@ const BuildQuote = () => { } : undefined, ); + const balanceBigNum = balanceBN + ? new BigNumber(balanceBN.toString(10), 10) + : null; const maxSellAmount = - balanceBN && gasPriceEstimation - ? balanceBN?.sub(gasPriceEstimation.estimatedGasFee) + balanceBigNum && gasPriceEstimation + ? balanceBigNum?.minus(gasPriceEstimation.estimatedGasFee.toString(10)) : null; const amountIsBelowMinimum = useMemo( - () => isAmountBelowMinimum(amountNumber), - [amountNumber, isAmountBelowMinimum], + () => isAmountBelowMinimum(amount), + [amount, isAmountBelowMinimum], ); const amountIsAboveMaximum = useMemo( - () => isAmountAboveMaximum(amountNumber), - [amountNumber, isAmountAboveMaximum], + () => isAmountAboveMaximum(amount), + [amount, isAmountAboveMaximum], ); const amountIsValid = useMemo( - () => isAmountValid(amountNumber), - [amountNumber, isAmountValid], + () => isAmountValid(amount), + [amount, isAmountValid], ); const amountIsOverGas = useMemo(() => { if (isBuy || !maxSellAmount) { return false; } - return Boolean(amountBNMinimalUnit?.gt(maxSellAmount)); - }, [amountBNMinimalUnit, isBuy, maxSellAmount]); + return Boolean(new BigNumber(amount).gt(maxSellAmount)); + }, [amount, isBuy, maxSellAmount]); const hasInsufficientBalance = useMemo(() => { - if (!balanceBN || !amountBNMinimalUnit) { - return false; + if (!balanceBigNum) { + return undefined; } - return balanceBN.lt(amountBNMinimalUnit); - }, [balanceBN, amountBNMinimalUnit]); + return balanceBigNum.lt(amount); + }, [balanceBigNum, amount]); const isFetching = isFetchingCryptoCurrencies || @@ -336,28 +334,18 @@ const BuildQuote = () => { const onAmountInputPress = useCallback(() => setAmountFocused(true), []); const handleKeypadChange = useCallback( - ({ value, valueAsNumber }) => { + ({ value }) => { setAmount(`${value}`); - setAmountNumber(valueAsNumber); - if (isSell) { - setAmountBNMinimalUnit( - toTokenMinimalUnit(`${value}`, selectedAsset?.decimals ?? 0) as BN, - ); - } }, - [isSell, selectedAsset?.decimals], + [], ); const handleQuickAmountPress = useCallback( ({ value }: QuickAmount) => { if (isBuy) { - setAmount(`${value}`); - setAmountNumber(value); + setAmount(value.toString()); } else { - const percentage = value * 100; - const amountPercentage = balanceBN - ?.mul(new BN(percentage)) - .div(new BN(100)); + const amountPercentage = balanceBigNum?.multipliedBy(value); if (!amountPercentage) { return; @@ -372,13 +360,12 @@ const BuildQuote = () => { amountToSet = maxSellAmount; } + // TODO: Too many levels of parsing strings and numbers back and forth here.. const newAmountString = fromTokenMinimalUnitString( amountToSet.toString(10), selectedAsset?.decimals ?? 18, ); - setAmountBNMinimalUnit(amountToSet); setAmount(newAmountString); - setAmountNumber(Number(newAmountString)); } }, [ @@ -408,7 +395,6 @@ const BuildQuote = () => { async (region: Region) => { hideRegionModal(); setAmount('0'); - setAmountNumber(0); if (selectedFiatCurrencyId === defaultFiatCurrency?.id) { /* * Selected fiat currency is default, we will fetch @@ -463,7 +449,6 @@ const BuildQuote = () => { (fiatCurrency) => { setSelectedFiatCurrencyId(fiatCurrency?.id); setAmount('0'); - setAmountNumber(0); hideFiatSelectorModal(); }, [hideFiatSelectorModal, setSelectedFiatCurrencyId], @@ -490,7 +475,7 @@ const BuildQuote = () => { if (selectedAsset && currentFiatCurrency) { navigation.navigate( ...createQuotesNavDetails({ - amount: isBuy ? amountNumber : amount, + amount, asset: selectedAsset, fiatCurrency: currentFiatCurrency, }), @@ -498,7 +483,7 @@ const BuildQuote = () => { const analyticsPayload = { payment_method_id: selectedPaymentMethodId as string, - amount: amountNumber, + amount: parseFloat(amount), location: screenLocation, }; @@ -521,7 +506,6 @@ const BuildQuote = () => { }, [ screenLocation, amount, - amountNumber, currentFiatCurrency, isBuy, navigation, @@ -687,7 +671,7 @@ const BuildQuote = () => { } const displayAmount = isBuy - ? formatAmount(amountNumber) + ? formatAmount(parseFloat(amount)) : `${amount} ${selectedAsset?.symbol}`; let quickAmounts: QuickAmount[] = []; @@ -698,7 +682,7 @@ const BuildQuote = () => { value: quickAmount, label: currentFiatCurrency?.denomSymbol + quickAmount.toString(), })) ?? []; - } else if (balanceBN && !balanceBN.isZero() && maxSellAmount?.gt(new BN(0))) { + } else if (balanceBigNum && !balanceBigNum.isZero() && maxSellAmount?.gt(0)) { quickAmounts = [ { value: 0.25, label: '25%' }, { value: 0.5, label: '50%' }, @@ -783,14 +767,13 @@ const BuildQuote = () => { } amount={displayAmount} highlightedError={ - amountNumber > 0 && (!amountIsValid || amountIsOverGas) + parseFloat(amount) > 0 && (!amountIsValid || amountIsOverGas) } currencyCode={isBuy ? currentFiatCurrency?.symbol : undefined} onPress={onAmountInputPress} onCurrencyPress={isBuy ? handleFiatSelectorPress : undefined} /> - {amountNumber > 0 && - amountIsValid && + {amountIsValid && !hasInsufficientBalance && amountIsOverGas && ( @@ -864,8 +847,8 @@ const BuildQuote = () => { {currentPaymentMethod?.customAction ? ( ) : ( @@ -874,7 +857,7 @@ const BuildQuote = () => { onPress={handleGetQuotePress} accessibilityRole="button" accessible - disabled={amountNumber <= 0} + disabled={parseInt(amount, 10) <= 0} > {strings('fiat_on_ramp_aggregator.get_quotes')} diff --git a/app/components/UI/Ramp/Views/Quotes/Quotes.tsx b/app/components/UI/Ramp/Views/Quotes/Quotes.tsx index 5738cdbc549d..b4cce1f7b9c3 100644 --- a/app/components/UI/Ramp/Views/Quotes/Quotes.tsx +++ b/app/components/UI/Ramp/Views/Quotes/Quotes.tsx @@ -74,7 +74,7 @@ import { getOrdersProviders } from './../../../../../reducers/fiatOrders'; const HIGHLIGHTED_QUOTES_COUNT = 2; export interface QuotesParams { - amount: number | string; + amount: string; asset: CryptoCurrency; fiatCurrency: FiatCurrency; } diff --git a/app/components/UI/Ramp/hooks/useIntentAmount.test.ts b/app/components/UI/Ramp/hooks/useIntentAmount.test.ts index b8a639b71311..d6046b014fe5 100644 --- a/app/components/UI/Ramp/hooks/useIntentAmount.test.ts +++ b/app/components/UI/Ramp/hooks/useIntentAmount.test.ts @@ -46,9 +46,6 @@ const mockFiatCurrenciesData = [ ] as FiatCurrency[]; const mockSetAmount = jest.fn(); -const mockSetAmountNumber = jest.fn(); -const mockSetAmountBNMinimalUnit = jest.fn(); - const mockSetIntent = jest.fn(); const mockUseRampSDKInitialValues: Partial = { @@ -80,14 +77,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).toHaveBeenCalledWith('100'); - expect(mockSetAmountNumber).toHaveBeenCalledWith(100); - expect(mockSetAmountBNMinimalUnit).not.toHaveBeenCalled(); expect(mockSetIntent).toHaveBeenCalledWith(expect.any(Function)); }); @@ -102,14 +95,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).toHaveBeenCalledWith('100.23'); - expect(mockSetAmountNumber).toHaveBeenCalledWith(100.23); - expect(mockSetAmountBNMinimalUnit).not.toHaveBeenCalled(); expect(mockSetIntent).toHaveBeenCalledWith(expect.any(Function)); }); @@ -124,14 +113,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).toHaveBeenCalledWith('100'); - expect(mockSetAmountNumber).toHaveBeenCalledWith(100); - expect(mockSetAmountBNMinimalUnit).not.toHaveBeenCalled(); expect(mockSetIntent).toHaveBeenCalledWith(expect.any(Function)); }); @@ -145,26 +130,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).toHaveBeenCalledWith('100.12345678'); - expect(mockSetAmountNumber.mock.calls).toMatchInlineSnapshot(` - [ - [ - 100.12345678, - ], - ] - `); - expect(mockSetAmountBNMinimalUnit.mock.calls).toMatchInlineSnapshot(` - [ - [ - "254c8454e", - ], - ] - `); expect(mockSetIntent).toHaveBeenCalledWith(expect.any(Function)); }); @@ -182,26 +151,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).toHaveBeenCalledWith('100.1234'); - expect(mockSetAmountNumber.mock.calls).toMatchInlineSnapshot(` - [ - [ - 100.1234, - ], - ] - `); - expect(mockSetAmountBNMinimalUnit.mock.calls).toMatchInlineSnapshot(` - [ - [ - "f4712", - ], - ] - `); expect(mockSetIntent).toHaveBeenCalledWith(expect.any(Function)); }); @@ -219,26 +172,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).toHaveBeenCalledWith('100'); - expect(mockSetAmountNumber.mock.calls).toMatchInlineSnapshot(` - [ - [ - 100, - ], - ] - `); - expect(mockSetAmountBNMinimalUnit.mock.calls).toMatchInlineSnapshot(` - [ - [ - "64", - ], - ] - `); expect(mockSetIntent).toHaveBeenCalledWith(expect.any(Function)); }); @@ -257,26 +194,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).toHaveBeenCalledWith('100.123'); - expect(mockSetAmountNumber.mock.calls).toMatchInlineSnapshot(` - [ - [ - 100.123, - ], - ] - `); - expect(mockSetAmountBNMinimalUnit.mock.calls).toMatchInlineSnapshot(` - [ - [ - "1871b", - ], - ] - `); expect(mockSetIntent).toHaveBeenCalledWith(expect.any(Function)); }); @@ -288,14 +209,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).not.toHaveBeenCalled(); - expect(mockSetAmountNumber).not.toHaveBeenCalled(); - expect(mockSetAmountBNMinimalUnit).not.toHaveBeenCalled(); expect(mockSetIntent).toHaveBeenCalledWith(expect.any(Function)); }); @@ -309,14 +226,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).not.toHaveBeenCalled(); - expect(mockSetAmountNumber).not.toHaveBeenCalled(); - expect(mockSetAmountBNMinimalUnit).not.toHaveBeenCalled(); expect(mockSetIntent).toHaveBeenCalledWith(expect.any(Function)); }); @@ -326,14 +239,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).not.toHaveBeenCalled(); - expect(mockSetAmountNumber).not.toHaveBeenCalled(); - expect(mockSetAmountBNMinimalUnit).not.toHaveBeenCalled(); expect(mockSetIntent).not.toHaveBeenCalled(); }); @@ -345,14 +254,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).not.toHaveBeenCalled(); - expect(mockSetAmountNumber).not.toHaveBeenCalled(); - expect(mockSetAmountBNMinimalUnit).not.toHaveBeenCalled(); expect(mockSetIntent).not.toHaveBeenCalled(); }); @@ -361,14 +266,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).not.toHaveBeenCalled(); - expect(mockSetAmountNumber).not.toHaveBeenCalled(); - expect(mockSetAmountBNMinimalUnit).not.toHaveBeenCalled(); expect(mockSetIntent).not.toHaveBeenCalled(); }); @@ -379,14 +280,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).not.toHaveBeenCalled(); - expect(mockSetAmountNumber).not.toHaveBeenCalled(); - expect(mockSetAmountBNMinimalUnit).not.toHaveBeenCalled(); expect(mockSetIntent).not.toHaveBeenCalled(); }); @@ -396,14 +293,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).not.toHaveBeenCalled(); - expect(mockSetAmountNumber).not.toHaveBeenCalled(); - expect(mockSetAmountBNMinimalUnit).not.toHaveBeenCalled(); expect(mockSetIntent).not.toHaveBeenCalled(); }); @@ -415,14 +308,10 @@ describe('useIntentAmount', () => { renderHook(() => useIntentAmount( mockSetAmount, - mockSetAmountNumber, - mockSetAmountBNMinimalUnit, currentFiatCurrency, ), ); expect(mockSetAmount).not.toHaveBeenCalled(); - expect(mockSetAmountNumber).not.toHaveBeenCalled(); - expect(mockSetAmountBNMinimalUnit).not.toHaveBeenCalled(); expect(mockSetIntent).not.toHaveBeenCalled(); }); }); diff --git a/app/components/UI/Ramp/hooks/useIntentAmount.ts b/app/components/UI/Ramp/hooks/useIntentAmount.ts index d07472685afc..512d5fbcc69b 100644 --- a/app/components/UI/Ramp/hooks/useIntentAmount.ts +++ b/app/components/UI/Ramp/hooks/useIntentAmount.ts @@ -1,8 +1,7 @@ import { useEffect } from 'react'; -import type BN from 'bn.js'; import { useRampSDK } from '../sdk'; import parseAmount from '../utils/parseAmount'; -import { toTokenMinimalUnit } from '../../../../util/number'; +// import { toTokenMinimalUnit } from '../../../../util/number'; import { FiatCurrency } from '@consensys/on-ramp-sdk'; /** @@ -19,10 +18,6 @@ import { FiatCurrency } from '@consensys/on-ramp-sdk'; */ export default function useIntentAmount( setAmount: (amount: React.SetStateAction) => void, - setAmountNumber: (amount: React.SetStateAction) => void, - setAmountBNMinimalUnit: ( - amount: React.SetStateAction, - ) => void, currentFiatCurrency: FiatCurrency | null, ) { const { selectedAsset, intent, setIntent, isBuy, isSell } = useRampSDK(); @@ -35,7 +30,13 @@ export default function useIntentAmount( ? currentFiatCurrency.decimals ?? 0 : selectedAsset.decimals ?? 0, ); + if (!parsedAmount) { + throw new Error(`Empty result for non-empty input '${intent.amount}'`); + } + setAmount(parsedAmount); + // TODO + /* if (parsedAmount) { let valueAsNumber = 0; try { @@ -47,7 +48,6 @@ export default function useIntentAmount( ); } setAmount(parsedAmount); - setAmountNumber(valueAsNumber); if (isSell) { setAmountBNMinimalUnit( toTokenMinimalUnit( @@ -57,6 +57,7 @@ export default function useIntentAmount( ); } } + */ } catch (parsingError) { console.error('Error parsing intent amount', parsingError as Error); } finally { @@ -71,7 +72,5 @@ export default function useIntentAmount( isSell, selectedAsset, setAmount, - setAmountNumber, - setAmountBNMinimalUnit, ]); } diff --git a/app/components/UI/Ramp/hooks/useLimits.ts b/app/components/UI/Ramp/hooks/useLimits.ts index ff36f5d94102..99dab1f4fece 100644 --- a/app/components/UI/Ramp/hooks/useLimits.ts +++ b/app/components/UI/Ramp/hooks/useLimits.ts @@ -1,3 +1,4 @@ +import { BigNumber } from 'bignumber.js'; import useSDKMethod from './useSDKMethod'; import { useRampSDK } from '../sdk'; @@ -18,13 +19,17 @@ const useLimits = () => { selectedFiatCurrencyId, ); - const isAmountBelowMinimum = (amount: number) => - amount !== 0 && limits && amount < limits.minAmount; + const isAmountBelowMinimum = (amount: string): boolean => { + const amountBigNum = new BigNumber(amount, 10); + return amountBigNum.gt(0) && !!limits && amountBigNum.lt(limits.minAmount); + }; - const isAmountAboveMaximum = (amount: number) => - amount !== 0 && limits && amount > limits.maxAmount; + const isAmountAboveMaximum = (amount: string): boolean => { + const amountBigNum = new BigNumber(amount, 10); + return amountBigNum.gt(0) && !!limits && amountBigNum.gt(limits.maxAmount); + }; - const isAmountValid = (amount: number) => + const isAmountValid = (amount: string): boolean => !isAmountBelowMinimum(amount) && !isAmountAboveMaximum(amount); return { diff --git a/app/util/smart-transactions/index.test.ts b/app/util/smart-transactions/index.test.ts index aeec09642c66..c2f09371b0c8 100644 --- a/app/util/smart-transactions/index.test.ts +++ b/app/util/smart-transactions/index.test.ts @@ -313,7 +313,7 @@ describe('Smart Transactions utils', () => { describe('getSmartTransactionMetricsProperties', () => { let smartTransactionsController: SmartTransactionsController; let controllerMessenger: ControllerMessenger; - + beforeEach(() => { smartTransactionsController = { getSmartTransactionByMinedTxHash: jest.fn(), @@ -322,7 +322,7 @@ describe('Smart Transactions utils', () => { subscribe: jest.fn(), } as unknown as ControllerMessenger; }); - + it('returns empty object if transactionMeta is undefined', async () => { const result = await getSmartTransactionMetricsProperties( smartTransactionsController, @@ -332,7 +332,7 @@ describe('Smart Transactions utils', () => { ); expect(result).toEqual({}); }); - + it('returns metrics if smartTransaction is found by getSmartTransactionByMinedTxHash', async () => { const transactionMeta = { hash: '0x123' } as TransactionMeta; const smartTransaction = { @@ -343,7 +343,7 @@ describe('Smart Transactions utils', () => { }, }; (smartTransactionsController.getSmartTransactionByMinedTxHash as jest.Mock).mockReturnValue(smartTransaction); - + const result = await getSmartTransactionMetricsProperties( smartTransactionsController, transactionMeta, @@ -356,7 +356,7 @@ describe('Smart Transactions utils', () => { smart_transaction_proxied: true, }); }); - + it('waits for smartTransaction if not found and waitForSmartTransaction is true', async () => { const transactionMeta = { hash: '0x123' } as TransactionMeta; const smartTransaction = { @@ -372,7 +372,7 @@ describe('Smart Transactions utils', () => { setTimeout(() => callback(smartTransaction), 100); } }); - + const result = await getSmartTransactionMetricsProperties( smartTransactionsController, transactionMeta, @@ -385,11 +385,11 @@ describe('Smart Transactions utils', () => { smart_transaction_proxied: false, }); }); - + it('returns empty object if smartTransaction is not found and waitForSmartTransaction is false', async () => { const transactionMeta = { hash: '0x123' } as TransactionMeta; (smartTransactionsController.getSmartTransactionByMinedTxHash as jest.Mock).mockReturnValue(undefined); - + const result = await getSmartTransactionMetricsProperties( smartTransactionsController, transactionMeta, @@ -398,12 +398,12 @@ describe('Smart Transactions utils', () => { ); expect(result).toEqual({}); }); - + it('returns empty object if smartTransaction is found but statusMetadata is undefined', async () => { const transactionMeta = { hash: '0x123' } as TransactionMeta; const smartTransaction = {}; (smartTransactionsController.getSmartTransactionByMinedTxHash as jest.Mock).mockReturnValue(smartTransaction); - + const result = await getSmartTransactionMetricsProperties( smartTransactionsController, transactionMeta, @@ -412,7 +412,7 @@ describe('Smart Transactions utils', () => { ); expect(result).toEqual({}); }); - + it('returns metrics if smartTransaction is found with statusMetadata', async () => { const transactionMeta = { hash: '0x123' } as TransactionMeta; const smartTransaction = { @@ -423,7 +423,7 @@ describe('Smart Transactions utils', () => { }, }; (smartTransactionsController.getSmartTransactionByMinedTxHash as jest.Mock).mockReturnValue(smartTransaction); - + const result = await getSmartTransactionMetricsProperties( smartTransactionsController, transactionMeta, diff --git a/app/util/smart-transactions/index.ts b/app/util/smart-transactions/index.ts index 82ce0d8bd511..e410a210c63f 100644 --- a/app/util/smart-transactions/index.ts +++ b/app/util/smart-transactions/index.ts @@ -103,8 +103,8 @@ export const getSmartTransactionMetricsProperties = async ( smartTransactionsController.getSmartTransactionByMinedTxHash( transactionMeta.hash, ); - const shouldWaitForSmartTransactionConfirmationDoneEvent = - waitForSmartTransaction && + const shouldWaitForSmartTransactionConfirmationDoneEvent = + waitForSmartTransaction && !smartTransaction?.statusMetadata && // We get this after polling for a status for a Smart Transaction. controllerMessenger; if (shouldWaitForSmartTransactionConfirmationDoneEvent) { From 4bb3be654a410febb432d37f9fdd484203b20dbc Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 23:43:50 +0000 Subject: [PATCH 36/57] fix test --- .../UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx | 2 +- app/components/UI/Ramp/Views/Quotes/Quotes.test.tsx | 2 +- .../useTokenBalancesController.test.tsx.snap | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx index 1e99e0e6abb7..9e4743db7c3d 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx @@ -155,7 +155,7 @@ jest.mock('../../hooks/usePaymentMethods', () => ); const MAX_LIMIT = 4; -const VALID_AMOUNT = 3; +const VALID_AMOUNT = '3'; const MIN_LIMIT = 2; const mockUseLimitsInitialValues: Partial> = { limits: { diff --git a/app/components/UI/Ramp/Views/Quotes/Quotes.test.tsx b/app/components/UI/Ramp/Views/Quotes/Quotes.test.tsx index 22c84f9f7ad7..5a4269bc93e8 100644 --- a/app/components/UI/Ramp/Views/Quotes/Quotes.test.tsx +++ b/app/components/UI/Ramp/Views/Quotes/Quotes.test.tsx @@ -100,7 +100,7 @@ jest.mock('../../hooks/useAnalytics', () => () => mockTrackEvent); jest.mock('../../hooks/useInAppBrowser', () => () => mockRenderInAppBrowser); const mockUseParamsInitialValues: DeepPartial = { - amount: 50, + amount: '50', asset: { symbol: 'ETH', }, diff --git a/app/components/hooks/useTokenBalancesController/__snapshots__/useTokenBalancesController.test.tsx.snap b/app/components/hooks/useTokenBalancesController/__snapshots__/useTokenBalancesController.test.tsx.snap index a066bf90ca6e..2c642f086298 100644 --- a/app/components/hooks/useTokenBalancesController/__snapshots__/useTokenBalancesController.test.tsx.snap +++ b/app/components/hooks/useTokenBalancesController/__snapshots__/useTokenBalancesController.test.tsx.snap @@ -2,24 +2,24 @@ exports[`useTokenBalancesController() should not rerender when state is not changed 1`] = ` - {"data":{"0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95":"2a"}} + {"data":{"0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95":"0x2a"}} `; exports[`useTokenBalancesController() should not rerender when state is not changed 2`] = ` - {"data":{"0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95":"2a"}} + {"data":{"0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95":"0x2a"}} `; exports[`useTokenBalancesController() should rerender when state changed 1`] = ` - {"data":{"0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95":"2a"}} + {"data":{"0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95":"0x2a"}} `; exports[`useTokenBalancesController() should rerender when state changed 2`] = ` - {"data":{"0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95":"2a","0x326836cc6cd09B5aa59B81A7F72F25FcC0136b96":"539"}} + {"data":{"0x326836cc6cd09B5aa59B81A7F72F25FcC0136b95":"0x2a","0x326836cc6cd09B5aa59B81A7F72F25FcC0136b96":"0x539"}} `; From e9fe6439758a0eef1984289a264860e1911ef9a3 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Mon, 28 Oct 2024 23:55:12 +0000 Subject: [PATCH 37/57] fix(useBalance): remove balanceBN --- .../ConfirmAddAsset/ConfirmAddAsset.test.tsx | 2 +- .../Ramp/Views/BuildQuote/BuildQuote.test.tsx | 20 +++---------------- .../UI/Ramp/Views/BuildQuote/BuildQuote.tsx | 7 +++---- app/components/UI/Ramp/hooks/useBalance.ts | 11 +++------- 4 files changed, 10 insertions(+), 30 deletions(-) diff --git a/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx b/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx index fa651057ec64..d6af69b4558d 100644 --- a/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx +++ b/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx @@ -48,7 +48,7 @@ jest.mock('../../../util/navigation/navUtils', () => ({ const mockUseBalanceInitialValue: Partial> = { balanceFiat: '$27.02', - balanceBN: toTokenMinimalUnit('5.36385', 18) as BN, + balance: toTokenMinimalUnit('5.36385', 18).toString(), }; const mockUseBalanceValues: Partial> = { diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx index 9e4743db7c3d..f9bd057411e1 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx @@ -191,7 +191,7 @@ jest.mock('../../../../hooks/useAddressBalance/useAddressBalance', () => const mockUseBalanceInitialValue: Partial> = { balanceFiat: '$27.02', - balanceBN: toTokenMinimalUnit('5.36385', 18) as BN, + balance: '5.36385', }; let mockUseBalanceValues: Partial> = { @@ -666,10 +666,7 @@ describe('BuildQuote View', () => { maxAmount: 10, } as Limits; - mockUseBalanceValues.balanceBN = toTokenMinimalUnit( - '5', - mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN; + mockUseBalanceValues.balance = '5'; render(BuildQuote); const initialAmount = '0'; const overBalanceAmout = '6'; @@ -685,10 +682,7 @@ describe('BuildQuote View', () => { render(BuildQuote); const initialAmount = '0'; - mockUseBalanceValues.balanceBN = toTokenMinimalUnit( - '1', - mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN; + mockUseBalanceValues.balance = '1'; const symbol = mockUseRampSDKValues.selectedAsset?.symbol; fireEvent.press(getByRoleButton(`${initialAmount} ${symbol}`)); fireEvent.press(getByRoleButton('25%')); @@ -716,10 +710,6 @@ describe('BuildQuote View', () => { mockUseBalanceValues = { balance: '1', balanceFiat: '$1.00', - balanceBN: toTokenMinimalUnit( - '1', - mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN, }; mockUseGasPriceEstimationValue = { estimatedGasFee: toTokenMinimalUnit( @@ -749,10 +739,6 @@ describe('BuildQuote View', () => { mockUseBalanceValues = { balance: '1', balanceFiat: '$1.00', - balanceBN: toTokenMinimalUnit( - '1', - mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN, }; mockUseGasPriceEstimationValue = { estimatedGasFee: toTokenMinimalUnit( diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx index 2ddaffb75879..9ef22abbdbb5 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx @@ -216,7 +216,7 @@ const BuildQuote = () => { selectedAddress, ); - const { balanceFiat, balanceBN } = useBalance( + const { balanceFiat, balance } = useBalance( selectedAsset ? { address: selectedAsset.address, @@ -224,8 +224,8 @@ const BuildQuote = () => { } : undefined, ); - const balanceBigNum = balanceBN - ? new BigNumber(balanceBN.toString(10), 10) + const balanceBigNum = balance + ? new BigNumber(balance, 10) : null; const maxSellAmount = @@ -369,7 +369,6 @@ const BuildQuote = () => { } }, [ - balanceBN, isBuy, maxSellAmount, selectedAsset?.address, diff --git a/app/components/UI/Ramp/hooks/useBalance.ts b/app/components/UI/Ramp/hooks/useBalance.ts index 93d9ee02ff82..642dac8181e8 100644 --- a/app/components/UI/Ramp/hooks/useBalance.ts +++ b/app/components/UI/Ramp/hooks/useBalance.ts @@ -22,7 +22,6 @@ import { const defaultReturn = { balance: null, balanceFiat: null, - balanceBN: null, }; interface Asset { @@ -51,14 +50,14 @@ export default function useBalance(asset?: Asset) { return defaultReturn; } - let balance, balanceFiat, balanceBN; + let balance, balanceFiat; if (assetAddress === NATIVE_ADDRESS) { balance = renderFromWei( //@ts-expect-error - TODO: Ramps team accountsByChainId[toHexadecimal(chainId)][selectedAddress]?.balance, ); - balanceBN = hexToBN( + const balanceBN = hexToBN( //@ts-expect-error - TODO: Ramps team accountsByChainId[toHexadecimal(chainId)][selectedAddress]?.balance, ); @@ -78,11 +77,7 @@ export default function useBalance(asset?: Asset) { exchangeRate, currentCurrency, ); - balanceBN = - assetAddress && assetAddress in balances - ? hexToBN(balances[assetAddress]) - : null; } - return { balance, balanceFiat, balanceBN }; + return { balance, balanceFiat }; } From ef2e7a90a01a172d34cc7b8bce995e51fd78f1a5 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 00:19:14 +0000 Subject: [PATCH 38/57] buildquote: add memoizations --- app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx | 1 - app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx b/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx index d6af69b4558d..bf792efa0316 100644 --- a/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx +++ b/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx @@ -7,7 +7,6 @@ import renderWithProvider, { import useBalance from '../Ramp/hooks/useBalance'; import { toTokenMinimalUnit } from '../../../util/number'; import { fireEvent } from '@testing-library/react-native'; -import BN from 'bn.js'; import { RootState } from '../../../reducers'; import { mockNetworkState } from '../../../util/test/network'; import { CHAIN_IDS } from '@metamask/transaction-controller'; diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx index 9ef22abbdbb5..2c0f67348733 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx @@ -253,7 +253,7 @@ const BuildQuote = () => { return false; } return Boolean(new BigNumber(amount).gt(maxSellAmount)); - }, [amount, isBuy, maxSellAmount]); + }, [amount, isBuy, maxSellAmount, balanceBigNum]); const hasInsufficientBalance = useMemo(() => { if (!balanceBigNum) { @@ -369,6 +369,7 @@ const BuildQuote = () => { } }, [ + balanceBigNum, isBuy, maxSellAmount, selectedAsset?.address, From 42d0736a05a78a7831d909a160526d07199cd677 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 00:21:09 +0000 Subject: [PATCH 39/57] chore: update test snapshot --- .../Ramp/Views/BuildQuote/BuildQuote.test.tsx | 4 ++-- .../UI/Ramp/Views/Quotes/Quotes.test.tsx | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx index f9bd057411e1..4bebf35311ae 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx @@ -785,7 +785,7 @@ describe('BuildQuote View', () => { }); expect(mockTrackEvent).toHaveBeenCalledWith('ONRAMP_QUOTES_REQUESTED', { - amount: VALID_AMOUNT, + amount: parseInt(VALID_AMOUNT), currency_source: mockUseFiatCurrenciesValues?.currentFiatCurrency?.symbol, currency_destination: mockUseRampSDKValues?.selectedAsset?.symbol, payment_method_id: mockUsePaymentMethodsValues.currentPaymentMethod?.id, @@ -820,7 +820,7 @@ describe('BuildQuote View', () => { }); expect(mockTrackEvent).toHaveBeenCalledWith('OFFRAMP_QUOTES_REQUESTED', { - amount: VALID_AMOUNT, + amount: parseInt(VALID_AMOUNT), currency_source: mockUseRampSDKValues?.selectedAsset?.symbol, currency_destination: mockUseFiatCurrenciesValues?.currentFiatCurrency?.symbol, diff --git a/app/components/UI/Ramp/Views/Quotes/Quotes.test.tsx b/app/components/UI/Ramp/Views/Quotes/Quotes.test.tsx index 5a4269bc93e8..3a9dbffdbb4f 100644 --- a/app/components/UI/Ramp/Views/Quotes/Quotes.test.tsx +++ b/app/components/UI/Ramp/Views/Quotes/Quotes.test.tsx @@ -257,7 +257,7 @@ describe('Quotes', () => { [ "ONRAMP_QUOTES_EXPANDED", { - "amount": 50, + "amount": "50", "chain_id_destination": "1", "currency_destination": "ETH", "currency_source": "USD", @@ -339,7 +339,7 @@ describe('Quotes', () => { [ "ONRAMP_PROVIDER_SELECTED", { - "amount": 50, + "amount": "50", "chain_id_destination": "1", "crypto_out": 0.0162, "currency_destination": "ETH", @@ -369,7 +369,7 @@ describe('Quotes', () => { [ "OFFRAMP_PROVIDER_SELECTED", { - "amount": 50, + "amount": "50", "chain_id_source": "1", "currency_destination": "USD", "currency_source": "ETH", @@ -404,7 +404,7 @@ describe('Quotes', () => { [ "ONRAMP_PROVIDER_SELECTED", { - "amount": 50, + "amount": "50", "chain_id_destination": "1", "crypto_out": 0.0162, "currency_destination": "ETH", @@ -434,7 +434,7 @@ describe('Quotes', () => { [ "OFFRAMP_PROVIDER_SELECTED", { - "amount": 50, + "amount": "50", "chain_id_source": "1", "currency_destination": "USD", "currency_source": "ETH", @@ -535,7 +535,7 @@ describe('Quotes', () => { [ "ONRAMP_QUOTES_RECEIVED", { - "amount": 50, + "amount": "50", "average_crypto_out": 0.016671, "average_gas_fee": 1.32, "average_processing_fee": 1.455, @@ -564,7 +564,7 @@ describe('Quotes', () => { [ "ONRAMP_QUOTE_ERROR", { - "amount": 50, + "amount": "50", "chain_id_destination": "1", "currency_destination": "ETH", "currency_source": "USD", @@ -594,7 +594,7 @@ describe('Quotes', () => { [ "OFFRAMP_QUOTES_RECEIVED", { - "amount": 50, + "amount": "50", "average_fiat_out": 0.016671, "average_gas_fee": 1.32, "average_processing_fee": 1.455, @@ -623,7 +623,7 @@ describe('Quotes', () => { [ "OFFRAMP_QUOTE_ERROR", { - "amount": 50, + "amount": "50", "chain_id_source": "1", "currency_destination": "USD", "currency_source": "ETH", From 511f945775fd015dfbfea030f89d64a1c0f1270a Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 00:50:26 +0000 Subject: [PATCH 40/57] useBalance refactor, test fix --- .../UI/Ramp/Views/BuildQuote/BuildQuote.tsx | 75 +++++++++++-------- app/components/UI/Ramp/hooks/useBalance.ts | 40 +++++----- 2 files changed, 66 insertions(+), 49 deletions(-) diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx index 2c0f67348733..25442007a7fe 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx @@ -224,14 +224,6 @@ const BuildQuote = () => { } : undefined, ); - const balanceBigNum = balance - ? new BigNumber(balance, 10) - : null; - - const maxSellAmount = - balanceBigNum && gasPriceEstimation - ? balanceBigNum?.minus(gasPriceEstimation.estimatedGasFee.toString(10)) - : null; const amountIsBelowMinimum = useMemo( () => isAmountBelowMinimum(amount), @@ -249,18 +241,29 @@ const BuildQuote = () => { ); const amountIsOverGas = useMemo(() => { + const balanceBigNum = balance + ? new BigNumber(balance, 10) + : null; + const maxSellAmount = + balanceBigNum && gasPriceEstimation + ? balanceBigNum?.minus(gasPriceEstimation.estimatedGasFee.toString(10)) + : null; + if (isBuy || !maxSellAmount) { return false; } return Boolean(new BigNumber(amount).gt(maxSellAmount)); - }, [amount, isBuy, maxSellAmount, balanceBigNum]); + }, [amount, isBuy, balance]); const hasInsufficientBalance = useMemo(() => { + const balanceBigNum = balance + ? new BigNumber(balance, 10) + : null; if (!balanceBigNum) { return undefined; } return balanceBigNum.lt(amount); - }, [balanceBigNum, amount]); + }, [balance, amount]); const isFetching = isFetchingCryptoCurrencies || @@ -345,20 +348,24 @@ const BuildQuote = () => { if (isBuy) { setAmount(value.toString()); } else { + const balanceBigNum = balance + ? new BigNumber(balance, 10) + : null; + const amountPercentage = balanceBigNum?.multipliedBy(value); if (!amountPercentage) { return; } - let amountToSet = amountPercentage; + const maxSellAmount = + balanceBigNum && gasPriceEstimation + ? balanceBigNum?.minus(gasPriceEstimation.estimatedGasFee.toString(10)) + : null; - if ( - selectedAsset?.address === NATIVE_ADDRESS && - maxSellAmount?.lt(amountPercentage) - ) { - amountToSet = maxSellAmount; - } + const amountToSet = ( + selectedAsset?.address === NATIVE_ADDRESS && maxSellAmount?.lt(amountPercentage) + ) ? maxSellAmount : amountPercentage; // TODO: Too many levels of parsing strings and numbers back and forth here.. const newAmountString = fromTokenMinimalUnitString( @@ -369,11 +376,10 @@ const BuildQuote = () => { } }, [ - balanceBigNum, isBuy, - maxSellAmount, selectedAsset?.address, selectedAsset?.decimals, + balance, ], ); @@ -682,17 +688,26 @@ const BuildQuote = () => { value: quickAmount, label: currentFiatCurrency?.denomSymbol + quickAmount.toString(), })) ?? []; - } else if (balanceBigNum && !balanceBigNum.isZero() && maxSellAmount?.gt(0)) { - quickAmounts = [ - { value: 0.25, label: '25%' }, - { value: 0.5, label: '50%' }, - { value: 0.75, label: '75%' }, - { - value: 1, - label: strings('fiat_on_ramp_aggregator.max'), - isNative: selectedAsset?.address === NATIVE_ADDRESS, - }, - ]; + } else { + const balanceBigNum = balance + ? new BigNumber(balance, 10) + : null; + const maxSellAmount = + balanceBigNum && gasPriceEstimation + ? balanceBigNum?.minus(gasPriceEstimation.estimatedGasFee.toString(10)) + : null; + if (balanceBigNum && !balanceBigNum.isZero() && maxSellAmount?.gt(0)) { + quickAmounts = [ + { value: 0.25, label: '25%' }, + { value: 0.5, label: '50%' }, + { value: 0.75, label: '75%' }, + { + value: 1, + label: strings('fiat_on_ramp_aggregator.max'), + isNative: selectedAsset?.address === NATIVE_ADDRESS, + }, + ]; + } } return ( diff --git a/app/components/UI/Ramp/hooks/useBalance.ts b/app/components/UI/Ramp/hooks/useBalance.ts index 642dac8181e8..a7602fdf4ce3 100644 --- a/app/components/UI/Ramp/hooks/useBalance.ts +++ b/app/components/UI/Ramp/hooks/useBalance.ts @@ -29,7 +29,10 @@ interface Asset { decimals: number; } -export default function useBalance(asset?: Asset) { +export default function useBalance(asset?: Asset): { + balance: string|null, + balanceFiat: string|null, +}{ const accountsByChainId = useSelector(selectAccountsByChainId); const chainId = useSelector(selectChainId); const selectedAddress = useSelector( @@ -50,9 +53,8 @@ export default function useBalance(asset?: Asset) { return defaultReturn; } - let balance, balanceFiat; if (assetAddress === NATIVE_ADDRESS) { - balance = renderFromWei( + const balance = renderFromWei( //@ts-expect-error - TODO: Ramps team accountsByChainId[toHexadecimal(chainId)][selectedAddress]?.balance, ); @@ -61,23 +63,23 @@ export default function useBalance(asset?: Asset) { //@ts-expect-error - TODO: Ramps team accountsByChainId[toHexadecimal(chainId)][selectedAddress]?.balance, ); - balanceFiat = weiToFiat(balanceBN, conversionRate, currentCurrency); - } else { - const exchangeRate = tokenExchangeRates?.[assetAddress]?.price; - balance = - assetAddress && assetAddress in balances - ? renderFromTokenMinimalUnit( - balances[assetAddress], - asset.decimals ?? 18, - ) - : 0; - balanceFiat = balanceToFiat( - balance, - conversionRate, - exchangeRate, - currentCurrency, - ); + const balanceFiat = weiToFiat(balanceBN, conversionRate, currentCurrency); + return { balance, balanceFiat }; } + const exchangeRate = tokenExchangeRates?.[assetAddress]?.price; + const balance = + assetAddress && assetAddress in balances + ? renderFromTokenMinimalUnit( + balances[assetAddress], + asset.decimals ?? 18, + ) + : '0'; + const balanceFiat = balanceToFiat( + balance, + conversionRate, + exchangeRate, + currentCurrency, + ); return { balance, balanceFiat }; } From 098cd0f8dca8d32090476f0fb0ad4991fb6be07e Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 01:01:04 +0000 Subject: [PATCH 41/57] buildquote: add memoizations --- app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx index 25442007a7fe..def4f1beeb21 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx @@ -253,7 +253,7 @@ const BuildQuote = () => { return false; } return Boolean(new BigNumber(amount).gt(maxSellAmount)); - }, [amount, isBuy, balance]); + }, [amount, isBuy, balance, gasPriceEstimation]); const hasInsufficientBalance = useMemo(() => { const balanceBigNum = balance @@ -380,6 +380,7 @@ const BuildQuote = () => { selectedAsset?.address, selectedAsset?.decimals, balance, + gasPriceEstimation, ], ); From 2db98c3b35b502a52fd23919f96305678e459e07 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 01:15:48 +0000 Subject: [PATCH 42/57] chore: clean up BuildQuote balance checks --- .../UI/Ramp/Views/BuildQuote/BuildQuote.tsx | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx index def4f1beeb21..f2bfe06d8f7b 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx @@ -241,12 +241,12 @@ const BuildQuote = () => { ); const amountIsOverGas = useMemo(() => { - const balanceBigNum = balance - ? new BigNumber(balance, 10) - : null; - const maxSellAmount = - balanceBigNum && gasPriceEstimation - ? balanceBigNum?.minus(gasPriceEstimation.estimatedGasFee.toString(10)) + if (balance === null) { + return false; + } + const balanceBigNum = new BigNumber(balance, 10); + const maxSellAmount = gasPriceEstimation !== null + ? balanceBigNum.minus(gasPriceEstimation.estimatedGasFee.toString(10)) : null; if (isBuy || !maxSellAmount) { @@ -256,12 +256,10 @@ const BuildQuote = () => { }, [amount, isBuy, balance, gasPriceEstimation]); const hasInsufficientBalance = useMemo(() => { - const balanceBigNum = balance - ? new BigNumber(balance, 10) - : null; - if (!balanceBigNum) { + if (balance === null) { return undefined; } + const balanceBigNum = new BigNumber(balance, 10); return balanceBigNum.lt(amount); }, [balance, amount]); @@ -348,18 +346,14 @@ const BuildQuote = () => { if (isBuy) { setAmount(value.toString()); } else { - const balanceBigNum = balance - ? new BigNumber(balance, 10) - : null; - - const amountPercentage = balanceBigNum?.multipliedBy(value); - - if (!amountPercentage) { + if (balance === null) { return; } + const balanceBigNum = new BigNumber(balance, 10); + + const amountPercentage = balanceBigNum.multipliedBy(value); - const maxSellAmount = - balanceBigNum && gasPriceEstimation + const maxSellAmount = gasPriceEstimation !== null ? balanceBigNum?.minus(gasPriceEstimation.estimatedGasFee.toString(10)) : null; From 9a7c7548c1d18307c56ea5a47ba56aebf923e3c7 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 01:41:15 +0000 Subject: [PATCH 43/57] chore: ramps test reordering --- .../UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx index 4bebf35311ae..e4ac807256c3 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx @@ -723,9 +723,8 @@ describe('BuildQuote View', () => { expect(getByRoleButton(`0.73 ${symbol}`)).toBeTruthy(); }); - it('updates the amount input up to the percentage considering gas', async () => { - render(BuildQuote); const initialAmount = '0'; + it('updates the amount input up to the percentage considering gas', async () => { mockUseRampSDKValues = { ...mockUseRampSDKInitialValues, isBuy: false, @@ -735,7 +734,6 @@ describe('BuildQuote View', () => { address: NATIVE_ADDRESS, }, }; - mockUseBalanceValues = { balance: '1', balanceFiat: '$1.00', @@ -746,6 +744,9 @@ describe('BuildQuote View', () => { mockUseRampSDKValues.selectedAsset?.decimals || 18, ) as BN, }; + + render(BuildQuote); + const symbol = mockUseRampSDKValues.selectedAsset?.symbol; fireEvent.press(getByRoleButton(`${initialAmount} ${symbol}`)); fireEvent.press(getByRoleButton('75%')); From 62494c2b03e2d1cd1ccf19f331856a2c2f3bebc3 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 01:49:15 +0000 Subject: [PATCH 44/57] fix: buildquote cleanup --- .../UI/Ramp/Views/BuildQuote/BuildQuote.tsx | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx index f2bfe06d8f7b..4178448122b9 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx @@ -241,7 +241,7 @@ const BuildQuote = () => { ); const amountIsOverGas = useMemo(() => { - if (balance === null) { + if (isBuy || balance === null) { return false; } const balanceBigNum = new BigNumber(balance, 10); @@ -249,7 +249,7 @@ const BuildQuote = () => { ? balanceBigNum.minus(gasPriceEstimation.estimatedGasFee.toString(10)) : null; - if (isBuy || !maxSellAmount) { + if (!maxSellAmount) { return false; } return Boolean(new BigNumber(amount).gt(maxSellAmount)); @@ -683,15 +683,12 @@ const BuildQuote = () => { value: quickAmount, label: currentFiatCurrency?.denomSymbol + quickAmount.toString(), })) ?? []; - } else { - const balanceBigNum = balance - ? new BigNumber(balance, 10) - : null; - const maxSellAmount = - balanceBigNum && gasPriceEstimation + } else if (balance !== null) { + const balanceBigNum = new BigNumber(balance, 10); + const maxSellAmount = gasPriceEstimation !== null ? balanceBigNum?.minus(gasPriceEstimation.estimatedGasFee.toString(10)) : null; - if (balanceBigNum && !balanceBigNum.isZero() && maxSellAmount?.gt(0)) { + if (!balanceBigNum.isZero() && maxSellAmount?.gt(0)) { quickAmounts = [ { value: 0.25, label: '25%' }, { value: 0.5, label: '50%' }, @@ -894,7 +891,7 @@ const BuildQuote = () => { : `${selectedAsset?.symbol}-crypto` } decimals={ - isBuy ? currentFiatCurrency?.decimals : selectedAsset?.decimals + (isBuy ? currentFiatCurrency?.decimals : selectedAsset?.decimals) ?? 0 } /> From 252458383d1d68d4546048bf9ddfaae4417bd51f Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 01:53:28 +0000 Subject: [PATCH 45/57] fix: weiToFiat validation fix --- app/util/number/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 67f4a41849a6..cf7672d4d6f5 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -489,7 +489,7 @@ export function weiToFiat( currencyCode, decimalsToShow = 5, ) { - if (typeof wei === 'undefined' || !conversionRate || (typeof wei === 'number' || isNaN(wei)) && isNaN(wei) || typeof wei !== 'number' && !isBN(wei)) { + if (typeof wei === 'undefined' || !conversionRate || (typeof wei === 'number' || isBN(wei)) && isNaN(wei) || typeof wei !== 'number' && !isBN(wei)) { return undefined; } if (!wei) { From f30807734e4b74c9189c02f18ba1f8301522a708 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 02:40:33 +0000 Subject: [PATCH 46/57] fix: BuildQuote quickAmounts fix --- .../UI/Ramp/Views/BuildQuote/BuildQuote.tsx | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx index 4178448122b9..b660e41773ac 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx @@ -675,32 +675,35 @@ const BuildQuote = () => { ? formatAmount(parseFloat(amount)) : `${amount} ${selectedAsset?.symbol}`; - let quickAmounts: QuickAmount[] = []; - - if (isBuy) { - quickAmounts = - limits?.quickAmounts?.map((quickAmount) => ({ - value: quickAmount, - label: currentFiatCurrency?.denomSymbol + quickAmount.toString(), - })) ?? []; - } else if (balance !== null) { + const getQuickAmounts = (): QuickAmount[] => { + if (isBuy) { + return limits?.quickAmounts?.map((quickAmount) => ({ + value: quickAmount, + label: currentFiatCurrency?.denomSymbol + quickAmount.toString(), + })) ?? []; + } + const sellLimits = [ + { value: 0.25, label: '25%' }, + { value: 0.50, label: '50%' }, + { value: 0.75, label: '75%' }, + { + value: 1, + label: strings('fiat_on_ramp_aggregator.max'), + isNative: selectedAsset?.address === NATIVE_ADDRESS, + }, + ]; + if (balance === null || gasPriceEstimation === null) { + return sellLimits; + } const balanceBigNum = new BigNumber(balance, 10); - const maxSellAmount = gasPriceEstimation !== null - ? balanceBigNum?.minus(gasPriceEstimation.estimatedGasFee.toString(10)) - : null; - if (!balanceBigNum.isZero() && maxSellAmount?.gt(0)) { - quickAmounts = [ - { value: 0.25, label: '25%' }, - { value: 0.5, label: '50%' }, - { value: 0.75, label: '75%' }, - { - value: 1, - label: strings('fiat_on_ramp_aggregator.max'), - isNative: selectedAsset?.address === NATIVE_ADDRESS, - }, - ]; + const maxSellAmount = balanceBigNum?.minus(gasPriceEstimation.estimatedGasFee.toString(10)); + if (!balanceBigNum.isZero() && maxSellAmount.gt(0)) { + return sellLimits; } - } + return []; + }; + + const quickAmounts = getQuickAmounts(); return ( From e91a686f246e4f571331bbc0509fd1553e45971a Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 02:56:07 +0000 Subject: [PATCH 47/57] fix: simplify toTokenMinimalUnit --- app/util/number/index.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index cf7672d4d6f5..08fcf2d95da5 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -177,8 +177,11 @@ export function fromTokenMinimalUnitString(minimalInput, decimals) { * @returns {Object} - BN instance containing the new number */ export function toTokenMinimalUnit(tokenValue, decimals) { - const base = toBN(Math.pow(10, decimals).toString()); - let value = convert.numberToString(tokenValue); + //const base = toBN(Math.pow(10, decimals).toString()); + const valueBigNum = new BigNumber(tokenValue.toString(10), 10); + //let value = convert.numberToString(tokenValue); + return valueBigNum.shiftedBy(-decimals).toString(10); + /* const negative = value.substring(0, 1) === '-'; if (negative) { value = value.substring(1); @@ -224,6 +227,7 @@ export function toTokenMinimalUnit(tokenValue, decimals) { tokenMinimal = tokenMinimal.mul(negative); } return new BN(tokenMinimal.toString(10), 10); + */ } /** From 87fb6a292116b88aaf488b3315347c264204daed Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 03:10:14 +0000 Subject: [PATCH 48/57] fixup toTokenMinimalUnit --- app/util/number/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index 08fcf2d95da5..a5a7a4e90088 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -180,7 +180,7 @@ export function toTokenMinimalUnit(tokenValue, decimals) { //const base = toBN(Math.pow(10, decimals).toString()); const valueBigNum = new BigNumber(tokenValue.toString(10), 10); //let value = convert.numberToString(tokenValue); - return valueBigNum.shiftedBy(-decimals).toString(10); + return valueBigNum.shiftedBy(decimals).toString(10); /* const negative = value.substring(0, 1) === '-'; if (negative) { From f3f6be485d7440c00db56bb7b4fd4859f67e48ae Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 03:30:35 +0000 Subject: [PATCH 49/57] fix: toTokenMinimalUnit --- app/util/number/index.js | 9 ++++++++- app/util/number/index.test.ts | 16 ++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index a5a7a4e90088..6a0f1aa9dc41 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -179,8 +179,15 @@ export function fromTokenMinimalUnitString(minimalInput, decimals) { export function toTokenMinimalUnit(tokenValue, decimals) { //const base = toBN(Math.pow(10, decimals).toString()); const valueBigNum = new BigNumber(tokenValue.toString(10), 10); + if (valueBigNum.isNaN()) { + throw new Error(`Could not parse '${tokenValue}' (${typeof tokenValue}) into BigNumber`); + } + const result = valueBigNum.shiftedBy(decimals); + if (result.gt(0) && result.lt(1)) { + throw new Error(`Invalid input '${JSON.stringify(tokenValue, decimals)}'.`); + } //let value = convert.numberToString(tokenValue); - return valueBigNum.shiftedBy(decimals).toString(10); + return result.toString(10); /* const negative = value.substring(0, 1) === '-'; if (negative) { diff --git a/app/util/number/index.test.ts b/app/util/number/index.test.ts index 1faf39c776eb..f278d7b9bf9f 100644 --- a/app/util/number/index.test.ts +++ b/app/util/number/index.test.ts @@ -351,20 +351,20 @@ describe('Number utils :: fromTokenMinimalUnitString', () => { describe('Number utils :: toTokenMinimalUnit', () => { it('toTokenMinimalUnit using number', () => { - expect(toTokenMinimalUnit(1337, 6)).toEqual(new BN('1337000000', 10)); - expect(toTokenMinimalUnit(1337, 0)).toEqual(new BN('1337')); - expect(toTokenMinimalUnit(1337.1, 1)).toEqual(new BN('13371')); + expect(toTokenMinimalUnit(1337, 6)).toEqual('1337000000'); + expect(toTokenMinimalUnit(1337, 0)).toEqual('1337'); + expect(toTokenMinimalUnit(1337.1, 1)).toEqual('13371'); }); it('toTokenMinimalUnit using string', () => { - expect(toTokenMinimalUnit('1337', 6)).toEqual(new BN('1337000000')); - expect(toTokenMinimalUnit('1337', 0)).toEqual(new BN('1337')); - expect(toTokenMinimalUnit('1337.1', 2)).toEqual(new BN('133710')); + expect(toTokenMinimalUnit('1337', 6)).toEqual('1337000000'); + expect(toTokenMinimalUnit('1337', 0)).toEqual('1337'); + expect(toTokenMinimalUnit('1337.1', 2)).toEqual('133710'); }); it('toTokenMinimalUnit using BN number', () => { - expect(toTokenMinimalUnit(new BN('1337'), 0)).toEqual(new BN('1337')); - expect(toTokenMinimalUnit(new BN('1337'), 6)).toEqual(new BN('1337000000')); + expect(toTokenMinimalUnit(new BN('1337'), 0)).toEqual('1337'); + expect(toTokenMinimalUnit(new BN('1337'), 6)).toEqual('1337000000'); }); it('toTokenMinimalUnit using invalid inputs', () => { From b4a1d4db75369a9784907dfbcf2b04a97b7ae7db Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 04:27:45 +0000 Subject: [PATCH 50/57] wip: introduce balanceMinimalUnit --- .../ConfirmAddAsset/ConfirmAddAsset.test.tsx | 3 ++- .../Ramp/Views/BuildQuote/BuildQuote.test.tsx | 1 + .../UI/Ramp/Views/BuildQuote/BuildQuote.tsx | 15 +++++++------ app/components/UI/Ramp/hooks/useBalance.ts | 22 ++++++++++--------- app/util/number/index.js | 1 + 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx b/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx index bf792efa0316..c97e01287dde 100644 --- a/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx +++ b/app/components/UI/ConfirmAddAsset/ConfirmAddAsset.test.tsx @@ -47,7 +47,8 @@ jest.mock('../../../util/navigation/navUtils', () => ({ const mockUseBalanceInitialValue: Partial> = { balanceFiat: '$27.02', - balance: toTokenMinimalUnit('5.36385', 18).toString(), + balance: '5.36385', + balanceMinimalUnit: toTokenMinimalUnit('5.36385', 18).toString(), }; const mockUseBalanceValues: Partial> = { diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx index e4ac807256c3..1ebc65fb5578 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx @@ -192,6 +192,7 @@ jest.mock('../../../../hooks/useAddressBalance/useAddressBalance', () => const mockUseBalanceInitialValue: Partial> = { balanceFiat: '$27.02', balance: '5.36385', + balanceMinimalUnit: '5363850000000000000', }; let mockUseBalanceValues: Partial> = { diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx index b660e41773ac..876cd5ebe94f 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx @@ -216,7 +216,7 @@ const BuildQuote = () => { selectedAddress, ); - const { balanceFiat, balance } = useBalance( + const { balance, balanceFiat, balanceMinimalUnit } = useBalance( selectedAsset ? { address: selectedAsset.address, @@ -241,10 +241,10 @@ const BuildQuote = () => { ); const amountIsOverGas = useMemo(() => { - if (isBuy || balance === null) { + if (isBuy || balanceMinimalUnit === null) { return false; } - const balanceBigNum = new BigNumber(balance, 10); + const balanceBigNum = new BigNumber(balanceMinimalUnit, 10); const maxSellAmount = gasPriceEstimation !== null ? balanceBigNum.minus(gasPriceEstimation.estimatedGasFee.toString(10)) : null; @@ -253,7 +253,7 @@ const BuildQuote = () => { return false; } return Boolean(new BigNumber(amount).gt(maxSellAmount)); - }, [amount, isBuy, balance, gasPriceEstimation]); + }, [amount, isBuy, balanceMinimalUnit, gasPriceEstimation]); const hasInsufficientBalance = useMemo(() => { if (balance === null) { @@ -346,10 +346,10 @@ const BuildQuote = () => { if (isBuy) { setAmount(value.toString()); } else { - if (balance === null) { + if (balanceMinimalUnit === null) { return; } - const balanceBigNum = new BigNumber(balance, 10); + const balanceBigNum = new BigNumber(balanceMinimalUnit, 10); const amountPercentage = balanceBigNum.multipliedBy(value); @@ -373,7 +373,7 @@ const BuildQuote = () => { isBuy, selectedAsset?.address, selectedAsset?.decimals, - balance, + balanceMinimalUnit, gasPriceEstimation, ], ); @@ -676,6 +676,7 @@ const BuildQuote = () => { : `${amount} ${selectedAsset?.symbol}`; const getQuickAmounts = (): QuickAmount[] => { + console.warn('GQC', {isBuy, isSell, limits, balance, balanceMinimalUnit, gasPriceEstimation }); if (isBuy) { return limits?.quickAmounts?.map((quickAmount) => ({ value: quickAmount, diff --git a/app/components/UI/Ramp/hooks/useBalance.ts b/app/components/UI/Ramp/hooks/useBalance.ts index a7602fdf4ce3..ace9522ddd7f 100644 --- a/app/components/UI/Ramp/hooks/useBalance.ts +++ b/app/components/UI/Ramp/hooks/useBalance.ts @@ -22,6 +22,7 @@ import { const defaultReturn = { balance: null, balanceFiat: null, + balanceMinimalUnit: null, }; interface Asset { @@ -32,6 +33,7 @@ interface Asset { export default function useBalance(asset?: Asset): { balance: string|null, balanceFiat: string|null, + balanceMinimalUnit: string|null, }{ const accountsByChainId = useSelector(selectAccountsByChainId); const chainId = useSelector(selectChainId); @@ -54,20 +56,20 @@ export default function useBalance(asset?: Asset): { } if (assetAddress === NATIVE_ADDRESS) { - const balance = renderFromWei( - //@ts-expect-error - TODO: Ramps team - accountsByChainId[toHexadecimal(chainId)][selectedAddress]?.balance, - ); + //@ts-expect-error - TODO: Ramps team + const balanceMinimalUnit = accountsByChainId[toHexadecimal(chainId)][selectedAddress]?.balance; + const balance = renderFromWei(balanceMinimalUnit); - const balanceBN = hexToBN( - //@ts-expect-error - TODO: Ramps team - accountsByChainId[toHexadecimal(chainId)][selectedAddress]?.balance, - ); + const balanceBN = hexToBN(balance); const balanceFiat = weiToFiat(balanceBN, conversionRate, currentCurrency); - return { balance, balanceFiat }; + return { balance, balanceFiat, balanceMinimalUnit }; } const exchangeRate = tokenExchangeRates?.[assetAddress]?.price; + const balanceMinimalUnit = + assetAddress && assetAddress in balances + ? balances[assetAddress] + : '0'; const balance = assetAddress && assetAddress in balances ? renderFromTokenMinimalUnit( @@ -81,5 +83,5 @@ export default function useBalance(asset?: Asset): { exchangeRate, currentCurrency, ); - return { balance, balanceFiat }; + return { balance, balanceFiat, balanceMinimalUnit }; } diff --git a/app/util/number/index.js b/app/util/number/index.js index 6a0f1aa9dc41..b13f5012d29e 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -159,6 +159,7 @@ export function fromTokenMinimalUnitString(minimalInput, decimals) { throw new TypeError('minimalInput must be a string'); } + console.warn('HARP', { minimalInput, decimals, }) const tokenFormat = ethersUtils.formatUnits(minimalInput, decimals); const isInteger = Boolean(regex.integer.exec(tokenFormat)); From 34e7d2ce9ec1dfa3a615728c6778b1f8661ab9ff Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 04:46:22 +0000 Subject: [PATCH 51/57] fix Ramps useBalance --- .../Ramp/Views/BuildQuote/BuildQuote.test.tsx | 3 ++ app/components/UI/Ramp/hooks/useBalance.ts | 30 ++++++++++--------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx index 1ebc65fb5578..78a0cc54cc59 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { Limits, Payment } from '@consensys/on-ramp-sdk'; import { act, fireEvent, screen } from '@testing-library/react-native'; import type BN from 'bn.js'; +import { BigNumber } from 'bignumber.js'; import { renderScreen } from '../../../../../util/test/renderWithProvider'; import BuildQuote from './BuildQuote'; import useRegions from '../../hooks/useRegions'; @@ -710,6 +711,7 @@ describe('BuildQuote View', () => { mockUseBalanceValues = { balance: '1', + balanceMinimalUnit: BigNumber(1).shiftedBy(mockUseRampSDKValues.selectedAsset?.decimals || 18).toString(10), balanceFiat: '$1.00', }; mockUseGasPriceEstimationValue = { @@ -737,6 +739,7 @@ describe('BuildQuote View', () => { }; mockUseBalanceValues = { balance: '1', + balanceMinimalUnit: BigNumber(1).shiftedBy(mockUseRampSDKValues.selectedAsset?.decimals || 18).toString(10), balanceFiat: '$1.00', }; mockUseGasPriceEstimationValue = { diff --git a/app/components/UI/Ramp/hooks/useBalance.ts b/app/components/UI/Ramp/hooks/useBalance.ts index ace9522ddd7f..08ac4f888ee3 100644 --- a/app/components/UI/Ramp/hooks/useBalance.ts +++ b/app/components/UI/Ramp/hooks/useBalance.ts @@ -31,9 +31,13 @@ interface Asset { } export default function useBalance(asset?: Asset): { - balance: string|null, - balanceFiat: string|null, - balanceMinimalUnit: string|null, + balance: string, + balanceFiat: string, + balanceMinimalUnit: string, +} | { + balance: null, + balanceFiat: null, + balanceMinimalUnit: null, }{ const accountsByChainId = useSelector(selectAccountsByChainId); const chainId = useSelector(selectChainId); @@ -66,17 +70,15 @@ export default function useBalance(asset?: Asset): { } const exchangeRate = tokenExchangeRates?.[assetAddress]?.price; - const balanceMinimalUnit = - assetAddress && assetAddress in balances - ? balances[assetAddress] - : '0'; - const balance = - assetAddress && assetAddress in balances - ? renderFromTokenMinimalUnit( - balances[assetAddress], - asset.decimals ?? 18, - ) - : '0'; + const balanceMinimalUnit = assetAddress && assetAddress in balances + ? balances[assetAddress] + : '0'; + const balance = balanceMinimalUnit + ? renderFromTokenMinimalUnit( + balanceMinimalUnit, + asset.decimals ?? 18, + ) + : '0'; const balanceFiat = balanceToFiat( balance, conversionRate, From f0473107de7ba589747db3f59d92659cb26bb45b Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 04:49:20 +0000 Subject: [PATCH 52/57] fix: toTokenMinimalUnit, fromTokenMiimalUnitSTring default decimals=0 --- app/util/number/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/util/number/index.js b/app/util/number/index.js index b13f5012d29e..64d54d6447f3 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -154,7 +154,7 @@ export function fromTokenMinimalUnit( * @param {number} decimals - Token decimals to convert * @returns {string} - String containing the new number */ -export function fromTokenMinimalUnitString(minimalInput, decimals) { +export function fromTokenMinimalUnitString(minimalInput, decimals=0) { if (typeof minimalInput !== 'string') { throw new TypeError('minimalInput must be a string'); } @@ -177,7 +177,7 @@ export function fromTokenMinimalUnitString(minimalInput, decimals) { * @param {number} decimals - Unit to convert from, ether by default * @returns {Object} - BN instance containing the new number */ -export function toTokenMinimalUnit(tokenValue, decimals) { +export function toTokenMinimalUnit(tokenValue, decimals=0) { //const base = toBN(Math.pow(10, decimals).toString()); const valueBigNum = new BigNumber(tokenValue.toString(10), 10); if (valueBigNum.isNaN()) { From 2623b573b381d3c0a3832b6ed82b4616ca445aab Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 05:48:21 +0000 Subject: [PATCH 53/57] fix: Ramps BuildQuote fix --- .../UI/Ramp/Views/BuildQuote/BuildQuote.tsx | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx index 876cd5ebe94f..ceaa66703a5b 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.tsx @@ -345,29 +345,29 @@ const BuildQuote = () => { ({ value }: QuickAmount) => { if (isBuy) { setAmount(value.toString()); - } else { - if (balanceMinimalUnit === null) { - return; - } - const balanceBigNum = new BigNumber(balanceMinimalUnit, 10); + return; + } + if (balanceMinimalUnit === null) { + return; + } + const balanceBigNum = new BigNumber(balanceMinimalUnit, 10); - const amountPercentage = balanceBigNum.multipliedBy(value); + const targetAmount = balanceBigNum.multipliedBy(value); - const maxSellAmount = gasPriceEstimation !== null - ? balanceBigNum?.minus(gasPriceEstimation.estimatedGasFee.toString(10)) - : null; + const maxSellAmount = gasPriceEstimation !== null + ? balanceBigNum?.minus(gasPriceEstimation.estimatedGasFee.toString(10)) + : null; - const amountToSet = ( - selectedAsset?.address === NATIVE_ADDRESS && maxSellAmount?.lt(amountPercentage) - ) ? maxSellAmount : amountPercentage; + const amountToSet = ( + selectedAsset?.address === NATIVE_ADDRESS && maxSellAmount?.lt(targetAmount) + ) ? maxSellAmount : targetAmount; - // TODO: Too many levels of parsing strings and numbers back and forth here.. - const newAmountString = fromTokenMinimalUnitString( - amountToSet.toString(10), - selectedAsset?.decimals ?? 18, - ); - setAmount(newAmountString); - } + // TODO: Too many levels of parsing strings and numbers back and forth here.. + const newAmountString = fromTokenMinimalUnitString( + amountToSet.toString(10), + selectedAsset?.decimals ?? 18, + ); + setAmount(newAmountString); }, [ isBuy, @@ -693,10 +693,10 @@ const BuildQuote = () => { isNative: selectedAsset?.address === NATIVE_ADDRESS, }, ]; - if (balance === null || gasPriceEstimation === null) { + if (balanceMinimalUnit === null || gasPriceEstimation === null) { return sellLimits; } - const balanceBigNum = new BigNumber(balance, 10); + const balanceBigNum = new BigNumber(balanceMinimalUnit, 10); const maxSellAmount = balanceBigNum?.minus(gasPriceEstimation.estimatedGasFee.toString(10)); if (!balanceBigNum.isZero() && maxSellAmount.gt(0)) { return sellLimits; From 49d73d8339a718be8291c280fe15e9b2e85c5ca1 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 06:06:34 +0000 Subject: [PATCH 54/57] chore: test, jsdoc fix --- .../Ramp/Views/BuildQuote/BuildQuote.test.tsx | 20 ++++++++++--------- app/util/number/index.js | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx index 78a0cc54cc59..0884e3ecaec3 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Limits, Payment } from '@consensys/on-ramp-sdk'; import { act, fireEvent, screen } from '@testing-library/react-native'; -import type BN from 'bn.js'; +import BN from 'bn.js'; import { BigNumber } from 'bignumber.js'; import { renderScreen } from '../../../../../util/test/renderWithProvider'; import BuildQuote from './BuildQuote'; @@ -241,10 +241,10 @@ let mockUseParamsValues: { const mockUseGasPriceEstimationInitialValue: ReturnType< typeof useGasPriceEstimation > = { - estimatedGasFee: toTokenMinimalUnit( + estimatedGasFee: new BN(toTokenMinimalUnit( '0.01', mockUseRampSDKInitialValues.selectedAsset?.decimals || 18, - ) as BN, + )), }; let mockUseGasPriceEstimationValue: ReturnType = @@ -669,6 +669,7 @@ describe('BuildQuote View', () => { } as Limits; mockUseBalanceValues.balance = '5'; + mockUseBalanceValues.balanceMinimalUnit = (5*Math.pow(10, 18)).toString(10); render(BuildQuote); const initialAmount = '0'; const overBalanceAmout = '6'; @@ -685,6 +686,7 @@ describe('BuildQuote View', () => { const initialAmount = '0'; mockUseBalanceValues.balance = '1'; + mockUseBalanceValues.balanceMinimalUnit = (1*Math.pow(10, 18)).toString(10); const symbol = mockUseRampSDKValues.selectedAsset?.symbol; fireEvent.press(getByRoleButton(`${initialAmount} ${symbol}`)); fireEvent.press(getByRoleButton('25%')); @@ -711,14 +713,14 @@ describe('BuildQuote View', () => { mockUseBalanceValues = { balance: '1', - balanceMinimalUnit: BigNumber(1).shiftedBy(mockUseRampSDKValues.selectedAsset?.decimals || 18).toString(10), + balanceMinimalUnit: (1*Math.pow(10, mockUseRampSDKValues.selectedAsset?.decimals || 18)).toString(10), balanceFiat: '$1.00', }; mockUseGasPriceEstimationValue = { - estimatedGasFee: toTokenMinimalUnit( + estimatedGasFee: new BN(toTokenMinimalUnit( '0.27', mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN, + )), }; const symbol = mockUseRampSDKValues.selectedAsset?.symbol; fireEvent.press(getByRoleButton(`${initialAmount} ${symbol}`)); @@ -739,14 +741,14 @@ describe('BuildQuote View', () => { }; mockUseBalanceValues = { balance: '1', - balanceMinimalUnit: BigNumber(1).shiftedBy(mockUseRampSDKValues.selectedAsset?.decimals || 18).toString(10), + balanceMinimalUnit: (1*Math.pow(10, mockUseRampSDKValues.selectedAsset?.decimals || 18)).toString(10), balanceFiat: '$1.00', }; mockUseGasPriceEstimationValue = { - estimatedGasFee: toTokenMinimalUnit( + estimatedGasFee: new BN(toTokenMinimalUnit( '0.27', mockUseRampSDKValues.selectedAsset?.decimals || 18, - ) as BN, + )), }; render(BuildQuote); diff --git a/app/util/number/index.js b/app/util/number/index.js index 64d54d6447f3..8583df743246 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -175,7 +175,7 @@ export function fromTokenMinimalUnitString(minimalInput, decimals=0) { * * @param {number|string|BN} tokenValue - Value to convert * @param {number} decimals - Unit to convert from, ether by default - * @returns {Object} - BN instance containing the new number + * @returns {string} - string format of new number */ export function toTokenMinimalUnit(tokenValue, decimals=0) { //const base = toBN(Math.pow(10, decimals).toString()); From 242eb0843ba7885f96dd883162ddf2ea37f4e5e4 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 06:08:56 +0000 Subject: [PATCH 55/57] wrap toTokenMinimalUnit value --- app/util/transactions/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/util/transactions/index.js b/app/util/transactions/index.js index 7f2e55c1e4d6..de1bd5f0332a 100644 --- a/app/util/transactions/index.js +++ b/app/util/transactions/index.js @@ -1479,7 +1479,7 @@ export const generateTxWithNewTokenAllowance = ( spenderAddress, transaction, ) => { - const uint = toTokenMinimalUnit(tokenValue, tokenDecimals); + const uint = new BN(toTokenMinimalUnit(tokenValue, tokenDecimals)); const approvalData = generateApprovalData({ spender: spenderAddress, value: uint.gt(UINT256_BN_MAX_VALUE) From e9cbdce5dcbaf0583d6cd66d9eea8ba6d9a7bedd Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 06:26:21 +0000 Subject: [PATCH 56/57] chore: BuildQuote test fix --- .../Ramp/Views/BuildQuote/BuildQuote.test.tsx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx index 0884e3ecaec3..bcb1fdc96efe 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx @@ -668,8 +668,12 @@ describe('BuildQuote View', () => { maxAmount: 10, } as Limits; - mockUseBalanceValues.balance = '5'; - mockUseBalanceValues.balanceMinimalUnit = (5*Math.pow(10, 18)).toString(10); + mockUseBalanceValues = { + ...mockUseBalanceInitialValue, + balance: '5', + balanceMinimalUnit: (5*Math.pow(10, mockUseRampSDKValues.selectedAsset?.decimals || 18)).toString(10), + }; + render(BuildQuote); const initialAmount = '0'; const overBalanceAmout = '6'; @@ -682,12 +686,15 @@ describe('BuildQuote View', () => { }); it('updates the amount input with quick amount buttons', async () => { - render(BuildQuote); const initialAmount = '0'; + mockUseBalanceValues = { + ...mockUseBalanceInitialValue, + balance: '1', + balanceMinimalUnit: (1*Math.pow(10, mockUseRampSDKValues.selectedAsset?.decimals || 18)).toString(10), + }; - mockUseBalanceValues.balance = '1'; - mockUseBalanceValues.balanceMinimalUnit = (1*Math.pow(10, 18)).toString(10); const symbol = mockUseRampSDKValues.selectedAsset?.symbol; + render(BuildQuote); fireEvent.press(getByRoleButton(`${initialAmount} ${symbol}`)); fireEvent.press(getByRoleButton('25%')); expect(getByRoleButton(`0.25 ${symbol}`)).toBeTruthy(); From 2096f8677c35c3f61eb08d1dd89beab5c56cbb08 Mon Sep 17 00:00:00 2001 From: legobt <6wbvkn0j@anonaddy.me> Date: Tue, 29 Oct 2024 06:33:41 +0000 Subject: [PATCH 57/57] lint:fix --- .../UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx | 9 ++++----- app/util/number/index.js | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx index bcb1fdc96efe..62d9ba3c346a 100644 --- a/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx +++ b/app/components/UI/Ramp/Views/BuildQuote/BuildQuote.test.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { Limits, Payment } from '@consensys/on-ramp-sdk'; import { act, fireEvent, screen } from '@testing-library/react-native'; import BN from 'bn.js'; -import { BigNumber } from 'bignumber.js'; import { renderScreen } from '../../../../../util/test/renderWithProvider'; import BuildQuote from './BuildQuote'; import useRegions from '../../hooks/useRegions'; @@ -671,7 +670,7 @@ describe('BuildQuote View', () => { mockUseBalanceValues = { ...mockUseBalanceInitialValue, balance: '5', - balanceMinimalUnit: (5*Math.pow(10, mockUseRampSDKValues.selectedAsset?.decimals || 18)).toString(10), + balanceMinimalUnit: (5 * Math.pow(10, mockUseRampSDKValues.selectedAsset?.decimals || 18)).toString(10), }; render(BuildQuote); @@ -690,7 +689,7 @@ describe('BuildQuote View', () => { mockUseBalanceValues = { ...mockUseBalanceInitialValue, balance: '1', - balanceMinimalUnit: (1*Math.pow(10, mockUseRampSDKValues.selectedAsset?.decimals || 18)).toString(10), + balanceMinimalUnit: (1 * Math.pow(10, mockUseRampSDKValues.selectedAsset?.decimals || 18)).toString(10), }; const symbol = mockUseRampSDKValues.selectedAsset?.symbol; @@ -720,7 +719,7 @@ describe('BuildQuote View', () => { mockUseBalanceValues = { balance: '1', - balanceMinimalUnit: (1*Math.pow(10, mockUseRampSDKValues.selectedAsset?.decimals || 18)).toString(10), + balanceMinimalUnit: (1 * Math.pow(10, mockUseRampSDKValues.selectedAsset?.decimals || 18)).toString(10), balanceFiat: '$1.00', }; mockUseGasPriceEstimationValue = { @@ -748,7 +747,7 @@ describe('BuildQuote View', () => { }; mockUseBalanceValues = { balance: '1', - balanceMinimalUnit: (1*Math.pow(10, mockUseRampSDKValues.selectedAsset?.decimals || 18)).toString(10), + balanceMinimalUnit: (1 * Math.pow(10, mockUseRampSDKValues.selectedAsset?.decimals || 18)).toString(10), balanceFiat: '$1.00', }; mockUseGasPriceEstimationValue = { diff --git a/app/util/number/index.js b/app/util/number/index.js index 8583df743246..b1422efd5927 100644 --- a/app/util/number/index.js +++ b/app/util/number/index.js @@ -154,12 +154,12 @@ export function fromTokenMinimalUnit( * @param {number} decimals - Token decimals to convert * @returns {string} - String containing the new number */ -export function fromTokenMinimalUnitString(minimalInput, decimals=0) { +export function fromTokenMinimalUnitString(minimalInput, decimals = 0) { if (typeof minimalInput !== 'string') { throw new TypeError('minimalInput must be a string'); } - console.warn('HARP', { minimalInput, decimals, }) + console.warn('HARP', { minimalInput, decimals, }); const tokenFormat = ethersUtils.formatUnits(minimalInput, decimals); const isInteger = Boolean(regex.integer.exec(tokenFormat)); @@ -177,7 +177,7 @@ export function fromTokenMinimalUnitString(minimalInput, decimals=0) { * @param {number} decimals - Unit to convert from, ether by default * @returns {string} - string format of new number */ -export function toTokenMinimalUnit(tokenValue, decimals=0) { +export function toTokenMinimalUnit(tokenValue, decimals = 0) { //const base = toBN(Math.pow(10, decimals).toString()); const valueBigNum = new BigNumber(tokenValue.toString(10), 10); if (valueBigNum.isNaN()) {