From b156fa4d67dfef8c259d1b78a3b9b15fb8a0bb36 Mon Sep 17 00:00:00 2001 From: tomasklim Date: Wed, 23 Oct 2024 18:08:59 +0200 Subject: [PATCH 1/5] chore: rename amountToSatoshi & networkAmountToSatoshi to x_smallestUnit --- .../wallet/coinmarket/coinmarketCommonActions.ts | 4 ++-- .../src/components/suite/FormattedCryptoAmount.tsx | 7 +++++-- .../TransactionReviewOutputElement.tsx | 4 ++-- .../form/common/useCoinmarketCurrencySwitcher.ts | 6 +++--- .../coinmarket/form/common/useCoinmarketFiatValues.tsx | 4 ++-- .../coinmarket/form/common/useCoinmarketFormActions.ts | 6 +++--- .../coinmarket/form/useCoinmarketExchangeForm.ts | 4 ++-- .../wallet/coinmarket/form/useCoinmarketSellForm.ts | 4 ++-- packages/suite/src/hooks/wallet/useSendForm.ts | 6 +++--- packages/suite/src/hooks/wallet/useSendFormImport.ts | 6 +++--- packages/suite/src/storage/migrations/index.ts | 9 +++++---- packages/suite/src/utils/suite/validation.ts | 10 +++++----- .../wallet/coinmarket/common/CoinmarketBalance.tsx | 4 ++-- .../CoinmarketFormInputAccountOption.tsx | 4 ++-- .../Options/BitcoinOptions/CoinControl/CoinControl.tsx | 4 ++-- .../src/views/wallet/send/Outputs/Amount/Amount.tsx | 4 ++-- .../src/views/wallet/send/Outputs/Amount/FiatInput.tsx | 4 ++-- .../src/formatters/prepareCryptoAmountFormatter.ts | 4 ++-- suite-common/formatters/src/utils/convert.ts | 4 ++-- .../wallet-core/src/send/sendFormEthereumThunks.ts | 5 +++-- .../wallet-core/src/send/sendFormRippleThunks.ts | 7 +++++-- .../wallet-core/src/send/sendFormSolanaThunks.ts | 4 ++-- suite-common/wallet-core/src/send/sendFormThunks.ts | 4 ++-- .../wallet-utils/src/__tests__/accountUtils.test.ts | 10 +++++----- suite-common/wallet-utils/src/accountUtils.ts | 6 +++--- suite-common/wallet-utils/src/cardanoUtils.ts | 8 ++++---- suite-common/wallet-utils/src/sendFormUtils.ts | 10 +++++----- 27 files changed, 80 insertions(+), 72 deletions(-) diff --git a/packages/suite/src/actions/wallet/coinmarket/coinmarketCommonActions.ts b/packages/suite/src/actions/wallet/coinmarket/coinmarketCommonActions.ts index e86e549a288..b50cfa972d1 100644 --- a/packages/suite/src/actions/wallet/coinmarket/coinmarketCommonActions.ts +++ b/packages/suite/src/actions/wallet/coinmarket/coinmarketCommonActions.ts @@ -2,7 +2,7 @@ import { isDesktop } from '@trezor/env-utils'; import { notificationsActions } from '@suite-common/toast-notifications'; import { PROTO } from '@trezor/connect'; import { - amountToSatoshi, + amountToSmallestUnit, formatAmount, getAccountDecimals, hasNetworkFeatures, @@ -204,7 +204,7 @@ export const convertDrafts = () => (dispatch: Dispatch, getState: GetState) => { if (draft) { const areSatsSelected = settings.bitcoinAmountUnit === PROTO.AmountUnit.SATOSHI; - const conversion = areSatsSelected ? amountToSatoshi : formatAmount; + const conversion = areSatsSelected ? amountToSmallestUnit : formatAmount; const decimals = getAccountDecimals(relatedAccount.symbol)!; if (draft.cryptoInput) { diff --git a/packages/suite/src/components/suite/FormattedCryptoAmount.tsx b/packages/suite/src/components/suite/FormattedCryptoAmount.tsx index 779953111af..3d245971feb 100644 --- a/packages/suite/src/components/suite/FormattedCryptoAmount.tsx +++ b/packages/suite/src/components/suite/FormattedCryptoAmount.tsx @@ -8,7 +8,7 @@ import { SignValue } from '@suite-common/suite-types'; import { formatCoinBalance, localizeNumber, - networkAmountToSatoshi, + networkAmountToSmallestUnit, } from '@suite-common/wallet-utils'; import { isSignValuePositive } from '@suite-common/formatters'; import { selectLanguage } from 'src/reducers/suite/suiteReducer'; @@ -68,7 +68,10 @@ export const FormattedCryptoAmount = ({ // convert to satoshis if needed if (isSatoshis) { - formattedValue = networkAmountToSatoshi(String(value), lowerCaseSymbol as NetworkSymbol); + formattedValue = networkAmountToSmallestUnit( + String(value), + lowerCaseSymbol as NetworkSymbol, + ); formattedSymbol = isTestnet ? `sat ${symbol?.toUpperCase()}` : 'sat'; } diff --git a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputElement.tsx b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputElement.tsx index 81738a99a78..2f530682f66 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputElement.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputElement.tsx @@ -6,7 +6,7 @@ import { FiatValue, FormattedCryptoAmount, Translation } from 'src/components/su import { Account } from 'src/types/wallet'; import { NetworkSymbol } from '@suite-common/wallet-config'; import { TokenInfo } from '@trezor/connect'; -import { amountToSatoshi } from '@suite-common/wallet-utils'; +import { amountToSmallestUnit } from '@suite-common/wallet-utils'; import { TransactionReviewStepIndicatorProps } from './TransactionReviewStepIndicator'; import { zIndices } from '@trezor/theme'; import { DeviceDisplay } from '../../../../DeviceDisplay/DeviceDisplay'; @@ -245,7 +245,7 @@ export const TransactionReviewOutputElement = forwardRef< - {amountToSatoshi(line.value, token.decimals)} + {amountToSmallestUnit(line.value, token.decimals)} )} diff --git a/packages/suite/src/hooks/wallet/coinmarket/form/common/useCoinmarketCurrencySwitcher.ts b/packages/suite/src/hooks/wallet/coinmarket/form/common/useCoinmarketCurrencySwitcher.ts index 3e372d75fb3..b2ea943ccbf 100644 --- a/packages/suite/src/hooks/wallet/coinmarket/form/common/useCoinmarketCurrencySwitcher.ts +++ b/packages/suite/src/hooks/wallet/coinmarket/form/common/useCoinmarketCurrencySwitcher.ts @@ -1,6 +1,6 @@ import { Network } from '@suite-common/wallet-config'; import { Account } from '@suite-common/wallet-types'; -import { amountToSatoshi, formatAmount } from '@suite-common/wallet-utils'; +import { amountToSmallestUnit, formatAmount } from '@suite-common/wallet-utils'; import { useDidUpdate } from '@trezor/react-utils'; import { UseFormReturn, useWatch } from 'react-hook-form'; import { @@ -56,7 +56,7 @@ export const useCoinmarketCurrencySwitcher = ( if (!amountInCrypto) { const amount = shouldSendInSats - ? amountToSatoshi(quoteCryptoAmount ?? '', networkDecimals) + ? amountToSmallestUnit(quoteCryptoAmount ?? '', networkDecimals) : quoteCryptoAmount; setValue(inputNames.cryptoInput, amount === '-1' ? '' : amount); @@ -73,7 +73,7 @@ export const useCoinmarketCurrencySwitcher = ( }; useDidUpdate(() => { - const conversion = shouldSendInSats ? amountToSatoshi : formatAmount; + const conversion = shouldSendInSats ? amountToSmallestUnit : formatAmount; if (!cryptoInputValue) { return; diff --git a/packages/suite/src/hooks/wallet/coinmarket/form/common/useCoinmarketFiatValues.tsx b/packages/suite/src/hooks/wallet/coinmarket/form/common/useCoinmarketFiatValues.tsx index a2b309efd86..61df2df2dbd 100644 --- a/packages/suite/src/hooks/wallet/coinmarket/form/common/useCoinmarketFiatValues.tsx +++ b/packages/suite/src/hooks/wallet/coinmarket/form/common/useCoinmarketFiatValues.tsx @@ -1,7 +1,7 @@ import { networks, NetworkSymbol } from '@suite-common/wallet-config'; import { selectFiatRatesByFiatRateKey, updateFiatRatesThunk } from '@suite-common/wallet-core'; import { FiatRatesResult, Rate, Timestamp, TokenAddress } from '@suite-common/wallet-types'; -import { amountToSatoshi, getFiatRateKey, toFiatCurrency } from '@suite-common/wallet-utils'; +import { amountToSmallestUnit, getFiatRateKey, toFiatCurrency } from '@suite-common/wallet-utils'; import { CryptoId, FiatCurrencyCode } from 'invity-api'; import { useCallback, useEffect } from 'react'; import { useDispatch, useSelector } from 'src/hooks/suite'; @@ -90,7 +90,7 @@ export const useCoinmarketFiatValues = ({ const decimals = getNetworkDecimals(network?.decimals); const formattedBalance = shouldSendInSats - ? amountToSatoshi(accountBalance, decimals) + ? amountToSmallestUnit(accountBalance, decimals) : accountBalance; const fiatValue = toFiatCurrency(accountBalance, fiatRate?.rate, 2); diff --git a/packages/suite/src/hooks/wallet/coinmarket/form/common/useCoinmarketFormActions.ts b/packages/suite/src/hooks/wallet/coinmarket/form/common/useCoinmarketFormActions.ts index 501b65f1cb4..fac58d6bb5f 100644 --- a/packages/suite/src/hooks/wallet/coinmarket/form/common/useCoinmarketFormActions.ts +++ b/packages/suite/src/hooks/wallet/coinmarket/form/common/useCoinmarketFormActions.ts @@ -1,7 +1,7 @@ import { isChanged } from '@suite-common/suite-utils'; import { selectAccounts, selectDevice } from '@suite-common/wallet-core'; import { - amountToSatoshi, + amountToSmallestUnit, formatAmount, fromFiatCurrency, isEthereumAccountSymbol, @@ -132,7 +132,7 @@ export const useCoinmarketFormActions = { const protocolAmount = protocol.sendForm.amount.toString(); const formattedAmount = shouldSendInSats - ? amountToSatoshi(protocolAmount, state.network.decimals) + ? amountToSmallestUnit(protocolAmount, state.network.decimals) : protocolAmount; sendFormUtils.setAmount(outputIndex, formattedAmount); @@ -356,7 +356,7 @@ export const useSendForm = (props: UseSendFormProps): SendContextValues => { useDidUpdate(() => { const { outputs } = getValues(); - const conversionToUse = shouldSendInSats ? amountToSatoshi : formatAmount; + const conversionToUse = shouldSendInSats ? amountToSmallestUnit : formatAmount; outputs.forEach((output, index) => { if (!output.amount) { diff --git a/packages/suite/src/hooks/wallet/useSendFormImport.ts b/packages/suite/src/hooks/wallet/useSendFormImport.ts index 8d16b838008..2a4e07523da 100644 --- a/packages/suite/src/hooks/wallet/useSendFormImport.ts +++ b/packages/suite/src/hooks/wallet/useSendFormImport.ts @@ -6,7 +6,7 @@ import { useBitcoinAmountUnit } from 'src/hooks/wallet/useBitcoinAmountUnit'; import { DEFAULT_PAYMENT } from '@suite-common/wallet-constants'; import { FiatCurrencyCode, fiatCurrencies } from '@suite-common/suite-config'; import { - amountToSatoshi, + amountToSmallestUnit, formatAmount, fromFiatCurrency, getFiatRateKey, @@ -97,7 +97,7 @@ export const useSendFormImport = ({ const cryptoAmount = item.amount || ''; if (shouldSendInSats) { // try to convert to satoshis - output.amount = amountToSatoshi(cryptoAmount, network.decimals); + output.amount = amountToSmallestUnit(cryptoAmount, network.decimals); } else { output.amount = cryptoAmount; } @@ -126,7 +126,7 @@ export const useSendFormImport = ({ const cryptoValue = fromFiatCurrency(output.fiat, network.decimals, itemRate); const cryptoAmount = cryptoValue && shouldSendInSats - ? amountToSatoshi(cryptoValue, network.decimals) + ? amountToSmallestUnit(cryptoValue, network.decimals) : cryptoValue ?? ''; output.amount = cryptoAmount; diff --git a/packages/suite/src/storage/migrations/index.ts b/packages/suite/src/storage/migrations/index.ts index a6ec2dfa963..1b9ce53d671 100644 --- a/packages/suite/src/storage/migrations/index.ts +++ b/packages/suite/src/storage/migrations/index.ts @@ -10,8 +10,8 @@ import type { OnUpgradeFunc } from '@trezor/suite-storage'; import type { DBWalletAccountTransaction, SuiteDBSchema } from '../definitions'; import { formatNetworkAmount, - networkAmountToSatoshi, - amountToSatoshi, + networkAmountToSmallestUnit, + amountToSmallestUnit, } from '@suite-common/wallet-utils'; import { updateAll } from './utils'; import { DeviceModelInternal, FirmwareType } from '@trezor/connect'; @@ -428,7 +428,8 @@ export const migrate: OnUpgradeFunc = async ( transaction, 'txs', ({ order, tx: origTx }) => { - const unformat = (amount: string) => networkAmountToSatoshi(amount, origTx.symbol); + const unformat = (amount: string) => + networkAmountToSmallestUnit(amount, origTx.symbol); const unformatIfDefined = (amount: string | undefined) => amount ? unformat(amount) : amount; @@ -439,7 +440,7 @@ export const migrate: OnUpgradeFunc = async ( totalSpent: unformat(origTx.totalSpent), tokens: origTx.tokens.map(tok => ({ ...tok, - amount: amountToSatoshi(tok.amount, tok.decimals), + amount: amountToSmallestUnit(tok.amount, tok.decimals), })), targets: origTx.targets.map(target => ({ ...target, diff --git a/packages/suite/src/utils/suite/validation.ts b/packages/suite/src/utils/suite/validation.ts index 1fddfeab2d5..f44859140d1 100644 --- a/packages/suite/src/utils/suite/validation.ts +++ b/packages/suite/src/utils/suite/validation.ts @@ -7,7 +7,7 @@ import { formatNetworkAmount, isDecimalsValid, isInteger, - networkAmountToSatoshi, + networkAmountToSmallestUnit, } from '@suite-common/wallet-utils'; import { BigNumber } from '@trezor/utils/src/bigNumber'; import { TranslationFunction } from 'src/hooks/suite/useTranslation'; @@ -59,7 +59,7 @@ export const validateLimits = let minCrypto = 0; if (amountLimits.minCrypto) { minCrypto = areSatsUsed - ? Number(networkAmountToSatoshi(amountLimits.minCrypto.toString(), symbol)) + ? Number(networkAmountToSmallestUnit(amountLimits.minCrypto.toString(), symbol)) : amountLimits.minCrypto; } if (amountLimits.minCrypto && Number(value) < minCrypto) { @@ -74,7 +74,7 @@ export const validateLimits = let maxCrypto = 0; if (amountLimits.maxCrypto) { maxCrypto = areSatsUsed - ? Number(networkAmountToSatoshi(amountLimits.maxCrypto.toString(), symbol)) + ? Number(networkAmountToSmallestUnit(amountLimits.maxCrypto.toString(), symbol)) : amountLimits.maxCrypto; } if (amountLimits.maxCrypto && Number(value) > maxCrypto) { @@ -106,7 +106,7 @@ export const validateLimitsBigNum = if (amountLimits.minCrypto) { minCrypto = areSatsUsed ? new BigNumber( - networkAmountToSatoshi(amountLimits.minCrypto.toString(), symbol), + networkAmountToSmallestUnit(amountLimits.minCrypto.toString(), symbol), ) : new BigNumber(amountLimits.minCrypto); } @@ -123,7 +123,7 @@ export const validateLimitsBigNum = if (amountLimits.maxCrypto) { maxCrypto = areSatsUsed ? new BigNumber( - networkAmountToSatoshi(amountLimits.maxCrypto.toString(), symbol), + networkAmountToSmallestUnit(amountLimits.maxCrypto.toString(), symbol), ) : new BigNumber(amountLimits.maxCrypto); } diff --git a/packages/suite/src/views/wallet/coinmarket/common/CoinmarketBalance.tsx b/packages/suite/src/views/wallet/coinmarket/common/CoinmarketBalance.tsx index b19dfea91ef..c71ac85e951 100644 --- a/packages/suite/src/views/wallet/coinmarket/common/CoinmarketBalance.tsx +++ b/packages/suite/src/views/wallet/coinmarket/common/CoinmarketBalance.tsx @@ -1,6 +1,6 @@ import { networks, NetworkSymbol } from '@suite-common/wallet-config'; import { TokenAddress } from '@suite-common/wallet-types'; -import { amountToSatoshi } from '@suite-common/wallet-utils'; +import { amountToSmallestUnit } from '@suite-common/wallet-utils'; import { typography } from '@trezor/theme'; import { FiatValue, HiddenPlaceholder, Translation } from 'src/components/suite'; import { useFiatFromCryptoValue } from 'src/hooks/suite/useFiatFromCryptoValue'; @@ -39,7 +39,7 @@ export const CoinmarketBalance = ({ const stringBalance = !isNaN(Number(balance)) ? balance : '0'; const formattedBalance = stringBalance && shouldSendInSats - ? amountToSatoshi(stringBalance, networkDecimals) + ? amountToSmallestUnit(stringBalance, networkDecimals) : stringBalance; const { fiatAmount } = useFiatFromCryptoValue({ diff --git a/packages/suite/src/views/wallet/coinmarket/common/CoinmarketForm/CoinmarketFormInput/CoinmarketFormInputAccountOption.tsx b/packages/suite/src/views/wallet/coinmarket/common/CoinmarketForm/CoinmarketFormInput/CoinmarketFormInputAccountOption.tsx index 11a7de53083..09d4106715c 100644 --- a/packages/suite/src/views/wallet/coinmarket/common/CoinmarketForm/CoinmarketFormInput/CoinmarketFormInputAccountOption.tsx +++ b/packages/suite/src/views/wallet/coinmarket/common/CoinmarketForm/CoinmarketFormInput/CoinmarketFormInputAccountOption.tsx @@ -1,4 +1,4 @@ -import { amountToSatoshi } from '@suite-common/wallet-utils'; +import { amountToSmallestUnit } from '@suite-common/wallet-utils'; import { useElevation } from '@trezor/components'; import { HiddenPlaceholder } from 'src/components/suite'; import { useBitcoinAmountUnit } from 'src/hooks/wallet/useBitcoinAmountUnit'; @@ -40,7 +40,7 @@ export const CoinmarketFormInputAccountOption = ({ const balanceLabel = coinmarketGetAccountLabel(option.label, shouldSendInSats); const balance = shouldSendInSats - ? amountToSatoshi(option.balance, network.decimals) + ? amountToSmallestUnit(option.balance, network.decimals) : option.balance; const accountType = optionGroups.find(group => group.options.find( diff --git a/packages/suite/src/views/wallet/send/Options/BitcoinOptions/CoinControl/CoinControl.tsx b/packages/suite/src/views/wallet/send/Options/BitcoinOptions/CoinControl/CoinControl.tsx index bf61ce180b1..315ae0dae42 100644 --- a/packages/suite/src/views/wallet/send/Options/BitcoinOptions/CoinControl/CoinControl.tsx +++ b/packages/suite/src/views/wallet/send/Options/BitcoinOptions/CoinControl/CoinControl.tsx @@ -5,7 +5,7 @@ import { typography } from '@trezor/theme'; import { COMPOSE_ERROR_TYPES } from '@suite-common/wallet-constants'; import { fetchAllTransactionsForAccountThunk } from '@suite-common/wallet-core'; import { getTxsPerPage } from '@suite-common/suite-utils'; -import { amountToSatoshi, formatNetworkAmount } from '@suite-common/wallet-utils'; +import { amountToSmallestUnit, formatNetworkAmount } from '@suite-common/wallet-utils'; import { FormattedCryptoAmount, Translation } from 'src/components/suite'; import { useDispatch, useSelector } from 'src/hooks/suite'; import { Pagination } from 'src/components/wallet'; @@ -115,7 +115,7 @@ export const CoinControl = ({ close }: CoinControlProps) => { ); const totalOutputsInSats = shouldSendInSats ? totalOutputs - : Number(amountToSatoshi(totalOutputs.toString(), network.decimals)); + : Number(amountToSmallestUnit(totalOutputs.toString(), network.decimals)); const missingToInput = totalOutputsInSats - totalInputs; const isMissingToAmount = missingToInput > 0; // relevant when the amount field is not validated, e.g. there is an error in the address const missingAmountTooBig = missingToInput > Number.MAX_SAFE_INTEGER; diff --git a/packages/suite/src/views/wallet/send/Outputs/Amount/Amount.tsx b/packages/suite/src/views/wallet/send/Outputs/Amount/Amount.tsx index 568e4b7413f..dad5e078732 100644 --- a/packages/suite/src/views/wallet/send/Outputs/Amount/Amount.tsx +++ b/packages/suite/src/views/wallet/send/Outputs/Amount/Amount.tsx @@ -10,7 +10,7 @@ import { formInputsMaxLength } from '@suite-common/validators'; import { selectFiatRatesByFiatRateKey } from '@suite-common/wallet-core'; import { Output, TokenAddress } from '@suite-common/wallet-types'; import { - amountToSatoshi, + amountToSmallestUnit, formatNetworkAmount, hasNetworkFeatures, isLowAnonymityWarning, @@ -199,7 +199,7 @@ export const Amount = ({ output, outputId }: AmountProps) => { if (dust && amountBig.lt(dust)) { if (shouldSendInSats) { - dust = amountToSatoshi(dust, decimals); + dust = amountToSmallestUnit(dust, decimals); } return translationString('AMOUNT_IS_BELOW_DUST', { diff --git a/packages/suite/src/views/wallet/send/Outputs/Amount/FiatInput.tsx b/packages/suite/src/views/wallet/send/Outputs/Amount/FiatInput.tsx index b4c81fefde3..2e56e3ac4c3 100644 --- a/packages/suite/src/views/wallet/send/Outputs/Amount/FiatInput.tsx +++ b/packages/suite/src/views/wallet/send/Outputs/Amount/FiatInput.tsx @@ -17,7 +17,7 @@ import { getInputState, findToken, isLowAnonymityWarning, - amountToSatoshi, + amountToSmallestUnit, formatAmount, buildCurrencyOptions, getFiatRateKey, @@ -141,7 +141,7 @@ export const FiatInput = ({ output, outputId, labelHoverRight, labelRight }: Fia const amount = fiatRate?.rate ? fromFiatCurrency(value, decimals, fiatRate.rate) : null; const formattedAmount = shouldSendInSats - ? amountToSatoshi(amount || '0', decimals) + ? amountToSmallestUnit(amount || '0', decimals) : amount; if (formattedAmount) { diff --git a/suite-common/formatters/src/formatters/prepareCryptoAmountFormatter.ts b/suite-common/formatters/src/formatters/prepareCryptoAmountFormatter.ts index 3f3839a174d..82eb43f1afc 100644 --- a/suite-common/formatters/src/formatters/prepareCryptoAmountFormatter.ts +++ b/suite-common/formatters/src/formatters/prepareCryptoAmountFormatter.ts @@ -7,7 +7,7 @@ import { networks, } from '@suite-common/wallet-config'; import { - amountToSatoshi, + amountToSmallestUnit, formatAmount, redactNumericalSubstring, } from '@suite-common/wallet-utils'; @@ -54,7 +54,7 @@ const convertToUnit = ( : undefined; if (isBalance && areAmountUnitsSupported && bitcoinAmountUnit === PROTO.AmountUnit.SATOSHI) { - return amountToSatoshi(value, decimals); + return amountToSmallestUnit(value, decimals); } // if it's not balance and sats units are disabled, values other than balances are in sats so we need to convert it to BTC diff --git a/suite-common/formatters/src/utils/convert.ts b/suite-common/formatters/src/utils/convert.ts index 0321cd8591c..d20cca3f7f7 100644 --- a/suite-common/formatters/src/utils/convert.ts +++ b/suite-common/formatters/src/utils/convert.ts @@ -1,6 +1,6 @@ import { networks, NetworkSymbol } from '@suite-common/wallet-config'; import { - amountToSatoshi, + amountToSmallestUnit, formatNetworkAmount, fromFiatCurrency, toFiatCurrency, @@ -46,5 +46,5 @@ export const convertFiatToCryptoAmount = ({ return cryptoAmount; } - return amountToSatoshi(new BigNumber(cryptoAmount), decimals); + return amountToSmallestUnit(new BigNumber(cryptoAmount), decimals); }; diff --git a/suite-common/wallet-core/src/send/sendFormEthereumThunks.ts b/suite-common/wallet-core/src/send/sendFormEthereumThunks.ts index a4b141609ff..6a394ede829 100644 --- a/suite-common/wallet-core/src/send/sendFormEthereumThunks.ts +++ b/suite-common/wallet-core/src/send/sendFormEthereumThunks.ts @@ -10,7 +10,7 @@ import { getEthereumEstimateFeeParams, prepareEthereumTransaction, getExternalComposeOutput, - amountToSatoshi, + amountToSmallestUnit, formatAmount, isPending, getAccountIdentity, @@ -50,7 +50,7 @@ const calculate = ( let amount: string; let max: string | undefined; const availableTokenBalance = token - ? amountToSatoshi(token.balance!, token.decimals) + ? amountToSmallestUnit(token.balance!, token.decimals) : undefined; if (output.type === 'send-max' || output.type === 'send-max-noaddress') { max = availableTokenBalance || calculateMax(availableBalance, feeInSatoshi); @@ -122,6 +122,7 @@ export const composeEthereumTransactionFeeLevelsThunk = createThunk< async ({ formState, composeContext }, { dispatch, rejectWithValue }) => { const { account, network, feeInfo } = composeContext; const composedOutput = getExternalComposeOutput(formState, account, network); + if (!composedOutput) return rejectWithValue({ error: 'fee-levels-compose-failed', diff --git a/suite-common/wallet-core/src/send/sendFormRippleThunks.ts b/suite-common/wallet-core/src/send/sendFormRippleThunks.ts index cff823fbf16..30fd1fc02d8 100644 --- a/suite-common/wallet-core/src/send/sendFormRippleThunks.ts +++ b/suite-common/wallet-core/src/send/sendFormRippleThunks.ts @@ -4,7 +4,7 @@ import { calculateTotal, calculateMax, getExternalComposeOutput, - networkAmountToSatoshi, + networkAmountToSmallestUnit, formatNetworkAmount, } from '@suite-common/wallet-utils'; import { XRP_FLAG } from '@suite-common/wallet-constants'; @@ -213,7 +213,10 @@ export const signRippleSendFormTransactionThunk = createThunk< const payment: RipplePayment = { destination: formState.outputs[0].address, - amount: networkAmountToSatoshi(formState.outputs[0].amount, selectedAccount.symbol), + amount: networkAmountToSmallestUnit( + formState.outputs[0].amount, + selectedAccount.symbol, + ), }; if (formState.rippleDestinationTag) { diff --git a/suite-common/wallet-core/src/send/sendFormSolanaThunks.ts b/suite-common/wallet-core/src/send/sendFormSolanaThunks.ts index 9b72dc6f1ca..ed186754de8 100644 --- a/suite-common/wallet-core/src/send/sendFormSolanaThunks.ts +++ b/suite-common/wallet-core/src/send/sendFormSolanaThunks.ts @@ -10,7 +10,7 @@ import { } from '@suite-common/wallet-types'; import { createThunk } from '@suite-common/redux-utils'; import { - amountToSatoshi, + amountToSmallestUnit, calculateMax, calculateTotal, formatAmount, @@ -45,7 +45,7 @@ const calculate = ( let amount: string; let max: string | undefined; const availableTokenBalance = token - ? amountToSatoshi(token.balance!, token.decimals) + ? amountToSmallestUnit(token.balance!, token.decimals) : undefined; if (output.type === 'send-max' || output.type === 'send-max-noaddress') { max = availableTokenBalance || calculateMax(availableBalance, feeInLamports); diff --git a/suite-common/wallet-core/src/send/sendFormThunks.ts b/suite-common/wallet-core/src/send/sendFormThunks.ts index 0922ecb0ad9..34dd49adf4a 100644 --- a/suite-common/wallet-core/src/send/sendFormThunks.ts +++ b/suite-common/wallet-core/src/send/sendFormThunks.ts @@ -19,7 +19,7 @@ import { notificationsActions } from '@suite-common/toast-notifications'; import { getNetwork, NetworkSymbol } from '@suite-common/wallet-config'; import { hasNetworkFeatures, - amountToSatoshi, + amountToSmallestUnit, formatAmount, getAccountDecimals, getAreSatoshisUsed, @@ -108,7 +108,7 @@ export const convertSendFormDraftsBtcAmountUnitsThunk = createThunk( const areSatsSupported = hasNetworkFeatures(relatedAccount, 'amount-unit'); const amountFormatter = - areSatsAmountUnit && areSatsSupported ? amountToSatoshi : formatAmount; + areSatsAmountUnit && areSatsSupported ? amountToSmallestUnit : formatAmount; const updatedDraft = cloneObject(draft); const amountDecimals = getAccountDecimals(relatedAccount.symbol)!; diff --git a/suite-common/wallet-utils/src/__tests__/accountUtils.test.ts b/suite-common/wallet-utils/src/__tests__/accountUtils.test.ts index 70d8ff2b23a..de932a572e1 100644 --- a/suite-common/wallet-utils/src/__tests__/accountUtils.test.ts +++ b/suite-common/wallet-utils/src/__tests__/accountUtils.test.ts @@ -17,7 +17,7 @@ import { getNetworkAccountFeatures, hasNetworkFeatures, isTestnet, - networkAmountToSatoshi, + networkAmountToSmallestUnit, parseBIP44Path, sortByCoin, getUtxoOutpoint, @@ -114,10 +114,10 @@ describe('account utils', () => { }); it('format amount to satoshi', () => { - expect(networkAmountToSatoshi('0.00000001', 'btc')).toEqual('1'); - expect(networkAmountToSatoshi('0.000001', 'xrp')).toEqual('1'); - expect(networkAmountToSatoshi('0.000000000000000001', 'eth')).toEqual('1'); - expect(networkAmountToSatoshi('aaa', 'eth')).toEqual('-1'); + expect(networkAmountToSmallestUnit('0.00000001', 'btc')).toEqual('1'); + expect(networkAmountToSmallestUnit('0.000001', 'xrp')).toEqual('1'); + expect(networkAmountToSmallestUnit('0.000000000000000001', 'eth')).toEqual('1'); + expect(networkAmountToSmallestUnit('aaa', 'eth')).toEqual('-1'); }); it('findAccountDevice', () => { diff --git a/suite-common/wallet-utils/src/accountUtils.ts b/suite-common/wallet-utils/src/accountUtils.ts index b4bff6bd27f..816076a8fc9 100644 --- a/suite-common/wallet-utils/src/accountUtils.ts +++ b/suite-common/wallet-utils/src/accountUtils.ts @@ -362,7 +362,7 @@ export const formatAmount = (amount: BigNumberValue, decimals: number) => { } }; -export const amountToSatoshi = (amount: BigNumberValue, decimals: number) => { +export const amountToSmallestUnit = (amount: BigNumberValue, decimals: number) => { try { const bAmount = new BigNumber(amount); if (bAmount.isNaN()) { @@ -390,14 +390,14 @@ export const satoshiAmountToBtc = (amount: BigNumberValue) => { } }; -export const networkAmountToSatoshi = (amount: string | null, symbol: NetworkSymbol) => { +export const networkAmountToSmallestUnit = (amount: string | null, symbol: NetworkSymbol) => { if (!amount) return '0'; const decimals = getAccountDecimals(symbol); if (!decimals) return amount; - return amountToSatoshi(amount, decimals); + return amountToSmallestUnit(amount, decimals); }; export const formatNetworkAmount = ( diff --git a/suite-common/wallet-utils/src/cardanoUtils.ts b/suite-common/wallet-utils/src/cardanoUtils.ts index 1bc665441fb..c7ca64c0888 100644 --- a/suite-common/wallet-utils/src/cardanoUtils.ts +++ b/suite-common/wallet-utils/src/cardanoUtils.ts @@ -11,10 +11,10 @@ import { CARDANO, CardanoCertificate, CardanoOutput, PROTO } from '@trezor/conne import { AccountType } from '@suite-common/wallet-config'; import { - amountToSatoshi, + amountToSmallestUnit, formatAmount, formatNetworkAmount, - networkAmountToSatoshi, + networkAmountToSmallestUnit, } from './accountUtils'; export const getDerivationType = (accountType: AccountType) => { @@ -67,7 +67,7 @@ export const transformUserOutputs = ( outputs.map((output, i) => { const setMax = i === maxOutputIndex; const amount = - output.amount === '' ? undefined : networkAmountToSatoshi(output.amount, symbol); + output.amount === '' ? undefined : networkAmountToSmallestUnit(output.amount, symbol); const tokenDecimals = accountTokens?.find(t => t.contract === output.token)?.decimals ?? 0; return { @@ -78,7 +78,7 @@ export const transformUserOutputs = ( { unit: output.token, quantity: output.amount - ? amountToSatoshi(output.amount, tokenDecimals) + ? amountToSmallestUnit(output.amount, tokenDecimals) : '0', }, ] diff --git a/suite-common/wallet-utils/src/sendFormUtils.ts b/suite-common/wallet-utils/src/sendFormUtils.ts index d40ae0860fa..6424d75f01b 100644 --- a/suite-common/wallet-utils/src/sendFormUtils.ts +++ b/suite-common/wallet-utils/src/sendFormUtils.ts @@ -35,7 +35,7 @@ import type { SendFormDraftKey, } from '@suite-common/wallet-types'; -import { amountToSatoshi, getUtxoOutpoint, networkAmountToSatoshi } from './accountUtils'; +import { amountToSmallestUnit, getUtxoOutpoint, networkAmountToSmallestUnit } from './accountUtils'; import { sanitizeHex } from './ethUtils'; export const calculateTotal = (amount: string, fee: string): string => { @@ -99,7 +99,7 @@ const getSerializedErc20Transfer = (token: TokenInfo, to: string, amount: string // 32 bytes address parameter, remove '0x' prefix const erc20recipient = padLeft(to, 64).substring(2); // convert amount to satoshi - const tokenAmount = amountToSatoshi(amount, token.decimals); + const tokenAmount = amountToSmallestUnit(amount, token.decimals); // 32 bytes amount paramter, remove '0x' prefix const erc20amount = padLeft(numberToHex(tokenAmount), 64).substring(2); @@ -286,7 +286,7 @@ export const getBitcoinComposeOutputs = ( } else if (output.amount) { const amount = isSatoshis ? output.amount - : networkAmountToSatoshi(output.amount, symbol); + : networkAmountToSmallestUnit(output.amount, symbol); if (address) { result.push({ @@ -338,7 +338,7 @@ export const getExternalComposeOutput = ( const tokenInfo = findToken(account.tokens, token); const decimals = tokenInfo ? tokenInfo.decimals : network.decimals; - const amountInSatoshi = amountToSatoshi(amount, decimals); + const formattedAmount = amountToSmallestUnit(amount, decimals); let output: ExternalOutput; if (isMaxActive) { @@ -361,7 +361,7 @@ export const getExternalComposeOutput = ( } else { output = { type: 'payment-noaddress', - amount: amountInSatoshi, + amount: formattedAmount, }; } From 4794b7e3318d7c56e20b3b04f8e6de4d9274b0a4 Mon Sep 17 00:00:00 2001 From: Pavlo Syrotyna Date: Wed, 23 Oct 2024 13:16:47 +0300 Subject: [PATCH 2/5] fix(staking): zero amounts when bumping fee of unstake tx --- .../components/suite/UnstakingTxAmount.tsx | 5 ++--- .../src/utils/suite/__fixtures__/stake.ts | 13 ----------- .../src/utils/suite/__tests__/stake.test.ts | 11 ---------- packages/suite/src/utils/suite/stake.ts | 12 +--------- suite-common/suite-utils/package.json | 3 ++- .../suite-utils/src/__fixtures__/stake.ts | 22 +++++++++++++++++++ .../suite-utils/src/__tests__/stake.test.ts | 11 ++++++++++ suite-common/suite-utils/src/stake.ts | 16 ++++++++++++++ .../src/send/sendFormEthereumThunks.ts | 15 +++++++++++-- .../src/__tests__/sendFormUtils.test.ts | 13 +++++++++++ .../wallet-utils/src/sendFormUtils.ts | 3 ++- yarn.lock | 1 + 12 files changed, 83 insertions(+), 42 deletions(-) create mode 100644 suite-common/suite-utils/src/__fixtures__/stake.ts create mode 100644 suite-common/suite-utils/src/__tests__/stake.test.ts diff --git a/packages/suite/src/components/suite/UnstakingTxAmount.tsx b/packages/suite/src/components/suite/UnstakingTxAmount.tsx index 6012b597d63..1098da59c23 100644 --- a/packages/suite/src/components/suite/UnstakingTxAmount.tsx +++ b/packages/suite/src/components/suite/UnstakingTxAmount.tsx @@ -1,8 +1,7 @@ import React from 'react'; -import { isUnstakeTx } from '@suite-common/suite-utils'; +import { getUnstakeAmountByEthereumDataHex, isUnstakeTx } from '@suite-common/suite-utils'; import { WalletAccountTransaction } from '@suite-common/wallet-types'; import { formatNetworkAmount } from '@suite-common/wallet-utils'; -import { getUnstakingAmount } from 'src/utils/suite/stake'; import { FormattedCryptoAmount } from './FormattedCryptoAmount'; interface UnstakingTxAmountProps { @@ -15,7 +14,7 @@ export const UnstakingTxAmount = ({ transaction }: UnstakingTxAmountProps) => { if (!isUnstakeTx(txSignature)) return null; - const amount = getUnstakingAmount(ethereumSpecific?.data); + const amount = getUnstakeAmountByEthereumDataHex(ethereumSpecific?.data); if (!amount) return null; diff --git a/packages/suite/src/utils/suite/__fixtures__/stake.ts b/packages/suite/src/utils/suite/__fixtures__/stake.ts index c7057a54beb..3516bc99595 100644 --- a/packages/suite/src/utils/suite/__fixtures__/stake.ts +++ b/packages/suite/src/utils/suite/__fixtures__/stake.ts @@ -47,19 +47,6 @@ export const transformTxFixtures = [ }, ]; -export const getUnstakingAmountFixtures = [ - { - description: 'should correctly extract and convert the unstaking amount from ethereum data', - ethereumData: '76ec871c0000000000000000000000000000000000000000000000000000000000000001', // without 0x - expectedAmountWei: '1', // 0.000000000000000001 eth - }, - { - description: 'should correctly remove 0x prefix from ethereum data', - ethereumData: '0x76ec871c0000000000000000000000000000000000000000000000000000000000000001', // with 0x - expectedAmountWei: '1', // 0.000000000000000001 eth - }, -]; - export const stakeFixture = [ { description: 'should stake 0.1 eth, expect correct transaction object with correct values', diff --git a/packages/suite/src/utils/suite/__tests__/stake.test.ts b/packages/suite/src/utils/suite/__tests__/stake.test.ts index 5e7df7903b9..dc60baee034 100644 --- a/packages/suite/src/utils/suite/__tests__/stake.test.ts +++ b/packages/suite/src/utils/suite/__tests__/stake.test.ts @@ -23,11 +23,9 @@ import { getEthNetworkForWalletSdkFixture, getInstantStakeTypeFixture, getChangedInternalTxFixture, - getUnstakingAmountFixtures, simulateUnstakeFixture, } from '../__fixtures__/stake'; import { - getUnstakingAmount, transformTx, stake, unstake, @@ -65,15 +63,6 @@ describe('transformTx', () => { }); }); -describe('getUnstakingAmount', () => { - getUnstakingAmountFixtures.forEach(test => { - it(test.description, () => { - const result = getUnstakingAmount(test.ethereumData); - expect(result).toBe(test.expectedAmountWei); - }); - }); -}); - type Result = Unsuccessful | Success; type AccountInfoResult = Result<(AccountInfo | null)[]>; type EstimateFeeResult = Result; diff --git a/packages/suite/src/utils/suite/stake.ts b/packages/suite/src/utils/suite/stake.ts index 64b3f37304d..16bc6798c69 100644 --- a/packages/suite/src/utils/suite/stake.ts +++ b/packages/suite/src/utils/suite/stake.ts @@ -7,7 +7,7 @@ import { import { DEFAULT_PAYMENT } from '@suite-common/wallet-constants'; import { NetworkSymbol } from '@suite-common/wallet-config'; import { selectNetwork } from '@everstake/wallet-sdk/ethereum'; -import { fromWei, hexToNumberString, numberToHex, toWei } from 'web3-utils'; +import { fromWei, numberToHex, toWei } from 'web3-utils'; import { getEthereumEstimateFeeParams, isPending, sanitizeHex } from '@suite-common/wallet-utils'; import TrezorConnect, { EthereumTransaction, Success, InternalTransfer } from '@trezor/connect'; import { BigNumber } from '@trezor/utils/src/bigNumber'; @@ -563,16 +563,6 @@ export const getDaysToAddToPoolInitial = (validatorsQueue?: ValidatorsQueue) => return daysToWait <= 0 ? 1 : daysToWait; }; -export const getUnstakingAmount = (ethereumData: string | undefined): string | null => { - if (!ethereumData) return null; - - // Check if the first two characters are '0x' and remove them if they are - const data = ethereumData.startsWith('0x') ? ethereumData.slice(2) : ethereumData; - const dataBuffer = Buffer.from(data, 'hex'); - - return hexToNumberString(`0x${dataBuffer.subarray(4, 36).toString('hex')}`); -}; - export const getInstantStakeType = ( internalTransfer: InternalTransfer, address?: string, diff --git a/suite-common/suite-utils/package.json b/suite-common/suite-utils/package.json index f9a8e66b82c..264dffb53d8 100644 --- a/suite-common/suite-utils/package.json +++ b/suite-common/suite-utils/package.json @@ -20,6 +20,7 @@ "@suite-common/wallet-types": "workspace:*", "@trezor/connect": "workspace:*", "@trezor/urls": "workspace:*", - "date-fns": "^2.30.0" + "date-fns": "^2.30.0", + "web3-utils": "^4.3.1" } } diff --git a/suite-common/suite-utils/src/__fixtures__/stake.ts b/suite-common/suite-utils/src/__fixtures__/stake.ts new file mode 100644 index 00000000000..22a1c8b4257 --- /dev/null +++ b/suite-common/suite-utils/src/__fixtures__/stake.ts @@ -0,0 +1,22 @@ +export const getUnstakeAmountByEthereumDataHexFixtures = [ + { + description: 'should correctly extract and convert the unstaking amount from ethereum data', + ethereumData: '76ec871c0000000000000000000000000000000000000000000000000000000000000001', // without 0x + expectedAmountWei: '1', // 0.000000000000000001 eth + }, + { + description: 'should correctly remove 0x prefix from ethereum data', + ethereumData: '0x76ec871c0000000000000000000000000000000000000000000000000000000000000001', // with 0x + expectedAmountWei: '1', // 0.000000000000000001 eth + }, + { + description: 'should return null when the transaction is not an unstake transaction', + ethereumData: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', + expectedAmountWei: null, + }, + { + description: 'should return null for invalid or unsupported ethereum data', + ethereumData: '1234', + expectedAmountWei: null, + }, +]; diff --git a/suite-common/suite-utils/src/__tests__/stake.test.ts b/suite-common/suite-utils/src/__tests__/stake.test.ts new file mode 100644 index 00000000000..c590612a537 --- /dev/null +++ b/suite-common/suite-utils/src/__tests__/stake.test.ts @@ -0,0 +1,11 @@ +import { getUnstakeAmountByEthereumDataHexFixtures } from '../__fixtures__/stake'; +import { getUnstakeAmountByEthereumDataHex } from '../stake'; + +describe('getUnstakeAmountByEthereumDataHex', () => { + getUnstakeAmountByEthereumDataHexFixtures.forEach(f => { + it(f.description, () => { + const result = getUnstakeAmountByEthereumDataHex(f.ethereumData); + expect(result).toBe(f.expectedAmountWei); + }); + }); +}); diff --git a/suite-common/suite-utils/src/stake.ts b/suite-common/suite-utils/src/stake.ts index bf0c80b4fb8..6852ed7482b 100644 --- a/suite-common/suite-utils/src/stake.ts +++ b/suite-common/suite-utils/src/stake.ts @@ -1,3 +1,5 @@ +import { hexToNumberString } from 'web3-utils'; + import { StakeType } from '@suite-common/wallet-types'; // Define signature constants @@ -31,3 +33,17 @@ export const getTxStakeNameByDataHex = (dataHex: string | undefined): StakeType return isStakeTypeTx(signature) ? signatureToStakeNameMap[signature] : null; }; + +export const getUnstakeAmountByEthereumDataHex = (dataHex?: string) => { + if (!dataHex) return null; + + // Check if the first two characters are '0x' and remove them if they are + const data = dataHex.startsWith('0x') ? dataHex.slice(2) : dataHex; + + const signature = getSignatureByEthereumDataHex(data); + if (!isUnstakeTx(signature)) return null; + + const dataBuffer = Buffer.from(data, 'hex'); + + return hexToNumberString(`0x${dataBuffer.subarray(4, 36).toString('hex')}`); +}; diff --git a/suite-common/wallet-core/src/send/sendFormEthereumThunks.ts b/suite-common/wallet-core/src/send/sendFormEthereumThunks.ts index 6a394ede829..bb5144ffddb 100644 --- a/suite-common/wallet-core/src/send/sendFormEthereumThunks.ts +++ b/suite-common/wallet-core/src/send/sendFormEthereumThunks.ts @@ -24,7 +24,10 @@ import { AddressDisplayOptions, } from '@suite-common/wallet-types'; import { getNetwork } from '@suite-common/wallet-config'; -import { getTxStakeNameByDataHex } from '@suite-common/suite-utils'; +import { + getTxStakeNameByDataHex, + getUnstakeAmountByEthereumDataHex, +} from '@suite-common/suite-utils'; import { selectTransactions } from '../transactions/transactionsReducer'; import { @@ -121,7 +124,15 @@ export const composeEthereumTransactionFeeLevelsThunk = createThunk< `${SEND_MODULE_PREFIX}/composeEthereumTransactionFeeLevelsThunk`, async ({ formState, composeContext }, { dispatch, rejectWithValue }) => { const { account, network, feeInfo } = composeContext; - const composedOutput = getExternalComposeOutput(formState, account, network); + const { ethereumDataHex } = formState; + const unstakeAmount = getUnstakeAmountByEthereumDataHex(ethereumDataHex); + + const composedOutput = getExternalComposeOutput( + formState, + account, + network, + unstakeAmount || undefined, + ); if (!composedOutput) return rejectWithValue({ diff --git a/suite-common/wallet-utils/src/__tests__/sendFormUtils.test.ts b/suite-common/wallet-utils/src/__tests__/sendFormUtils.test.ts index 4a349bb328b..9950a92ee18 100644 --- a/suite-common/wallet-utils/src/__tests__/sendFormUtils.test.ts +++ b/suite-common/wallet-utils/src/__tests__/sendFormUtils.test.ts @@ -330,6 +330,19 @@ describe('sendForm utils', () => { output: { type: 'payment-noaddress', amount: '1000000' }, tokenInfo: undefined, }); + + expect( + getExternalComposeOutput( + { outputs: [{ ...OUTPUT, address: 'A', amount: '0', token: 'A' }] }, + EthAccount, + EthNetwork, + '1', // already formatted + ), + ).toEqual({ + decimals: 2, + output: { type: 'payment', address: 'A', amount: '1' }, + tokenInfo: EthAccount.tokens![0], + }); }); it('calculateEthFee', () => { diff --git a/suite-common/wallet-utils/src/sendFormUtils.ts b/suite-common/wallet-utils/src/sendFormUtils.ts index 6424d75f01b..0eeb2122d71 100644 --- a/suite-common/wallet-utils/src/sendFormUtils.ts +++ b/suite-common/wallet-utils/src/sendFormUtils.ts @@ -327,6 +327,7 @@ export const getExternalComposeOutput = ( values: Partial, account: Account, network: Network, + formattedFallbackAmount?: string, // for cases when value is zero but amount is available in eth data ) => { if (!values || !Array.isArray(values.outputs) || !values.outputs[0]) return; const out = values.outputs[0]; @@ -356,7 +357,7 @@ export const getExternalComposeOutput = ( output = { type: 'payment', address, - amount: amountInSatoshi, + amount: formattedFallbackAmount || formattedAmount, }; } else { output = { diff --git a/yarn.lock b/yarn.lock index 93c3769fb35..c3a5d4ca04f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9118,6 +9118,7 @@ __metadata: "@trezor/connect": "workspace:*" "@trezor/urls": "workspace:*" date-fns: "npm:^2.30.0" + web3-utils: "npm:^4.3.1" languageName: unknown linkType: soft From de50ecb7e5986f84d1993f65ca9159310b24afba Mon Sep 17 00:00:00 2001 From: tomasklim Date: Sun, 3 Nov 2024 15:55:52 +0100 Subject: [PATCH 3/5] fix(suite): double label when bumping staking txs --- .../TransactionReviewOutput.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutput.tsx b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutput.tsx index e7d9bba38d3..8694dacf71b 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutput.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutput.tsx @@ -56,7 +56,8 @@ export type TransactionReviewOutputProps = { export const TransactionReviewOutput = forwardRef( (props, ref) => { - const { type, state, label, value, symbol, token, account, ethereumStakeType } = props; + const { type, state, label, value, symbol, token, account, ethereumStakeType, isRbf } = + props; let outputLabel: ReactNode = label; const { networkType } = account; const { translationString } = useTranslation(); @@ -156,6 +157,11 @@ export const TransactionReviewOutput = forwardRef Date: Sun, 3 Nov 2024 16:03:31 +0100 Subject: [PATCH 4/5] fix(suite): hide amount line when bumping fee of claim tx --- .../TransactionReviewOutputElement.tsx | 7 +- .../TransactionReviewOutputList.tsx | 2 + .../TransactionReviewTotalOutput.tsx | 106 +++++++++++------- 3 files changed, 71 insertions(+), 44 deletions(-) diff --git a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputElement.tsx b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputElement.tsx index 2f530682f66..dc37416b82e 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputElement.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputElement.tsx @@ -171,12 +171,13 @@ export const TransactionReviewOutputElement = forwardRef< const network = account?.networkType; const cardanoFingerprint = getFingerprint(account?.tokens, token?.symbol); const isActive = state === 'active'; - const hasMultipleLines = lines.length > 1; + + const showMultiIndicator = lines.length > 1; return ( - - {hasMultipleLines ? ( + + {showMultiIndicator ? ( {indicator} diff --git a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputList.tsx b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputList.tsx index 788046d2802..94480e89c91 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputList.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewOutputList.tsx @@ -234,6 +234,8 @@ export const TransactionReviewOutputList = ({ outputs={outputs} buttonRequestsCount={buttonRequestsCount} precomposedTx={precomposedTx} + ethereumStakeType={ethereumStakeType} + isRbfAction={isRbfAction} /> )} diff --git a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewTotalOutput.tsx b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewTotalOutput.tsx index 66c3b716f26..11be00b6fb2 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewTotalOutput.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewOutputList/TransactionReviewTotalOutput.tsx @@ -19,6 +19,7 @@ import { OutputElementLine, } from './TransactionReviewOutputElement'; import type { TransactionReviewOutputListProps } from './TransactionReviewOutputList'; +import { StakeType } from '@suite-common/wallet-types'; type StepIndicatorProps = Pick< TransactionReviewOutputListProps, @@ -35,7 +36,7 @@ const StepIndicator = ({ signedTx, outputs, buttonRequestsCount }: StepIndicator type TransactionReviewTotalOutputProps = Omit< TransactionReviewOutputListProps, - 'precomposedForm' | 'decision' | 'detailsOpen' | 'isRbfAction' | 'actionText' + 'precomposedForm' | 'decision' | 'detailsOpen' | 'actionText' >; const getLines = ( @@ -43,6 +44,8 @@ const getLines = ( networkType: TransactionReviewOutputListProps['account']['networkType'], symbol: TransactionReviewOutputListProps['account']['symbol'], precomposedTx: TransactionReviewOutputListProps['precomposedTx'], + isRbfAction?: boolean, + ethereumStakeType?: StakeType, ): Array => { const isUpdatedSendFlow = getIsUpdatedSendFlow(device); const isUpdatedEthereumSendFlow = getIsUpdatedEthereumSendFlow(device, networkType); @@ -65,20 +68,21 @@ const getLines = ( .toString(); if (isUpdatedEthereumSendFlow) { - return [ - { - id: 'amount', // In updated ethereum send flow there is no total amount shown, only amount without fee - label: , - value: tokenInfo - ? formatAmount(precomposedTx.totalSpent, tokenInfo.decimals) - : formatNetworkAmount(amountWithoutFee, symbol), - }, - { - id: 'fee', - label: , - value: formatNetworkAmount(precomposedTx.fee, symbol), - }, - ]; + const isUnknownStakingClaimValue = isRbfAction && ethereumStakeType === 'claim'; + const amountLine = { + id: 'amount', // In updated ethereum send flow there is no total amount shown, only amount without fee + label: , + value: tokenInfo + ? formatAmount(precomposedTx.totalSpent, tokenInfo.decimals) + : formatNetworkAmount(amountWithoutFee, symbol), + }; + const feeLine = { + id: 'fee', + label: , + value: formatNetworkAmount(precomposedTx.fee, symbol), + }; + + return isUnknownStakingClaimValue ? [feeLine] : [amountLine, feeLine]; } if (isUpdatedSendFlow) { return [ @@ -112,33 +116,53 @@ const getLines = ( export const TransactionReviewTotalOutput = forwardRef< HTMLDivElement, TransactionReviewTotalOutputProps ->(({ account, signedTx, outputs, buttonRequestsCount, precomposedTx }, ref) => { - const device = useSelector(selectDevice); +>( + ( + { + account, + signedTx, + outputs, + buttonRequestsCount, + precomposedTx, + ethereumStakeType, + isRbfAction, + }, + ref, + ) => { + const device = useSelector(selectDevice); - if (!device) { - return null; - } + if (!device) { + return null; + } - const { symbol, networkType } = account; + const { symbol, networkType } = account; - const lines = getLines(device, networkType, symbol, precomposedTx); + const lines = getLines( + device, + networkType, + symbol, + precomposedTx, + isRbfAction, + ethereumStakeType, + ); - return ( - - } - lines={lines} - cryptoSymbol={symbol} - fiatSymbol={symbol} - fiatVisible={!isTestnet(symbol)} - ref={ref} - token={precomposedTx?.token} - /> - ); -}); + return ( + + } + lines={lines} + cryptoSymbol={symbol} + fiatSymbol={symbol} + fiatVisible={!isTestnet(symbol)} + ref={ref} + token={precomposedTx?.token} + /> + ); + }, +); From 973274f9d9146944b4710386f0b7669dd47d2c45 Mon Sep 17 00:00:00 2001 From: tomasklim Date: Sun, 3 Nov 2024 16:04:23 +0100 Subject: [PATCH 5/5] fix(suite): hide 0 value when bumping fee of claim tx & approve trade tx --- .../TransactionReviewSummary.tsx | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewSummary.tsx b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewSummary.tsx index 12c91001860..68134c5cbfa 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewSummary.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewSummary.tsx @@ -242,6 +242,8 @@ export const TransactionReviewSummary = ({ const isFeeCustom = drafts[currentAccountKey]?.selectedFee === 'custom'; const isComposedFeeRateDifferent = isFeeCustom && formFeeRate !== fee; + const isZeroAmount = amount === '0'; // bump claim tx and trade approve has 0 value + return ( @@ -254,13 +256,15 @@ export const TransactionReviewSummary = ({ - - - + {!isZeroAmount && ( + + + + )}