diff --git a/src/app/components/confirmStxTransactionComponent/index.tsx b/src/app/components/confirmStxTransactionComponent/index.tsx index 7b23effcb..d23221af0 100644 --- a/src/app/components/confirmStxTransactionComponent/index.tsx +++ b/src/app/components/confirmStxTransactionComponent/index.tsx @@ -130,6 +130,7 @@ interface Props { title?: string; subTitle?: string; hasSignatures?: boolean; + feeOverride?: BigNumber; } function ConfirmStxTransactionComponent({ @@ -144,6 +145,7 @@ function ConfirmStxTransactionComponent({ onCancelClick, skipModal = false, hasSignatures = false, + feeOverride, }: Props) { const { t } = useTranslation('translation', { keyPrefix: 'CONFIRM_TRANSACTION' }); const { t: signatureRequestTranslate } = useTranslation('translation', { @@ -255,6 +257,12 @@ function ConfirmStxTransactionComponent({ setOpenTransactionSettingModal(false); }; + useEffect(() => { + if (feeOverride) { + applyTxSettings({ fee: microstacksToStx(feeOverride).toString() }); + } + }, [feeOverride]); + const handleConnectAndConfirm = async () => { if (!selectedAccount) { console.error('No account selected'); diff --git a/src/app/components/inputScreen/index.tsx b/src/app/components/inputScreen/index.tsx new file mode 100644 index 000000000..956106a5d --- /dev/null +++ b/src/app/components/inputScreen/index.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import styled from 'styled-components'; + +const Container = styled.div` + flex: 1 1 100%; + display: flex; + flex-direction: column; + justify-content: space-between; +`; + +const ButtonsContainer = styled.div` + margin: ${(props) => props.theme.spacing(12)}px 0; +`; + +const InputsContainer = styled.div` + display: flex; + flex-direction: column; +`; + +type InputScreenProps = { + inputs: React.ReactNode; + buttons: React.ReactNode; + header?: React.ReactNode; +}; + +function InputScreen({ inputs, buttons, header }: InputScreenProps) { + return ( + +
+ {header} + {inputs} +
+ {buttons} +
+ ); +} + +export default InputScreen; diff --git a/src/app/screens/confirmStxTransaction/index.tsx b/src/app/screens/confirmStxTransaction/index.tsx index 24baf7560..38a09f93e 100644 --- a/src/app/screens/confirmStxTransaction/index.tsx +++ b/src/app/screens/confirmStxTransaction/index.tsx @@ -22,6 +22,7 @@ import { getStxFiatEquivalent, isMultiSig, microstacksToStx, + stxToMicrostacks, } from '@secretkeylabs/xverse-core'; import { MultiSigSpendingCondition, deserializeTransaction } from '@stacks/transactions'; import { useMutation } from '@tanstack/react-query'; @@ -38,7 +39,6 @@ const AlertContainer = styled.div((props) => ({ function ConfirmStxTransaction() { const { t } = useTranslation('translation'); - const [fee, setStateFee] = useState(new BigNumber(0)); const [amount, setAmount] = useState(new BigNumber(0)); const [fiatAmount, setFiatAmount] = useState(new BigNumber(0)); const [total, setTotal] = useState(new BigNumber(0)); @@ -53,7 +53,18 @@ function ConfirmStxTransaction() { const { refetch } = useStxWalletData(); const location = useLocation(); - const { unsignedTx: stringHex, sponsored, isBrowserTx, tabId, requestToken } = location.state; + const { + unsignedTx: stringHex, + sponsored, + isBrowserTx, + tabId, + requestToken, + fee: stateFee, + } = location.state; + const [fee, setStateFee] = useState( + stateFee ? stxToMicrostacks(new BigNumber(stateFee)) : new BigNumber(0), + ); + const unsignedTx = useMemo(() => deserializeTransaction(stringHex), [stringHex]); // SignTransaction Params @@ -123,7 +134,7 @@ function ConfirmStxTransaction() { } const txAmount = new BigNumber(txPayload.amount.toString(10)); - const txFee = new BigNumber(unsignedTx.auth.spendingCondition.fee.toString()); + const txFee = new BigNumber(fee.toString() ?? unsignedTx.auth.spendingCondition.fee.toString()); const txTotal = amount.plus(fee); const txFiatAmount = getStxFiatEquivalent( amount, @@ -137,7 +148,7 @@ function ConfirmStxTransaction() { const modifiedMemoString = txMemo.content.split('\u0000').join(''); setAmount(txAmount); - setStateFee(txFee); + if (!fee) setStateFee(txFee); setFiatAmount(txFiatAmount); setTotal(txTotal); setFiatTotal(txFiatTotal); @@ -194,6 +205,7 @@ function ConfirmStxTransaction() { recipientAddress: recipient, amountToSend: getAmount().toString(), stxMemo: memo, + fee: fee.toString(), }, }); } @@ -214,6 +226,7 @@ function ConfirmStxTransaction() { isSponsored={sponsored} skipModal={isLedgerAccount(selectedAccount)} hasSignatures={hasSignatures} + feeOverride={fee} > props.theme.spacing(12)}px 0; -`; - -type Props = { +type BtcRecipientScreenProps = { recipientAddress: string; setRecipientAddress: (address: string) => void; onNext: () => void; @@ -26,14 +14,18 @@ type Props = { header?: React.ReactNode; }; -// TODO: this could be extracted into a component for reuse -function RecipientSelector({ +type InputFeedback = { + variant: 'danger'; + message: string; +} + +function BtcRecipientScreen({ recipientAddress, setRecipientAddress, onNext, isLoading, header, -}: Props) { +}: BtcRecipientScreenProps) { const { t } = useTranslation('translation', { keyPrefix: 'SEND' }); const { network } = useWalletSelector(); const [addressIsValid, setAddressIsValid] = useState(true); @@ -51,41 +43,39 @@ function RecipientSelector({ setAddressIsValid(true); }; - const inputFeedback = useMemo(() => { + const inputFeedback: InputFeedback[] = useMemo(() => { if (addressIsValid) { return []; } return [ { - variant: 'danger' as const, + variant: 'danger', message: t('ERRORS.ADDRESS_INVALID'), }, ]; - }, [addressIsValid]); + }, [addressIsValid, t]); + + const inputElement = ( + + ); - return ( - -
- {header} - -
- -