fix(trading): clear preselectedQuote after loading into buy form

(cherry picked from commit 96eadf22cb)
This commit is contained in:
vytick
2026-01-19 14:09:35 +04:00
committed by pavelmario
parent d358b52f31
commit b0d92cc2a5
7 changed files with 86 additions and 13 deletions

View File

@@ -8,6 +8,8 @@ import {
TRADING_DEFAULT_CRYPTO_CURRENCY,
TRADING_FORM_CRYPTO_INPUT,
TRADING_FORM_FIAT_INPUT,
TRADING_FORM_PAYMENT_METHOD_SELECT,
TRADING_FORM_PROVIDER_SELECT,
TradingAmountLimitProps,
TradingBuyFormProps,
type TradingBuyType,
@@ -119,6 +121,7 @@ export const useTradingBuyForm = ({
});
const { formState, reset, setValue, handleSubmit, control } = methods;
const values = useWatch({ control }) as TradingBuyFormProps;
const { paymentMethod, provider } = values;
const previousValues = useRef<TradingBuyFormProps | null>(
!isFromRedirect && isNotFormPage ? draftUpdated : null,
);
@@ -306,6 +309,38 @@ export const useTradingBuyForm = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [receiveAddress]);
useEffect(() => {
if (!preselectedQuote) {
return;
}
const preselectedProvider = preselectedQuote.exchange;
const preselectedPaymentMethod = preselectedQuote.paymentMethod;
const shouldUpdateProvider = !!preselectedProvider && preselectedProvider !== provider;
const shouldUpdatePaymentMethod =
!!preselectedPaymentMethod && paymentMethod?.value !== preselectedPaymentMethod;
dispatch(tradingBuyActions.savePreselectedQuote(undefined));
if (shouldUpdateProvider) {
setValue(TRADING_FORM_PROVIDER_SELECT, preselectedProvider);
}
if (shouldUpdatePaymentMethod) {
const matchingOption = paymentMethods.find(
method => method.value === preselectedPaymentMethod,
);
setValue(
TRADING_FORM_PAYMENT_METHOD_SELECT,
matchingOption ?? {
value: preselectedPaymentMethod,
label: preselectedQuote.paymentMethodName ?? preselectedPaymentMethod,
},
);
}
}, [paymentMethod, paymentMethods, preselectedQuote, provider, setValue, dispatch]);
useEffect(() => {
dispatch(tradingThunks.loadInitialDataThunk({ activeSection: type }));
}, [dispatch]);

View File

@@ -68,6 +68,7 @@ export const useTradingBuyFormDefaultValues = (
cryptoSelect: defaultCrypto,
countrySelect: defaultCountry,
paymentMethod: defaultPaymentMethod,
provider: undefined,
amountInCrypto: false,
receiveAddress: undefined,
}),

View File

