From 65a0cfb220dd2a4fc723aa6196c799d8cdd3f70a Mon Sep 17 00:00:00 2001 From: Peter Sanderson Date: Wed, 12 Feb 2025 15:56:07 +0100 Subject: [PATCH] chore: extract FeeRate component --- .../src/components/FeeRate/FeeRate.tsx | 18 ++++++++++++++++++ packages/product-components/src/index.ts | 1 + .../TransactionReviewSummary.tsx | 8 ++++---- .../TxDetailModal/BasicTxDetails.tsx | 16 ++++++++++------ .../CancelTransaction/CancelTransaction.tsx | 6 +++--- .../TxDetailModal/ChangeFee/ChangeFee.tsx | 10 +++++++--- .../src/components/wallet/Fees/FeeDetails.tsx | 9 ++++++--- suite-common/wallet-utils/src/sendFormUtils.ts | 15 ++++++++------- 8 files changed, 57 insertions(+), 26 deletions(-) create mode 100644 packages/product-components/src/components/FeeRate/FeeRate.tsx diff --git a/packages/product-components/src/components/FeeRate/FeeRate.tsx b/packages/product-components/src/components/FeeRate/FeeRate.tsx new file mode 100644 index 00000000000..472d155a5bb --- /dev/null +++ b/packages/product-components/src/components/FeeRate/FeeRate.tsx @@ -0,0 +1,18 @@ +import { NetworkType } from '@suite-common/wallet-config'; +import { getFeeUnits } from '@suite-common/wallet-utils'; +import { BigNumber } from '@trezor/utils'; + +type FeeRateProps = { + feeRate: string | BigNumber; + networkType: NetworkType; +}; + +export const FeeRate = ({ feeRate, networkType }: FeeRateProps) => { + const fee = typeof feeRate === 'string' ? new BigNumber(feeRate) : feeRate; + + return ( + + {fee.toFixed(2)} {getFeeUnits(networkType)} + + ); +}; diff --git a/packages/product-components/src/index.ts b/packages/product-components/src/index.ts index e9677c14681..23f43bd71f1 100644 --- a/packages/product-components/src/index.ts +++ b/packages/product-components/src/index.ts @@ -22,3 +22,4 @@ export { export { NumberInput } from './components/NumberInput/NumberInput'; export { InputWithOptions } from './components/InputWithOptions/InputWithOptions'; export { EditableText } from './components/EditableText/EditableText'; +export { FeeRate } from './components/FeeRate/FeeRate'; 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 f7e1bd8b484..e7e3caf75b7 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewSummary.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/TransactionReviewModal/TransactionReviewSummary.tsx @@ -1,9 +1,9 @@ import { formatDuration } from '@suite-common/suite-utils'; import { NetworkType, networks } from '@suite-common/wallet-config'; import { FeeInfo, GeneralPrecomposedTransactionFinal, StakeType } from '@suite-common/wallet-types'; -import { getFee, getFeeUnits } from '@suite-common/wallet-utils'; +import { getFee } from '@suite-common/wallet-utils'; import { Box, IconButton, Note, Row, Text } from '@trezor/components'; -import { CoinLogo } from '@trezor/product-components'; +import { CoinLogo, FeeRate } from '@trezor/product-components'; import { spacings } from '@trezor/theme'; import { AccountLabel, Translation } from 'src/components/suite'; @@ -85,11 +85,11 @@ export const TransactionReviewSummary = ({ {': '} - {fee} {getFeeUnits(network.networkType)} + ) : ( - {fee} {getFeeUnits(network.networkType)} + )} diff --git a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/TxDetailModal/BasicTxDetails.tsx b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/TxDetailModal/BasicTxDetails.tsx index a4f47596850..62ca5784ef2 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/TxDetailModal/BasicTxDetails.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/TxDetailModal/BasicTxDetails.tsx @@ -2,7 +2,7 @@ import styled from 'styled-components'; import { fromWei } from 'web3-utils'; import { Network } from '@suite-common/wallet-config'; -import { getFeeRate, getFeeUnits, getTxIcon, isPending } from '@suite-common/wallet-utils'; +import { getFeeRate, getTxIcon, isPending } from '@suite-common/wallet-utils'; import { Card, Divider, @@ -16,7 +16,7 @@ import { Text, useElevation, } from '@trezor/components'; -import { CoinLogo } from '@trezor/product-components'; +import { CoinLogo, FeeRate } from '@trezor/product-components'; import { Elevation, borders, mapElevationToBorder, spacings, spacingsPx } from '@trezor/theme'; import { FormattedDateWithBullet, Translation } from 'src/components/suite'; @@ -148,7 +148,10 @@ export const BasicTxDetails = ({ {/* tx.feeRate was added in @trezor/blockchain-link 2.1.5 meaning that users might have locally saved old transactions without this field. since we cant reliably migrate this data, we are keeping old way of displaying feeRate in place */} - {`${tx?.feeRate ? tx.feeRate : getFeeRate(tx)} ${getFeeUnits('bitcoin')}`} + )} @@ -168,9 +171,10 @@ export const BasicTxDetails = ({ } iconName="receipt"> - {`${fromWei(tx.ethereumSpecific?.gasPrice ?? '0', 'gwei')} ${getFeeUnits( - 'ethereum', - )}`} + } iconName="receipt"> diff --git a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/TxDetailModal/CancelTransaction/CancelTransaction.tsx b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/TxDetailModal/CancelTransaction/CancelTransaction.tsx index 1ab5ca260df..e8a4ccf9a0b 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/TxDetailModal/CancelTransaction/CancelTransaction.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/TxDetailModal/CancelTransaction/CancelTransaction.tsx @@ -1,6 +1,7 @@ import { SelectedAccountLoaded, WalletAccountTransaction } from '@suite-common/wallet-types'; -import { formatNetworkAmount, getFeeUnits } from '@suite-common/wallet-utils'; +import { formatNetworkAmount } from '@suite-common/wallet-utils'; import { Card, Column, Divider, InfoItem, Row, Text } from '@trezor/components'; +import { FeeRate } from '@trezor/product-components'; import { spacings } from '@trezor/theme'; import { HELP_CENTER_CANCEL_TRANSACTION } from '@trezor/urls'; import { BigNumber } from '@trezor/utils'; @@ -66,8 +67,7 @@ export const CancelTransaction = ({ tx, selectedAccount }: CancelTransactionProp - {feePerByte.toFormat(2)}  - {getFeeUnits(networkType)} + } diff --git a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/TxDetailModal/ChangeFee/ChangeFee.tsx b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/TxDetailModal/ChangeFee/ChangeFee.tsx index a28b915a2c2..644958a12e9 100644 --- a/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/TxDetailModal/ChangeFee/ChangeFee.tsx +++ b/packages/suite/src/components/suite/modals/ReduxModal/UserContextModal/TxDetailModal/ChangeFee/ChangeFee.tsx @@ -1,8 +1,9 @@ import { ReactNode } from 'react'; import { WalletAccountTransaction } from '@suite-common/wallet-types'; -import { formatNetworkAmount, getFeeUnits } from '@suite-common/wallet-utils'; +import { formatNetworkAmount } from '@suite-common/wallet-utils'; import { Card, Column, Divider, InfoItem, Row, Text } from '@trezor/components'; +import { FeeRate } from '@trezor/product-components'; import { spacings } from '@trezor/theme'; import { FiatValue, FormattedCryptoAmount, Translation } from 'src/components/suite'; @@ -28,7 +29,10 @@ const ChangeFeeLoaded = (props: ChangeFeeProps) => { } = useRbfContext(); const feeRate = - networkType === 'bitcoin' ? `${tx.rbfParams?.feeRate} ${getFeeUnits(networkType)}` : null; + networkType === 'bitcoin' && tx.rbfParams?.feeRate !== undefined ? ( + + ) : null; + const fee = formatNetworkAmount(tx.fee, tx.symbol); return ( @@ -44,7 +48,7 @@ const ChangeFeeLoaded = (props: ChangeFeeProps) => { label={ <> - {feeRate && ` (${feeRate})`} + {feeRate && <> ({feeRate})} } typographyStyle="body" diff --git a/packages/suite/src/components/wallet/Fees/FeeDetails.tsx b/packages/suite/src/components/wallet/Fees/FeeDetails.tsx index 5b89cbd9504..1f68a50d674 100644 --- a/packages/suite/src/components/wallet/Fees/FeeDetails.tsx +++ b/packages/suite/src/components/wallet/Fees/FeeDetails.tsx @@ -10,6 +10,7 @@ import { import { getFeeUnits } from '@suite-common/wallet-utils'; import { Row, Text } from '@trezor/components'; import { FeeLevel } from '@trezor/connect'; +import { FeeRate } from '@trezor/product-components'; import { spacings } from '@trezor/theme'; import { Translation } from 'src/components/suite/Translation'; @@ -55,8 +56,10 @@ const BitcoinDetails = ({ }> - {hasInfo ? transactionInfo.feePerByte : selectedLevel.feePerUnit}{' '} - {getFeeUnits(networkType)} + {hasInfo ? ` (${transactionInfo.bytes} B)` : ''} @@ -96,7 +99,7 @@ const EthereumDetails = ({ }>{gasLimit} }> - {gasPrice} {getFeeUnits(networkType)} + ) diff --git a/suite-common/wallet-utils/src/sendFormUtils.ts b/suite-common/wallet-utils/src/sendFormUtils.ts index 397dad48701..5bc6823befb 100644 --- a/suite-common/wallet-utils/src/sendFormUtils.ts +++ b/suite-common/wallet-utils/src/sendFormUtils.ts @@ -218,15 +218,16 @@ export const getNonComposeErrorMessage = (error: FieldError | undefined) => export const isLowAnonymityWarning = (error?: Merge>) => error?.amount?.type === COMPOSE_ERROR_TYPES.ANONYMITY; -export const getFeeUnits = (networkType: NetworkType) => { - if (networkType === 'ethereum') return 'GWEI'; - if (networkType === 'ripple') return 'Drops'; - if (networkType === 'cardano') return 'Lovelaces/B'; - if (networkType === 'solana') return 'Lamports'; - - return 'sat/vB'; +const mapNetworkTypeToFeeUnits: Record = { + bitcoin: 'sat/vB', + cardano: 'Lovelaces/B', + ethereum: 'GWEI', + ripple: 'Drops', + solana: 'Lamports', }; +export const getFeeUnits = (networkType: NetworkType) => mapNetworkTypeToFeeUnits[networkType]; + export const getFee = (networkType: NetworkType, tx: GeneralPrecomposedTransactionFinal) => { if (networkType === 'solana') return tx.fee;