From c7d1906108ca4512a9717ecebfc8c8bdcb366945 Mon Sep 17 00:00:00 2001 From: Victor Kirov Date: Thu, 3 Oct 2024 14:37:42 +0300 Subject: [PATCH] Prep for native segwit (#583) * Prep for native segwit * Update ledger confirmation screen to be stx specific * bump core * Remove unused type lib * Update core * Fix issue with xverse api call * Update package.json * Bump core --- package-lock.json | 14 +- package.json | 2 +- .../confirmBtcTransaction/ledgerStepView.tsx | 2 +- .../confirmStxTransactionComponent/index.tsx | 1 - src/app/components/stepper/index.tsx | 121 ---- .../transactionSetting/editBtcFee.tsx | 408 ------------- .../transactionSetting/editStxFee.tsx | 13 +- .../components/transactionSetting/feeItem.tsx | 186 ------ .../components/transactionSetting/index.tsx | 138 +---- src/app/hooks/useBtcFeeRate.ts | 7 +- src/app/hooks/useBtcFees.ts | 116 ---- src/app/routes/index.tsx | 6 +- .../screens/confirmFtTransaction/index.tsx | 6 +- .../screens/confirmNftTransaction/index.tsx | 6 +- .../screens/confirmStxTransaction/index.tsx | 6 +- .../index.styled.ts | 22 - .../confirmLedgerStxTransaction/index.tsx | 314 ++++++++++ .../ledger/confirmLedgerTransaction/index.tsx | 575 ------------------ src/app/screens/signPsbtRequest/index.tsx | 4 +- .../screens/signPsbtRequest/useSignPsbt.ts | 28 +- src/app/screens/speedUpTransaction/index.tsx | 4 +- src/app/utils/currency.ts | 94 +-- src/common/types/ledger.ts | 10 +- src/locales/en.json | 3 +- 24 files changed, 418 insertions(+), 1668 deletions(-) delete mode 100644 src/app/components/stepper/index.tsx delete mode 100644 src/app/components/transactionSetting/editBtcFee.tsx delete mode 100644 src/app/components/transactionSetting/feeItem.tsx delete mode 100644 src/app/hooks/useBtcFees.ts rename src/app/screens/ledger/{confirmLedgerTransaction => confirmLedgerStxTransaction}/index.styled.ts (77%) create mode 100644 src/app/screens/ledger/confirmLedgerStxTransaction/index.tsx delete mode 100644 src/app/screens/ledger/confirmLedgerTransaction/index.tsx diff --git a/package-lock.json b/package-lock.json index bc96e7796..415ee7480 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@playwright/test": "1.46.1", "@react-spring/web": "^9.6.1", "@sats-connect/core": "0.3.0", - "@secretkeylabs/xverse-core": "23.0.0", + "@secretkeylabs/xverse-core": "24.0.0", "@stacks/connect": "7.4.1", "@stacks/stacks-blockchain-api-types": "6.1.1", "@stacks/transactions": "6.16.1", @@ -1270,9 +1270,9 @@ } }, "node_modules/@secretkeylabs/xverse-core": { - "version": "23.0.0", - "resolved": "https://npm.pkg.github.com/download/@secretkeylabs/xverse-core/23.0.0/d5f2b2868344504e3933bca5efca5ff67331e192", - "integrity": "sha512-jXkrCtO7aRCBerbz0ktO+1oHiDy8Ef0eMoXQe+YExxba1kVgSh5XevDRXT8vtzf5SQKr7Kg4thxhnMbQ9UofSg==", + "version": "24.0.0", + "resolved": "https://npm.pkg.github.com/download/@secretkeylabs/xverse-core/24.0.0/9b8bace8b966fd87f149e88e7a27f6c05af0a448", + "integrity": "sha512-eRO7o4sjYrHgEy6da4Ip1+4iS1SRP5MEC38AWb1/AnEnJyuXEnPMS90NK+WhdwjSRUjcNBkFM6li0MIk1x+nkw==", "license": "ISC", "dependencies": { "@bitcoinerlab/secp256k1": "^1.0.2", @@ -13635,9 +13635,9 @@ } }, "@secretkeylabs/xverse-core": { - "version": "23.0.0", - "resolved": "https://npm.pkg.github.com/download/@secretkeylabs/xverse-core/23.0.0/d5f2b2868344504e3933bca5efca5ff67331e192", - "integrity": "sha512-jXkrCtO7aRCBerbz0ktO+1oHiDy8Ef0eMoXQe+YExxba1kVgSh5XevDRXT8vtzf5SQKr7Kg4thxhnMbQ9UofSg==", + "version": "24.0.0", + "resolved": "https://npm.pkg.github.com/download/@secretkeylabs/xverse-core/24.0.0/9b8bace8b966fd87f149e88e7a27f6c05af0a448", + "integrity": "sha512-eRO7o4sjYrHgEy6da4Ip1+4iS1SRP5MEC38AWb1/AnEnJyuXEnPMS90NK+WhdwjSRUjcNBkFM6li0MIk1x+nkw==", "requires": { "@bitcoinerlab/secp256k1": "^1.0.2", "@noble/curves": "^1.2.0", diff --git a/package.json b/package.json index 26075e48a..b670a007a 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "@playwright/test": "1.46.1", "@react-spring/web": "^9.6.1", "@sats-connect/core": "0.3.0", - "@secretkeylabs/xverse-core": "23.0.0", + "@secretkeylabs/xverse-core": "24.0.0", "@stacks/connect": "7.4.1", "@stacks/stacks-blockchain-api-types": "6.1.1", "@stacks/transactions": "6.16.1", diff --git a/src/app/components/confirmBtcTransaction/ledgerStepView.tsx b/src/app/components/confirmBtcTransaction/ledgerStepView.tsx index 74c7520eb..5eccd8f9e 100644 --- a/src/app/components/confirmBtcTransaction/ledgerStepView.tsx +++ b/src/app/components/confirmBtcTransaction/ledgerStepView.tsx @@ -9,7 +9,7 @@ import LedgerFailView from '@components/ledger/failLedgerView'; import { ConnectLedgerTitle, InfoImage, -} from '@screens/ledger/confirmLedgerTransaction/index.styled'; +} from '@screens/ledger/confirmLedgerStxTransaction/index.styled'; import type { TFunction } from 'react-i18next'; export enum Steps { diff --git a/src/app/components/confirmStxTransactionComponent/index.tsx b/src/app/components/confirmStxTransactionComponent/index.tsx index f69a1c299..983440b28 100644 --- a/src/app/components/confirmStxTransactionComponent/index.tsx +++ b/src/app/components/confirmStxTransactionComponent/index.tsx @@ -397,7 +397,6 @@ function ConfirmStxTransactionComponent({ ((props) => ({ - marginTop: props.theme.spacing(8), - fontSize: '0.875rem', - fontWeight: 500, - color: props.isActive ? props.theme.colors.white_0 : props.theme.colors.white_600, - transition: 'color 0.3s ease', -})); - -const getBackgroundColor = (props) => { - if (props.isCompleted) { - return props.theme.colors.success_medium; - } - if (props.isActive) { - return '#4C525F'; - } - return 'transparent'; -}; - -const Dot = styled.div((props) => ({ - height: 30, - width: 30, - backgroundColor: getBackgroundColor(props), - border: '2px solid', - borderColor: props.isCompleted - ? props.theme.colors.success_medium - : props.theme.colors.elevation6, - borderRadius: '50%', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - color: props.theme.colors.white_0, - fontWeight: 'bold', - fontSize: '0.875rem', - flex: '1 0 auto', - transition: 'background-color 0.3s ease, border-color 0.3s ease', - '&::after': { - content: '""', - display: props.isActive ? 'block' : 'none', - position: 'absolute', - width: 8, - height: 8, - borderRadius: '50%', - backgroundColor: props.theme.colors.white_0, - }, -})); - -const calculateColorStops = (props) => { - const successColor = props.theme.colors.success_medium; - - // Calculate the color stops - let startStop: string; - if (props.step === 0) startStop = '0%'; - if (props.step > 1) startStop = '100%'; - else startStop = '50%'; - const endStop = props.step > 0 ? '50%' : '0%'; - - return `${successColor} ${startStop}, #4C525F ${endStop}`; -}; - -type LineProps = { step: number }; -const Line = styled.div((props) => ({ - height: 2, - width: '100%', - background: `linear-gradient(90deg, ${calculateColorStops(props)})`, - marginTop: props.theme.spacing(8), -})); - -interface Props { - steps: { title: string; isCompleted: boolean }[]; -} - -// TODO: Make this component more generic -export default function Stepper({ steps }: Props): JSX.Element { - const currentStepIndex = steps.findIndex((step) => !step.isCompleted); - const currentStep = currentStepIndex > -1 ? currentStepIndex : steps.length; - - function getContentForDot(stepIndex: number, isCompleted: boolean, currentPosition: number) { - if (isCompleted) { - return Check Icon; - } - if (currentPosition !== stepIndex) { - return String(stepIndex + 1); - } - return ''; - } - return ( - <> - - - {getContentForDot(0, steps[0].isCompleted, currentStep)} - - - - {getContentForDot(1, steps[1].isCompleted, currentStep)} - - - - {steps.map((step, index) => ( - - {step.title} - - ))} - - - ); -} diff --git a/src/app/components/transactionSetting/editBtcFee.tsx b/src/app/components/transactionSetting/editBtcFee.tsx deleted file mode 100644 index f2e04dae2..000000000 --- a/src/app/components/transactionSetting/editBtcFee.tsx +++ /dev/null @@ -1,408 +0,0 @@ -import FiatAmountText from '@components/fiatAmountText'; -import useBtcClient from '@hooks/apiClients/useBtcClient'; -import useSupportedCoinRates from '@hooks/queries/useSupportedCoinRates'; -import useBtcFees from '@hooks/useBtcFees'; -import useDebounce from '@hooks/useDebounce'; -import useOrdinalsByAddress from '@hooks/useOrdinalsByAddress'; -import useSelectedAccount from '@hooks/useSelectedAccount'; -import useWalletSelector from '@hooks/useWalletSelector'; -import { Faders } from '@phosphor-icons/react'; -import { - ErrorCodes, - getBtcFees, - getBtcFeesForNonOrdinalBtcSend, - getBtcFeesForOrdinalSend, - getBtcFiatEquivalent, - type Recipient, - type UTXO, -} from '@secretkeylabs/xverse-core'; -import { StyledP } from '@ui-library/common.styled'; -import BigNumber from 'bignumber.js'; -import { useEffect, useMemo, useRef, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { NumericFormat } from 'react-number-format'; -import styled from 'styled-components'; -import Theme from 'theme'; -import FeeItem from './feeItem'; - -const Container = styled.div((props) => ({ - display: 'flex', - flexDirection: 'column', - paddingBottom: props.theme.space.m, -})); - -const DetailText = styled.h1((props) => ({ - ...props.theme.typography.body_m, - color: props.theme.colors.white_200, -})); - -const InputContainer = styled.div<{ - withError?: boolean; -}>((props) => ({ - display: 'flex', - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - marginTop: props.theme.space.xs, - marginBottom: props.theme.space.s, - border: `1px solid ${ - props.withError ? props.theme.colors.danger_medium : props.theme.colors.elevation6 - }`, - backgroundColor: props.theme.colors.elevation1, - borderRadius: props.theme.radius(1), - padding: props.theme.space.s, -})); - -const InputField = styled.input((props) => ({ - ...props.theme.typography.body_m, - backgroundColor: 'transparent', - color: props.theme.colors.white_0, - border: 'transparent', - width: '50%', - '&::-webkit-outer-spin-button': { - '-webkit-appearance': 'none', - margin: 0, - }, - '&::-webkit-inner-spin-button': { - '-webkit-appearance': 'none', - margin: 0, - }, - '&[type=number]': { - '-moz-appearance': 'textfield', - }, -})); - -const FeeText = styled.span((props) => ({ - ...props.theme.typography.body_m, - color: props.theme.colors.white_0, -})); - -const FeeContainer = styled.div({ - display: 'flex', - flexDirection: 'column', -}); - -const ErrorText = styled.h1((props) => ({ - ...props.theme.typography.body_s, - color: props.theme.colors.danger_light, - marginBottom: props.theme.space.xxs, -})); - -const FeePrioritiesContainer = styled.div` - display: flex; - margin-top: ${(props) => props.theme.space.m}; - flex-direction: column; -`; - -const FeeItemContainer = styled.button<{ - isSelected: boolean; -}>` - display: flex; - padding: ${(props) => props.theme.space.s} ${(props) => props.theme.space.m}; - align-items: center; - gap: ${(props) => props.theme.space.s}; - align-self: stretch; - border-radius: ${(props) => props.theme.space.s}; - border: 1px solid ${(props) => props.theme.colors.elevation6}; - flex-direction: row; - background: ${(props) => (props.isSelected ? props.theme.colors.elevation6_600 : 'transparent')}; - margin-top: ${(props) => props.theme.space.xs}; - flex: 1; - transition: background-color 0.1s ease; - - &:hover:enabled { - background-color: ${(props) => props.theme.colors.elevation6_400}; - } - - &:active:enabled { - background-color: ${(props) => props.theme.colors.elevation6_600}; - } -`; - -const TextRow = styled.div` - display: flex; - flex-direction: row; - justify-content: space-between; - flex: 1; -`; - -const CustomTextsContainer = styled.div` - display: flex; - flex-direction: row; - justify-content: space-between; - flex: 1; -`; - -const Row = styled.div` - display: flex; - flex-direction: row; - align-items: center; -`; - -const TotalFeeText = styled(StyledP)` - margin-right: ${(props) => props.theme.space.xxs}; -`; - -type Props = { - type?: string; - fee: string; - feeRate?: BigNumber | string; - btcRecipients?: Recipient[]; - ordinalTxUtxo?: UTXO; - isRestoreFlow?: boolean; - nonOrdinalUtxos?: UTXO[]; - feeMode: string; - error: string; - customFeeSelected: boolean; - setIsLoading: () => void; - setIsNotLoading: () => void; - setFee: (fee: string) => void; - setFeeRate: (feeRate: string) => void; - setFeeMode: (feeMode: string) => void; - setError: (error: string) => void; - setCustomFeeSelected: (selected: boolean) => void; - feeOptionSelected: (feeRate: string, totalFee: string) => void; -}; - -function EditBtcFee({ - type, - fee, - feeRate, - btcRecipients, - ordinalTxUtxo, - isRestoreFlow, - nonOrdinalUtxos, - feeMode, - error, - customFeeSelected, - setIsLoading, - setIsNotLoading, - setFee, - setFeeRate, - setError, - setFeeMode, - setCustomFeeSelected, - feeOptionSelected, -}: Props) { - const { t } = useTranslation('translation'); - - const selectedAccount = useSelectedAccount(); - const { btcAddress, ordinalsAddress } = selectedAccount; - const { network, fiatCurrency } = useWalletSelector(); - const { btcFiatRate } = useSupportedCoinRates(); - const [totalFee, setTotalFee] = useState(fee); - const [feeRateInput, setFeeRateInput] = useState(feeRate?.toString() ?? ''); - const inputRef = useRef(null); - const debouncedFeeRateInput = useDebounce(feeRateInput, 500); - const { ordinals } = useOrdinalsByAddress(btcAddress); - const ordinalsUtxos = useMemo(() => ordinals?.map((ord) => ord.utxo), [ordinals]); - const btcClient = useBtcClient(); - const { feeData, highFeeError, mediumFeeError } = useBtcFees({ - isRestoreFlow: !!isRestoreFlow, - nonOrdinalUtxos, - btcRecipients, - type, - ordinalTxUtxo, - }); - - useEffect(() => { - setFee(totalFee); - }, [totalFee]); - - const recalculateFees = async () => { - if (type === 'BTC') { - try { - setIsLoading(); - setError(''); - - if (isRestoreFlow) { - const { fee: modifiedFee, selectedFeeRate } = await getBtcFeesForNonOrdinalBtcSend( - btcAddress, - nonOrdinalUtxos!, - ordinalsAddress, - network.type, - feeMode, - feeRateInput, - ); - setFeeRateInput(selectedFeeRate!.toString()); - setTotalFee(modifiedFee.toString()); - } else if (btcRecipients && selectedAccount) { - const { fee: modifiedFee, selectedFeeRate } = await getBtcFees( - btcRecipients, - btcAddress, - btcClient, - network.type, - feeMode, - feeRateInput, - ); - setFeeRateInput(selectedFeeRate!.toString()); - setTotalFee(modifiedFee.toString()); - } - } catch (err: any) { - if (Number(err) === ErrorCodes.InSufficientBalance) { - setError(t('TX_ERRORS.INSUFFICIENT_BALANCE')); - } else if (Number(err) === ErrorCodes.InSufficientBalanceWithTxFee) { - setError(t('TX_ERRORS.INSUFFICIENT_BALANCE_FEES')); - } else setError(err.toString()); - } finally { - setIsNotLoading(); - } - } else if (type === 'Ordinals' && btcRecipients && ordinalTxUtxo) { - try { - setIsLoading(); - setError(''); - - const { fee: modifiedFee, selectedFeeRate } = await getBtcFeesForOrdinalSend( - btcRecipients[0].address, - ordinalTxUtxo, - btcAddress, - btcClient, - network.type, - ordinalsUtxos || [], - feeMode, - feeRateInput, - ); - if (selectedFeeRate) setFeeRateInput(selectedFeeRate.toString()); - setTotalFee(modifiedFee.toString()); - } catch (err: any) { - if (Number(err) === ErrorCodes.InSufficientBalance) { - setError(t('TX_ERRORS.INSUFFICIENT_BALANCE')); - } else if (Number(err) === ErrorCodes.InSufficientBalanceWithTxFee) { - setError(t('TX_ERRORS.INSUFFICIENT_BALANCE_FEES')); - } else setError(err.toString()); - } finally { - setIsNotLoading(); - } - } - }; - - useEffect(() => { - if (feeRateInput) { - setFeeRate(feeRateInput); - } - }, [feeRateInput]); - - useEffect(() => { - if (debouncedFeeRateInput) { - recalculateFees(); - } - }, [debouncedFeeRateInput]); - - const onInputEditFeesChange = ({ target: { value } }: React.ChangeEvent) => { - if (error) { - setError(''); - } - - if (feeMode !== 'custom') { - setFeeMode('custom'); - } - - setFeeRateInput(value); - - if (type !== 'BTC' && type !== 'Ordinals') { - setFeeRateInput(value); - setTotalFee(value); - } - }; - - return ( - - {t('TRANSACTION_SETTING.FEE_INFO')} - - {!customFeeSelected && ( - - { - feeOptionSelected(feeData?.highFeeRate?.toString() || '', feeData?.highTotalFee); - setFeeMode('high'); - }} - selected={feeMode === 'high'} - error={highFeeError} - /> - { - feeOptionSelected( - feeData?.standardFeeRate?.toString() || '', - feeData?.standardTotalFee, - ); - setFeeMode('medium'); - }} - selected={feeMode === 'medium'} - error={mediumFeeError} - /> - { - setCustomFeeSelected(true); - }} - > - - - - {t('TRANSACTION_SETTING.CUSTOM')} - - - {t('TRANSACTION_SETTING.MANUAL_SETTING')} - - - - - )} - - {customFeeSelected && ( - - - - {t('UNITS.SATS_PER_VB')} - - - - - {t('TRANSACTION_SETTING.TOTAL_FEE')}: - - ( - - {value} - - )} - /> - - - - {error && {error}} - - )} - - ); -} - -export default EditBtcFee; diff --git a/src/app/components/transactionSetting/editStxFee.tsx b/src/app/components/transactionSetting/editStxFee.tsx index 4cd551c8c..9f2925f4a 100644 --- a/src/app/components/transactionSetting/editStxFee.tsx +++ b/src/app/components/transactionSetting/editStxFee.tsx @@ -105,7 +105,6 @@ const ErrorText = styled.p((props) => ({ // TODO tim: this component needs refactoring. separate business logic from presentation type Props = { - type?: string; fee: string; feeRate?: BigNumber | string; feeMode: string; @@ -117,7 +116,6 @@ type Props = { }; function EditStxFee({ - type, fee, feeRate, feeMode, @@ -133,7 +131,6 @@ function EditStxFee({ const [totalFee, setTotalFee] = useState(fee); const [feeRateInput, setFeeRateInput] = useState(feeRate?.toString() ?? ''); const inputRef = useRef(null); - const isStx = type === 'STX'; const modifyStxFees = (mode: string) => { const currentFee = new BigNumber(fee); @@ -161,7 +158,7 @@ function EditStxFee({ }; useEffect(() => { - if (isStx && feeMode !== 'custom') { + if (feeMode !== 'custom') { modifyStxFees(feeMode); } }, [feeMode]); @@ -215,11 +212,9 @@ function EditStxFee({ {error && {error}} - {isStx && ( - modifyStxFees('low')}> - {t('TRANSACTION_SETTING.LOW')} - - )} + modifyStxFees('low')}> + {t('TRANSACTION_SETTING.LOW')} + modifyStxFees('medium')}> {t('TRANSACTION_SETTING.STANDARD')} diff --git a/src/app/components/transactionSetting/feeItem.tsx b/src/app/components/transactionSetting/feeItem.tsx deleted file mode 100644 index 4af201283..000000000 --- a/src/app/components/transactionSetting/feeItem.tsx +++ /dev/null @@ -1,186 +0,0 @@ -import FiatAmountText from '@components/fiatAmountText'; -import useWalletSelector from '@hooks/useWalletSelector'; -import { Bicycle, CarProfile, RocketLaunch } from '@phosphor-icons/react'; -import { ErrorCodes } from '@secretkeylabs/xverse-core'; -import { StyledP } from '@ui-library/common.styled'; -import Spinner from '@ui-library/spinner'; -import BigNumber from 'bignumber.js'; -import { useTranslation } from 'react-i18next'; -import styled from 'styled-components'; -import Theme from 'theme'; - -const FeeItemContainer = styled.button<{ - isSelected: boolean; -}>` - display: flex; - padding: ${(props) => props.theme.space.s} ${(props) => props.theme.space.m}; - align-items: center; - gap: ${(props) => props.theme.space.s}; - align-self: stretch; - border-radius: ${(props) => props.theme.space.s}; - border: 1px solid ${(props) => props.theme.colors.elevation6}; - flex-direction: row; - background: ${(props) => (props.isSelected ? props.theme.colors.elevation6_600 : 'transparent')}; - margin-top: ${(props) => props.theme.space.xs}; - flex: 1; - transition: background-color 0.1s ease; - - &:hover:enabled { - background-color: ${(props) => props.theme.colors.elevation6_400}; - } - - &:active:enabled { - background-color: ${(props) => props.theme.colors.elevation6_600}; - } -`; - -const IconContainer = styled.div` - display: flex; - align-items: center; - justify-content: center; -`; - -const TextsContainer = styled.div` - display: flex; - flex-direction: row; - justify-content: space-between; - - flex: 1; -`; - -const ColumnsTexts = styled.div` - display: flex; - flex-direction: column; - align-items: flex-start; - flex: 1; -`; -const EndColumnTexts = styled.div` - display: flex; - flex-direction: column; - align-items: flex-end; -`; - -const StyledHeading = styled(StyledP)` - margin-bottom: ${(props) => props.theme.space.xxs}; -`; - -const StyledSubText = styled(StyledP)` - margin-bottom: ${(props) => props.theme.space.xxs}; -`; - -const LoaderContainer = styled.div` - display: flex; - align-items: center; - justify-content: flex-end; - flex: 1; -`; - -const StyledFiatAmountText = styled(FiatAmountText)` - ${(props) => props.theme.typography.body_medium_s} - color: ${(props) => props.theme.colors.white_200}; -`; - -type FeePriority = 'high' | 'medium' | 'low'; - -type Props = { - priority: FeePriority; - time: string; - feeRate: string; - totalFee: string; - fiatAmount: BigNumber; - selected: boolean; - onClick?: () => void; - error?: string; -}; - -function FeeItem({ - priority, - time, - feeRate, - totalFee, - fiatAmount, - selected, - error, - onClick, -}: Props) { - const { t } = useTranslation('translation'); - const { fiatCurrency } = useWalletSelector(); - - const getIcon = () => { - switch (priority) { - case 'high': - return ; - case 'medium': - return ; - case 'low': - return ; - default: - return ; - } - }; - - const getLabel = () => { - switch (priority) { - case 'high': - return t('SPEED_UP_TRANSACTION.HIGH_PRIORITY'); - case 'medium': - return t('SPEED_UP_TRANSACTION.MED_PRIORITY'); - case 'low': - return t('SPEED_UP_TRANSACTION.LOW_PRIORITY'); - default: - return t('SPEED_UP_TRANSACTION.HIGH_PRIORITY'); - } - }; - - const getErrorMessage = (btcError: string) => { - if ( - Number(btcError) === ErrorCodes.InSufficientBalance || - Number(btcError) === ErrorCodes.InSufficientBalanceWithTxFee - ) { - return t('SEND.ERRORS.INSUFFICIENT_BALANCE'); - } - return btcError; - }; - - return ( - - {getIcon()} - - - - {getLabel()} - - - {time} - - {`${feeRate} sats/vB`} - - - - {totalFee && ( - - {`${totalFee} sats`} - - )} - - {error && ( - - {getErrorMessage(error)} - - )} - - - {!totalFee && !error && ( - - - - )} - - - ); -} - -export default FeeItem; diff --git a/src/app/components/transactionSetting/index.tsx b/src/app/components/transactionSetting/index.tsx index 7ae8c456e..d3701050c 100644 --- a/src/app/components/transactionSetting/index.tsx +++ b/src/app/components/transactionSetting/index.tsx @@ -1,20 +1,12 @@ import ArrowIcon from '@assets/img/settings/arrow.svg'; -import useBtcWalletData from '@hooks/queries/useBtcWalletData'; import useStxWalletData from '@hooks/queries/useStxWalletData'; -import useWalletSelector from '@hooks/useWalletSelector'; -import { - isCustomFeesAllowed, - stxToMicrostacks, - type Recipient, - type UTXO, -} from '@secretkeylabs/xverse-core'; +import { stxToMicrostacks } from '@secretkeylabs/xverse-core'; import Button from '@ui-library/button'; import Sheet from '@ui-library/sheet'; import BigNumber from 'bignumber.js'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; -import EditBtcFee from './editBtcFee'; import EditNonce from './editNonce'; import EditStxFee from './editStxFee'; @@ -49,21 +41,13 @@ const TransactionSettingNonceOptionButton = styled.button((props) => ({ justifyContent: 'space-between', })); -type TxType = 'STX' | 'BTC' | 'Ordinals'; - type Props = { visible: boolean; fee: string; - feePerVByte?: BigNumber; loading?: boolean; nonce?: string; onApplyClick: (params: { fee: string; feeRate?: string; nonce?: string }) => void; onCrossClick: () => void; - type?: TxType; - btcRecipients?: Recipient[]; - ordinalTxUtxo?: UTXO; - isRestoreFlow?: boolean; - nonOrdinalUtxos?: UTXO[]; showFeeSettings: boolean; nonceSettings?: boolean; setShowFeeSettings: (value: boolean) => void; @@ -72,32 +56,22 @@ type Props = { function TransactionSettingAlert({ visible, fee, - feePerVByte, loading, nonce, onApplyClick, onCrossClick, - type = 'STX', - btcRecipients, - ordinalTxUtxo, - isRestoreFlow, - nonOrdinalUtxos, showFeeSettings, nonceSettings = false, setShowFeeSettings, }: Props) { const { t } = useTranslation('translation'); const [feeInput, setFeeInput] = useState(fee); - const [feeRate, setFeeRate] = useState(feePerVByte); + const [feeRate, setFeeRate] = useState(); const [nonceInput, setNonceInput] = useState(nonce); const [error, setError] = useState(''); const [selectedOption, setSelectedOption] = useState('medium'); const [showNonceSettings, setShowNonceSettings] = useState(false); - const [isLoading, setIsLoading] = useState(loading); - const [customFeeSelected, setCustomFeeSelected] = useState(false); - const { network } = useWalletSelector(); const { data: stxData } = useStxWalletData(); - const { data: btcBalance } = useBtcWalletData(); const applyClickForStx = () => { if (stxData?.availableBalance) { @@ -130,40 +104,6 @@ function TransactionSettingAlert({ onApplyClick({ fee: feeInput.toString(), nonce: nonceInput }); }; - const applyClickForBtc = async () => { - const currentFee = new BigNumber(feeInput); - if (currentFee.gt(btcBalance ?? 0)) { - // show fee exceeds total balance error - setError(t('TRANSACTION_SETTING.GREATER_FEE_ERROR')); - return; - } - if (selectedOption === 'custom' && feeRate) { - const response = await isCustomFeesAllowed(network.type, feeRate.toString()); - if (!response) { - setError(t('TRANSACTION_SETTING.LOWER_THAN_MINIMUM')); - return; - } - } - setShowNonceSettings(false); - setShowFeeSettings(false); - setCustomFeeSelected(false); - setError(''); - onApplyClick({ fee: feeInput.toString(), feeRate: feeRate?.toString() }); - }; - - const btcFeeOptionSelected = async (selectedFeeRate: string, totalFee: string) => { - const currentFee = new BigNumber(feeInput); - if (currentFee.gt(btcBalance ?? 0)) { - // show fee exceeds total balance error - setError(t('TRANSACTION_SETTING.GREATER_FEE_ERROR')); - return; - } - setShowNonceSettings(false); - setShowFeeSettings(false); - setError(''); - onApplyClick({ fee: totalFee, feeRate: selectedFeeRate }); - }; - const onEditFeesPress = () => { setShowFeeSettings(true); }; @@ -172,14 +112,6 @@ function TransactionSettingAlert({ setShowNonceSettings(true); }; - const onLoading = () => { - setIsLoading(true); - }; - - const onComplete = () => { - setIsLoading(false); - }; - const onClosePress = () => { setShowNonceSettings(false); setShowFeeSettings(false); @@ -192,43 +124,16 @@ function TransactionSettingAlert({ } if (showFeeSettings) { - if (type === 'STX') { - return ( - - ); - } return ( - { - setCustomFeeSelected(selected); - }} - customFeeSelected={customFeeSelected} - feeOptionSelected={btcFeeOptionSelected} /> ); } @@ -241,14 +146,12 @@ function TransactionSettingAlert({ Arrow - {type === 'STX' && ( - - - {t('TRANSACTION_SETTING.ADVANCED_SETTING_NONCE_OPTION')} - - Arrow - - )} + + + {t('TRANSACTION_SETTING.ADVANCED_SETTING_NONCE_OPTION')} + + Arrow + ); }; @@ -266,7 +169,7 @@ function TransactionSettingAlert({ onClose={onClosePress} > {renderContent()} - {type === 'STX' && (showFeeSettings || showNonceSettings || nonceSettings) && ( + {(showFeeSettings || showNonceSettings || nonceSettings) && (