@@ -1,7 +1,8 @@
import { Control, Controller } from 'react-hook-form';
import { Control, Controller, UseFormSetValue } from 'react-hook-form';
import {
TRADING_FORM_PAYMENT_METHOD_SELECT,
TRADING_FORM_PROVIDER_SELECT,
type TradingPaymentMethodListProps,
} from '@suite-common/trading';
import { Select } from '@trezor/components';
@@ -25,8 +26,10 @@ export const TradingFormInputPaymentMethod = ({ label }: TradingFormInputDefault
state: { isFormLoading, isFormInvalid },
},
getValues,
setValue,
type,
} = useTradingFormContext<TradingTradeBuySellType>();
const setValueTyped = setValue as UseFormSetValue<TradingBuySellFormProps>;
const amountIsEmpty =
type === 'buy'
@@ -49,7 +52,10 @@ export const TradingFormInputPaymentMethod = ({ label }: TradingFormInputDefault
render={({ field: { onChange, value } }) => (
<Select
value={value}
onChange={onChange}
onChange={selected => {
setValueTyped(TRADING_FORM_PROVIDER_SELECT, undefined);
onChange(selected);
}}
options={paymentMethods}
labelLeft={label && <Translation id={label} />}
formatOptionLabel={(option: TradingPaymentMethodListProps) =>

View File

@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';
import { BuyTrade, CryptoId, ExchangeTrade } from 'invity-api';
import { BuyTrade, CryptoId, ExchangeTrade, SellFiatTrade } from 'invity-api';
import { ExperimentId } from '@suite-common/message-system';
import {
@@ -54,17 +54,45 @@ import { useIsContentBelowBreakpoint } from '../../../../../support/suite/Conten
import { useReceiveAddressModalControls } from '../TradingSelectedOffer/TradingReceiveAddress/useReceiveAddressModalControls';
import { TradingUtilsTorWarning } from '../TradingUtils/TradingUtilsTorWarning';
export const getSelectedQuote = (
context: TradingFormContextValues<TradingType>,
bestScoredQuote: TradingTradeType | undefined,
) => {
const getQuotesFilteredByProvider = (quotes: TradingTradeType[], provider: string | undefined) =>
quotes?.filter(quote => (provider ? quote.exchange === provider : true));
const getQuotesFilteredByProviderAndPaymentMethod = (
quotes: BuyTrade[] | SellFiatTrade[],
provider: string | undefined,
paymentMethod: string | undefined,
) =>
getQuotesFilteredByProvider(quotes, provider).filter(quote =>
paymentMethod ? (quote as BuyTrade | SellFiatTrade).paymentMethod === paymentMethod : true,
);
export const getSelectedQuote = (context: TradingFormContextValues<TradingType>) => {
const { provider } = context.getValues();
console.warn('provider', provider);
if (!isTradingExchangeContext(context)) {
return bestScoredQuote;
const { paymentMethod } = context.getValues();
console.warn('paymentMethod', paymentMethod);
const q = getQuotesFilteredByProviderAndPaymentMethod(
context.quotes,
provider,
paymentMethod?.value,
)?.[0];
console.warn('selected quote', q);
return q;
}
const isDex = context.getValues(TRADING_EXCHANGE_FORM) === TRADING_EXCHANGE_FORM_DEX;
const quotesFilteredByProvider = getQuotesFilteredByProvider(context.quotes, provider);
const bestScoredQuote = quotesFilteredByProvider?.[0];
const selectedQuote = isDex ? context.dexQuotes?.[0] : context.cexQuotes?.[0];
const selectedQuote = isDex
? getQuotesFilteredByProvider(context.dexQuotes, provider)?.[0]
: getQuotesFilteredByProvider(context.cexQuotes, provider)?.[0];
return selectedQuote ?? bestScoredQuote;
};
@@ -101,7 +129,7 @@ export const TradingFormOffer = () => {
const bestScoredQuote = quotes?.[0];
const { preselectedQuote } = context;
const quote = preselectedQuote ?? getSelectedQuote(context, bestScoredQuote);
const quote = preselectedQuote ?? getSelectedQuote(context);
const bestScoredQuoteAmounts = getCryptoQuoteAmountProps(quote, context);
const areFeesLoading = useSelector(state => selectAreFeesLoading(state, account.symbol));
const isDiscoveryRunning = useSelector(selectHasRunningDiscovery);

View File

@@ -30,11 +30,10 @@ export const TradingReceiveAddressEmpty = ({ title, text }: TradingReceiveAddres
export const TradingSelectedOfferProvider = () => {
const context = useTradingFormContext();
const { quotes, preselectedQuote, isAmountEmpty, form, type, goToOffers } = context;
const { preselectedQuote, isAmountEmpty, form, type, goToOffers } = context;
const providers = getProvidersInfoProps(context);
const bestScoredQuote = quotes?.[0];
const quote = preselectedQuote ?? getSelectedQuote(context, bestScoredQuote);
const quote = preselectedQuote ?? getSelectedQuote(context);
const onGoToOffers = async () => {
await goToOffers();

View File

@@ -40,6 +40,7 @@ export const TRADING_FORM_CRYPTO_INPUT = 'cryptoInput';
export const TRADING_FORM_CRYPTO_CURRENCY_SELECT = 'cryptoSelect';
export const TRADING_FORM_COUNTRY_SELECT = 'countrySelect';
export const TRADING_FORM_PAYMENT_METHOD_SELECT = 'paymentMethod';
export const TRADING_FORM_PROVIDER_SELECT = 'provider';
export const TRADING_FORM_AMOUNT_IN_CRYPTO = 'amountInCrypto';
export const TRADING_EXCHANGE_FROM_ADDRESS = 'fromAddress';

View File

@@ -136,6 +136,7 @@ export type TradingBuyFormProps = {
[constants.TRADING_FORM_CRYPTO_CURRENCY_SELECT]: TradingAssetOption;
[constants.TRADING_FORM_COUNTRY_SELECT]: TradingCountryOption;
[constants.TRADING_FORM_PAYMENT_METHOD_SELECT]?: TradingPaymentMethodListProps;
[constants.TRADING_FORM_PROVIDER_SELECT]?: string;
[constants.TRADING_FORM_AMOUNT_IN_CRYPTO]: boolean;
[constants.TRADING_BUY_RECEIVE_ADDRESS]?: string;
};
@@ -209,6 +210,7 @@ export interface TradingExchangeFormProps extends FormState {
[constants.TRADING_EXCHANGE_FROM_ADDRESS]?: string | undefined;
[constants.TRADING_EXCHANGE_RECEIVE_ADDRESS]?: string | undefined;
[constants.TRADING_EXCHANGE_EXTRA_FIELD]?: string | undefined;
[constants.TRADING_FORM_PROVIDER_SELECT]?: string;
}
export type MinimalExchangeFormProps = {
@@ -255,6 +257,7 @@ export interface TradingSellFormProps extends FormState {
[constants.TRADING_FORM_PAYMENT_METHOD_SELECT]?: TradingPaymentMethodListProps;
[constants.TRADING_FORM_COUNTRY_SELECT]: TradingCountryOption;
[constants.TRADING_FORM_AMOUNT_IN_CRYPTO]: boolean;
[constants.TRADING_FORM_PROVIDER_SELECT]?: string;
}
export type MinimalSellFormProps = {