From fc2f8366b58e1eedc4e18347f8aa2255cdecad7b Mon Sep 17 00:00:00 2001 From: Anxo Rodriguez Date: Wed, 6 Nov 2024 18:11:08 +0000 Subject: [PATCH 1/3] feat: allow to use same tokens for hooks --- .../containers/AdvancedOrdersWidget/index.tsx | 3 ++- .../hooks/useAdvancedOrdersActions.ts | 12 +++++----- .../containers/HooksStoreWidget/index.tsx | 4 ++-- .../hooks/useSetRecipientOverride.ts | 4 ++-- .../hooks/useLimitOrdersWidgetActions.ts | 10 ++++----- .../containers/LimitOrdersWidget/index.tsx | 3 ++- .../EthFlow/hooks/useEthFlowActions.ts | 4 ++-- .../modules/swap/containers/EthFlow/index.tsx | 22 +++++++++++-------- .../swap/containers/SwapUpdaters/index.tsx | 4 ++-- .../swap/containers/SwapWidget/index.tsx | 8 +++++-- .../swap/hooks/useSetupSwapAmountsFromUrl.ts | 4 ++-- .../swap/hooks/useSwapButtonContext.ts | 8 +++++-- .../src/modules/swap/hooks/useSwapState.tsx | 4 ++-- .../updaters/SwapAmountsFromUrlUpdater.tsx | 4 ++-- .../TradeWidget/TradeWidgetForm.tsx | 2 +- .../TradeWidget/TradeWidgetUpdaters.tsx | 4 +++- .../trade/containers/TradeWidget/index.tsx | 4 +++- .../trade/containers/TradeWidget/types.ts | 1 + .../setupTradeState/useSetupTradeState.ts | 9 ++++---- .../hooks/useNavigateOnCurrencySelection.ts | 8 +++++-- .../trade/hooks/useOnCurrencySelection.ts | 10 ++++++--- .../trade/updaters/CommonTradeUpdater.tsx | 4 ++-- .../yield/containers/YieldWidget/index.tsx | 2 ++ .../yield/hooks/useYieldWidgetActions.ts | 2 +- .../src/pages/Hooks/index.tsx | 2 +- .../cowswap-frontend/src/pages/Swap/index.tsx | 3 +-- 26 files changed, 87 insertions(+), 58 deletions(-) diff --git a/apps/cowswap-frontend/src/modules/advancedOrders/containers/AdvancedOrdersWidget/index.tsx b/apps/cowswap-frontend/src/modules/advancedOrders/containers/AdvancedOrdersWidget/index.tsx index 19f1c6c246..5cae007bd8 100644 --- a/apps/cowswap-frontend/src/modules/advancedOrders/containers/AdvancedOrdersWidget/index.tsx +++ b/apps/cowswap-frontend/src/modules/advancedOrders/containers/AdvancedOrdersWidget/index.tsx @@ -68,7 +68,7 @@ export function AdvancedOrdersWidget({ orderKind, isUnlocked, } = useAdvancedOrdersDerivedState() - const actions = useAdvancedOrdersActions() + const actions = useAdvancedOrdersActions({ allowSameToken: false }) const { isLoading: isTradePriceUpdating } = useTradeQuote() const { showRecipient } = useAtomValue(advancedOrdersSettingsAtom) const priceImpact = useTradePriceImpact() @@ -124,6 +124,7 @@ export function AdvancedOrdersWidget({ isTradePriceUpdating, priceImpact, disablePriceImpact, + allowSameToken: false, } return ( diff --git a/apps/cowswap-frontend/src/modules/advancedOrders/hooks/useAdvancedOrdersActions.ts b/apps/cowswap-frontend/src/modules/advancedOrders/hooks/useAdvancedOrdersActions.ts index f948b91b22..82254435c1 100644 --- a/apps/cowswap-frontend/src/modules/advancedOrders/hooks/useAdvancedOrdersActions.ts +++ b/apps/cowswap-frontend/src/modules/advancedOrders/hooks/useAdvancedOrdersActions.ts @@ -12,10 +12,10 @@ import { useAdvancedOrdersDerivedState } from './useAdvancedOrdersDerivedState' import { useUpdateAdvancedOrdersRawState } from './useAdvancedOrdersRawState' // TODO: this should be also unified for each trade widget (swap, limit, advanced) -export function useAdvancedOrdersActions() { +export function useAdvancedOrdersActions({ allowSameToken }: { allowSameToken: boolean }) { const { inputCurrency } = useAdvancedOrdersDerivedState() - const naviageOnCurrencySelection = useNavigateOnCurrencySelection() + const naviageOnCurrencySelection = useNavigateOnCurrencySelection({ allowSameToken }) const updateCurrencyAmount = useUpdateCurrencyAmount() const resetTradeQuote = useResetTradeQuote() @@ -33,7 +33,7 @@ export function useAdvancedOrdersActions() { naviageOnCurrencySelection(field, currency) resetTradeQuote() }, - [naviageOnCurrencySelection, updateCurrencyAmount, resetTradeQuote] + [naviageOnCurrencySelection, updateCurrencyAmount, resetTradeQuote], ) const onUserInput = useCallback( @@ -45,14 +45,14 @@ export function useAdvancedOrdersActions() { field, }) }, - [inputCurrency, updateCurrencyAmount] + [inputCurrency, updateCurrencyAmount], ) const onChangeRecipient = useCallback( (recipient: string | null) => { updateAdvancedOrdersState({ recipient }) }, - [updateAdvancedOrdersState] + [updateAdvancedOrdersState], ) const onSwitchTokensDefault = useSwitchTokensPlaces({ @@ -71,6 +71,6 @@ export function useAdvancedOrdersActions() { onChangeRecipient, onSwitchTokens, }), - [onCurrencySelection, onUserInput, onChangeRecipient, onSwitchTokens] + [onCurrencySelection, onUserInput, onChangeRecipient, onSwitchTokens], ) } diff --git a/apps/cowswap-frontend/src/modules/hooksStore/containers/HooksStoreWidget/index.tsx b/apps/cowswap-frontend/src/modules/hooksStore/containers/HooksStoreWidget/index.tsx index c6217ef6d5..c09d74c1fb 100644 --- a/apps/cowswap-frontend/src/modules/hooksStore/containers/HooksStoreWidget/index.tsx +++ b/apps/cowswap-frontend/src/modules/hooksStore/containers/HooksStoreWidget/index.tsx @@ -66,7 +66,7 @@ export function HooksStoreWidget() { }, [chainId, isChainIdUnsupported, onDismiss]) useSetupHooksStoreOrderParams() - useSetRecipientOverride() + useSetRecipientOverride({ allowSameToken: true }) const isHookSelectionOpen = !!(selectedHookPosition || hookToEdit) const hideSwapWidget = isHookSelectionOpen || isRescueWidgetOpen @@ -114,7 +114,7 @@ export function HooksStoreWidget() { return ( <> - + {isHookSelectionOpen && ( diff --git a/apps/cowswap-frontend/src/modules/hooksStore/hooks/useSetRecipientOverride.ts b/apps/cowswap-frontend/src/modules/hooksStore/hooks/useSetRecipientOverride.ts index 2df029bc11..b012051444 100644 --- a/apps/cowswap-frontend/src/modules/hooksStore/hooks/useSetRecipientOverride.ts +++ b/apps/cowswap-frontend/src/modules/hooksStore/hooks/useSetRecipientOverride.ts @@ -5,8 +5,8 @@ import { useIsHooksTradeType, useIsNativeIn } from 'modules/trade' import { usePostHooksRecipientOverride } from './usePostHooksRecipientOverride' -export function useSetRecipientOverride() { - const { onChangeRecipient } = useSwapActionHandlers() +export function useSetRecipientOverride({ allowSameToken }: { allowSameToken: boolean }): void { + const { onChangeRecipient } = useSwapActionHandlers({ allowSameToken }) const hookRecipientOverride = usePostHooksRecipientOverride() const isHooksTradeType = useIsHooksTradeType() const isNativeIn = useIsNativeIn() diff --git a/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWidget/hooks/useLimitOrdersWidgetActions.ts b/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWidget/hooks/useLimitOrdersWidgetActions.ts index 7216681236..e26b119ee2 100644 --- a/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWidget/hooks/useLimitOrdersWidgetActions.ts +++ b/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWidget/hooks/useLimitOrdersWidgetActions.ts @@ -16,7 +16,7 @@ import { useIsWrapOrUnwrap } from 'modules/trade/hooks/useIsWrapOrUnwrap' import { useOnCurrencySelection } from 'modules/trade/hooks/useOnCurrencySelection' import { useSwitchTokensPlaces } from 'modules/trade/hooks/useSwitchTokensPlaces' -export function useLimitOrdersWidgetActions(): TradeWidgetActions { +export function useLimitOrdersWidgetActions({ allowSameToken }: { allowSameToken: boolean }): TradeWidgetActions { const { inputCurrency, outputCurrency, orderKind } = useLimitOrdersDerivedState() const { activeRate } = useAtomValue(limitRateAtom) const isWrapOrUnwrap = useIsWrapOrUnwrap() @@ -24,7 +24,7 @@ export function useLimitOrdersWidgetActions(): TradeWidgetActions { const updateLimitOrdersState = useUpdateLimitOrdersRawState() - const onCurrencySelection = useOnCurrencySelection() + const onCurrencySelection = useOnCurrencySelection({ allowSameToken }) const onUserInput = useCallback( (field: Field, typedValue: string) => { @@ -42,7 +42,7 @@ export function useLimitOrdersWidgetActions(): TradeWidgetActions { orderKind: isWrapOrUnwrap || field === Field.INPUT ? OrderKind.SELL : OrderKind.BUY, }) }, - [updateCurrencyAmount, isWrapOrUnwrap, inputCurrency, outputCurrency, activeRate] + [updateCurrencyAmount, isWrapOrUnwrap, inputCurrency, outputCurrency, activeRate], ) const onSwitchTokens = useSwitchTokensPlaces({ @@ -51,11 +51,11 @@ export function useLimitOrdersWidgetActions(): TradeWidgetActions { const onChangeRecipient = useCallback( (recipient: string | null) => updateLimitOrdersState({ recipient }), - [updateLimitOrdersState] + [updateLimitOrdersState], ) return useMemo( () => ({ onUserInput, onSwitchTokens, onChangeRecipient, onCurrencySelection }), - [onUserInput, onSwitchTokens, onChangeRecipient, onCurrencySelection] + [onUserInput, onSwitchTokens, onChangeRecipient, onCurrencySelection], ) } diff --git a/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWidget/index.tsx b/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWidget/index.tsx index a2420948e3..7c6aab3fcd 100644 --- a/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWidget/index.tsx +++ b/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWidget/index.tsx @@ -75,7 +75,7 @@ export function LimitOrdersWidget() { const { feeAmount } = useAtomValue(limitRateAtom) const { isLoading: isRateLoading } = useTradeQuote() const rateInfoParams = useRateInfoParams(inputCurrencyAmount, outputCurrencyAmount) - const widgetActions = useLimitOrdersWidgetActions() + const widgetActions = useLimitOrdersWidgetActions({ allowSameToken: false }) const isWrapOrUnwrap = useIsWrapOrUnwrap() const { showRecipient: showRecipientSetting } = settingsState @@ -228,6 +228,7 @@ const LimitOrders = React.memo((props: LimitOrdersProps) => { disablePriceImpact: localFormValidation === LimitOrdersFormState.FeeExceedsFrom, disableQuotePolling: isConfirmOpen, hideTradeWarnings: !!localFormValidation, + allowSameToken: false, } return ( diff --git a/apps/cowswap-frontend/src/modules/swap/containers/EthFlow/hooks/useEthFlowActions.ts b/apps/cowswap-frontend/src/modules/swap/containers/EthFlow/hooks/useEthFlowActions.ts index 8dab67db7a..e1ad3ac3ba 100644 --- a/apps/cowswap-frontend/src/modules/swap/containers/EthFlow/hooks/useEthFlowActions.ts +++ b/apps/cowswap-frontend/src/modules/swap/containers/EthFlow/hooks/useEthFlowActions.ts @@ -30,13 +30,13 @@ export interface EthFlowActions { directSwap(): void } -export function useEthFlowActions(callbacks: EthFlowActionCallbacks): EthFlowActions { +export function useEthFlowActions(callbacks: EthFlowActionCallbacks, allowSameToken: boolean): EthFlowActions { const { chainId } = useWalletInfo() const { trade } = useDerivedSwapInfo() const updateEthFlowContext = useSetAtom(updateEthFlowContextAtom) - const { onCurrencySelection } = useSwapActionHandlers() + const { onCurrencySelection } = useSwapActionHandlers({ allowSameToken }) const { onOpen: openSwapConfirmModal } = useTradeConfirmActions() return useMemo(() => { diff --git a/apps/cowswap-frontend/src/modules/swap/containers/EthFlow/index.tsx b/apps/cowswap-frontend/src/modules/swap/containers/EthFlow/index.tsx index a8b9760bd0..e662533465 100644 --- a/apps/cowswap-frontend/src/modules/swap/containers/EthFlow/index.tsx +++ b/apps/cowswap-frontend/src/modules/swap/containers/EthFlow/index.tsx @@ -25,13 +25,13 @@ import { useEthFlowActions } from './hooks/useEthFlowActions' import useRemainingNativeTxsAndCosts from './hooks/useRemainingNativeTxsAndCosts' import { useSetupEthFlow } from './hooks/useSetupEthFlow' - export interface EthFlowProps { nativeInput?: CurrencyAmount hasEnoughWrappedBalanceForSwap: boolean wrapCallback: WrapUnwrapCallback | null directSwapCallback: HandleSwapCallback onDismiss: Command + allowSameToken: boolean } export function EthFlowModal({ @@ -40,6 +40,7 @@ export function EthFlowModal({ wrapCallback, directSwapCallback, hasEnoughWrappedBalanceForSwap, + allowSameToken, }: EthFlowProps) { const { chainId } = useWalletInfo() const native = useNativeCurrency() @@ -48,14 +49,17 @@ export function EthFlowModal({ const ethFlowContext = useAtomValue(ethFlowContextAtom) const approveCallback = useTradeApproveCallback( - (nativeInput && currencyAmountToTokenAmount(nativeInput)) || undefined + (nativeInput && currencyAmountToTokenAmount(nativeInput)) || undefined, + ) + const ethFlowActions = useEthFlowActions( + { + wrap: wrapCallback, + approve: approveCallback, + dismiss: onDismiss, + directSwap: directSwapCallback, + }, + allowSameToken, ) - const ethFlowActions = useEthFlowActions({ - wrap: wrapCallback, - approve: approveCallback, - dismiss: onDismiss, - directSwap: directSwapCallback, - }) const approveActivity = useSingleActivityDescriptor({ chainId, id: ethFlowContext.approve.txHash || undefined }) const wrapActivity = useSingleActivityDescriptor({ chainId, id: ethFlowContext.wrap.txHash || undefined }) @@ -86,7 +90,7 @@ export function EthFlowModal({ approvalState, approveActivity, wrapActivity, - onDismiss + onDismiss, }) return ( diff --git a/apps/cowswap-frontend/src/modules/swap/containers/SwapUpdaters/index.tsx b/apps/cowswap-frontend/src/modules/swap/containers/SwapUpdaters/index.tsx index 3e3a8fcd8e..13d51d236d 100644 --- a/apps/cowswap-frontend/src/modules/swap/containers/SwapUpdaters/index.tsx +++ b/apps/cowswap-frontend/src/modules/swap/containers/SwapUpdaters/index.tsx @@ -6,7 +6,7 @@ import { useTradeSlippage, useIsSmartSlippageApplied } from 'modules/tradeSlippa import { SwapAmountsFromUrlUpdater } from '../../updaters/SwapAmountsFromUrlUpdater' import { SwapDerivedStateUpdater } from '../../updaters/SwapDerivedStateUpdater' -export function SwapUpdaters() { +export function SwapUpdaters({ allowSameToken }: { allowSameToken: boolean }) { const slippage = useTradeSlippage() const isSmartSlippageApplied = useIsSmartSlippageApplied() @@ -18,7 +18,7 @@ export function SwapUpdaters() { isSmartSlippage={isSmartSlippageApplied} /> - + ) } diff --git a/apps/cowswap-frontend/src/modules/swap/containers/SwapWidget/index.tsx b/apps/cowswap-frontend/src/modules/swap/containers/SwapWidget/index.tsx index d5c0f61f5c..a2cf59de7a 100644 --- a/apps/cowswap-frontend/src/modules/swap/containers/SwapWidget/index.tsx +++ b/apps/cowswap-frontend/src/modules/swap/containers/SwapWidget/index.tsx @@ -54,16 +54,17 @@ import { ConfirmSwapModalSetup } from '../ConfirmSwapModalSetup' export interface SwapWidgetProps { topContent?: ReactNode bottomContent?: ReactNode + allowSameToken?: boolean } -export function SwapWidget({ topContent, bottomContent }: SwapWidgetProps) { +export function SwapWidget({ topContent, bottomContent, allowSameToken = false }: SwapWidgetProps) { const { chainId } = useWalletInfo() const { currencies, trade } = useDerivedSwapInfo() const slippage = useTradeSlippage() const parsedAmounts = useSwapCurrenciesAmounts() const { isSupportedWallet } = useWalletDetails() const isSwapUnsupported = useIsTradeUnsupported(currencies.INPUT, currencies.OUTPUT) - const swapActions = useSwapActionHandlers() + const swapActions = useSwapActionHandlers({ allowSameToken }) const swapState = useSwapState() const { independentField, recipient } = swapState const showRecipientControls = useShowRecipientControls(recipient) @@ -169,6 +170,7 @@ export function SwapWidget({ topContent, bottomContent }: SwapWidgetProps) { openNativeWrapModal, }, swapActions, + allowSameToken, ) const tradeUrlParams = useTradeRouteContext() @@ -181,6 +183,7 @@ export function SwapWidget({ topContent, bottomContent }: SwapWidgetProps) { wrapCallback: swapButtonContext.onWrapOrUnwrap, directSwapCallback: swapButtonContext.handleSwap, hasEnoughWrappedBalanceForSwap: swapButtonContext.hasEnoughWrappedBalanceForSwap, + allowSameToken, } const swapModalsProps: SwapModalsProps = { @@ -255,6 +258,7 @@ export function SwapWidget({ topContent, bottomContent }: SwapWidgetProps) { priceImpact: priceImpactParams, disableQuotePolling: true, tradeQuoteStateOverride, + allowSameToken, } useSetLocalTimeOffset(getQuoteTimeOffset(swapButtonContext.quoteDeadlineParams)) diff --git a/apps/cowswap-frontend/src/modules/swap/hooks/useSetupSwapAmountsFromUrl.ts b/apps/cowswap-frontend/src/modules/swap/hooks/useSetupSwapAmountsFromUrl.ts index d516fe124b..3c69ff91bb 100644 --- a/apps/cowswap-frontend/src/modules/swap/hooks/useSetupSwapAmountsFromUrl.ts +++ b/apps/cowswap-frontend/src/modules/swap/hooks/useSetupSwapAmountsFromUrl.ts @@ -25,11 +25,11 @@ import { useSwapActionHandlers } from './useSwapState' * * In case when both sellAmount and buyAmount specified, buyAmount will be ignored */ -export function useSetupSwapAmountsFromUrl() { +export function useSetupSwapAmountsFromUrl({ allowSameToken }: { allowSameToken: boolean }): void { const { search, pathname } = useLocation() const navigate = useNavigate() const params = useMemo(() => new URLSearchParams(search), [search]) - const { onUserInput } = useSwapActionHandlers() + const { onUserInput } = useSwapActionHandlers({ allowSameToken }) const cleanParams = useCallback(() => { const queryParams = new URLSearchParams(search) diff --git a/apps/cowswap-frontend/src/modules/swap/hooks/useSwapButtonContext.ts b/apps/cowswap-frontend/src/modules/swap/hooks/useSwapButtonContext.ts index 933a0b6c14..5bd7c96a60 100644 --- a/apps/cowswap-frontend/src/modules/swap/hooks/useSwapButtonContext.ts +++ b/apps/cowswap-frontend/src/modules/swap/hooks/useSwapButtonContext.ts @@ -38,7 +38,11 @@ export interface SwapButtonInput { openNativeWrapModal(): void } -export function useSwapButtonContext(input: SwapButtonInput, actions: TradeWidgetActions): SwapButtonsContext { +export function useSwapButtonContext( + input: SwapButtonInput, + actions: TradeWidgetActions, + allowSameToken: boolean, +): SwapButtonsContext { const { feeWarningAccepted, impactWarningAccepted, openNativeWrapModal } = input const { account, chainId } = useWalletInfo() @@ -52,7 +56,7 @@ export function useSwapButtonContext(input: SwapButtonInput, actions: TradeWidge inputError: swapInputError, } = useDerivedSwapInfo() const toggleWalletModal = useToggleWalletModal() - const { onCurrencySelection } = useSwapActionHandlers() + const { onCurrencySelection } = useSwapActionHandlers({ allowSameToken }) const isBestQuoteLoading = useIsBestQuoteLoading() const tradeConfirmActions = useTradeConfirmActions() const { standaloneMode } = useInjectedWidgetParams() diff --git a/apps/cowswap-frontend/src/modules/swap/hooks/useSwapState.tsx b/apps/cowswap-frontend/src/modules/swap/hooks/useSwapState.tsx index 4953671631..ddf813675c 100644 --- a/apps/cowswap-frontend/src/modules/swap/hooks/useSwapState.tsx +++ b/apps/cowswap-frontend/src/modules/swap/hooks/useSwapState.tsx @@ -60,10 +60,10 @@ interface DerivedSwapInfo { trade: TradeGp | undefined } -export function useSwapActionHandlers(): TradeWidgetActions { +export function useSwapActionHandlers({ allowSameToken }: { allowSameToken: boolean }): TradeWidgetActions { const { chainId } = useWalletInfo() const dispatch = useAppDispatch() - const onCurrencySelection = useNavigateOnCurrencySelection() + const onCurrencySelection = useNavigateOnCurrencySelection({ allowSameToken }) const navigate = useTradeNavigate() const swapState = useSwapState() diff --git a/apps/cowswap-frontend/src/modules/swap/updaters/SwapAmountsFromUrlUpdater.tsx b/apps/cowswap-frontend/src/modules/swap/updaters/SwapAmountsFromUrlUpdater.tsx index e1c21f2cb1..a629351ee4 100644 --- a/apps/cowswap-frontend/src/modules/swap/updaters/SwapAmountsFromUrlUpdater.tsx +++ b/apps/cowswap-frontend/src/modules/swap/updaters/SwapAmountsFromUrlUpdater.tsx @@ -1,6 +1,6 @@ import { useSetupSwapAmountsFromUrl } from '../hooks/useSetupSwapAmountsFromUrl' -export function SwapAmountsFromUrlUpdater() { - useSetupSwapAmountsFromUrl() +export function SwapAmountsFromUrlUpdater({ allowSameToken }: { allowSameToken: boolean }) { + useSetupSwapAmountsFromUrl({ allowSameToken }) return null } diff --git a/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx b/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx index 6866a903ba..b296713c8f 100644 --- a/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx +++ b/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx @@ -52,7 +52,7 @@ export function TradeWidgetForm(props: TradeWidgetProps) { const { pendingActivity } = useCategorizeRecentActivity() const isWrapOrUnwrap = useIsWrapOrUnwrap() - const { slots, actions, params, disableOutput } = props + const { slots, actions, params, disableOutput, allowSameToken } = props const { settingsWidget, lockScreen, topContent, middleContent, bottomContent, outerContent } = slots const { onCurrencySelection, onUserInput, onSwitchTokens, onChangeRecipient } = actions diff --git a/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetUpdaters.tsx b/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetUpdaters.tsx index ae2243872b..49dadd718d 100644 --- a/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetUpdaters.tsx +++ b/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetUpdaters.tsx @@ -21,6 +21,7 @@ interface TradeWidgetUpdatersProps { children: ReactNode tradeQuoteStateOverride?: TradeQuoteState | null onChangeRecipient: (recipient: string | null) => void + allowSameToken: boolean } export function TradeWidgetUpdaters({ @@ -30,6 +31,7 @@ export function TradeWidgetUpdaters({ enableSmartSlippage, onChangeRecipient, children, + allowSameToken, }: TradeWidgetUpdatersProps) { const { chainId, account } = useWalletInfo() const updateQuoteState = useUpdateTradeQuote() @@ -51,7 +53,7 @@ export function TradeWidgetUpdaters({ {!disableQuotePolling && } - + {enableSmartSlippage && } {disableNativeSelling && } {children} diff --git a/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/index.tsx b/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/index.tsx index 743505a670..701a8d8232 100644 --- a/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/index.tsx +++ b/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/index.tsx @@ -13,8 +13,9 @@ export function TradeWidget(props: TradeWidgetProps) { disableNativeSelling = false, tradeQuoteStateOverride, enableSmartSlippage, + allowSameToken, } = params - const modals = TradeWidgetModals({confirmModal, genericModal, selectTokenWidget: slots.selectTokenWidget}) + const modals = TradeWidgetModals({ confirmModal, genericModal, selectTokenWidget: slots.selectTokenWidget }) return ( <> @@ -25,6 +26,7 @@ export function TradeWidget(props: TradeWidgetProps) { tradeQuoteStateOverride={tradeQuoteStateOverride} enableSmartSlippage={enableSmartSlippage} onChangeRecipient={props.actions.onChangeRecipient} + allowSameToken={allowSameToken} > {slots.updaters} diff --git a/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/types.ts b/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/types.ts index 0cf4606b84..377351dab0 100644 --- a/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/types.ts +++ b/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/types.ts @@ -31,6 +31,7 @@ interface TradeWidgetParams { isMarketOrderWidget?: boolean displayTokenName?: boolean customSelectTokenButton?: ReactNode + allowSameToken: boolean } export interface TradeWidgetSlots { diff --git a/apps/cowswap-frontend/src/modules/trade/hooks/setupTradeState/useSetupTradeState.ts b/apps/cowswap-frontend/src/modules/trade/hooks/setupTradeState/useSetupTradeState.ts index 97bbd1cece..5c272f05b2 100644 --- a/apps/cowswap-frontend/src/modules/trade/hooks/setupTradeState/useSetupTradeState.ts +++ b/apps/cowswap-frontend/src/modules/trade/hooks/setupTradeState/useSetupTradeState.ts @@ -19,7 +19,7 @@ import { useTradeState } from '../useTradeState' const INITIAL_CHAIN_ID_FROM_URL = getRawCurrentChainIdFromUrl() const EMPTY_TOKEN_ID = '_' -export function useSetupTradeState(): void { +export function useSetupTradeState({ allowSameToken }: { allowSameToken: boolean }): void { useSetupTradeStateFromUrl() const { chainId: providerChainId, account } = useWalletInfo() const prevProviderChainId = usePrevious(providerChainId) @@ -130,7 +130,8 @@ export function useSetupTradeState(): void { const tokensAreEmpty = !inputCurrencyId && !outputCurrencyId - const sameTokens = + const sameTokensError = + !allowSameToken && inputCurrencyId !== EMPTY_TOKEN_ID && (inputCurrencyId || outputCurrencyId) && inputCurrencyId?.toLowerCase() === outputCurrencyId?.toLowerCase() @@ -155,10 +156,10 @@ export function useSetupTradeState(): void { return } - if (sameTokens || tokensAreEmpty || onlyChainIdIsChanged) { + if (sameTokensError || tokensAreEmpty || onlyChainIdIsChanged) { tradeNavigate(currentChainId, defaultState) - if (sameTokens) { + if (sameTokensError) { console.debug('[TRADE STATE]', 'Url contains invalid tokens, resetting') } else if (tokensAreEmpty) { console.debug('[TRADE STATE]', 'Url does not contain both tokens, resetting') diff --git a/apps/cowswap-frontend/src/modules/trade/hooks/useNavigateOnCurrencySelection.ts b/apps/cowswap-frontend/src/modules/trade/hooks/useNavigateOnCurrencySelection.ts index 54d8edf293..1a4eff0feb 100644 --- a/apps/cowswap-frontend/src/modules/trade/hooks/useNavigateOnCurrencySelection.ts +++ b/apps/cowswap-frontend/src/modules/trade/hooks/useNavigateOnCurrencySelection.ts @@ -40,7 +40,11 @@ function useResolveCurrencyAddressOrSymbol(): (currency: Currency | null) => str * if there are more than one token with the same symbol * @see useResetStateWithSymbolDuplication.ts */ -export function useNavigateOnCurrencySelection(): CurrencySelectionCallback { +export function useNavigateOnCurrencySelection({ + allowSameToken, +}: { + allowSameToken: boolean +}): CurrencySelectionCallback { const { chainId } = useWalletInfo() const { state } = useTradeState() const navigate = useTradeNavigate() @@ -60,7 +64,7 @@ export function useNavigateOnCurrencySelection(): CurrencySelectionCallback { navigate( chainId, // Just invert tokens when user selected the same token - areCurrenciesTheSame + areCurrenciesTheSame && !allowSameToken ? { inputCurrencyId: outputCurrencyId, outputCurrencyId: inputCurrencyId } : { inputCurrencyId: targetInputCurrencyId, diff --git a/apps/cowswap-frontend/src/modules/trade/hooks/useOnCurrencySelection.ts b/apps/cowswap-frontend/src/modules/trade/hooks/useOnCurrencySelection.ts index c79764628b..ce9cfb3adf 100644 --- a/apps/cowswap-frontend/src/modules/trade/hooks/useOnCurrencySelection.ts +++ b/apps/cowswap-frontend/src/modules/trade/hooks/useOnCurrencySelection.ts @@ -11,9 +11,13 @@ import { useNavigateOnCurrencySelection } from 'modules/trade/hooks/useNavigateO import { convertAmountToCurrency } from 'utils/orderUtils/calculateExecutionPrice' -export function useOnCurrencySelection(): (field: Field, currency: Currency | null) => void { +export function useOnCurrencySelection({ + allowSameToken, +}: { + allowSameToken: boolean +}): (field: Field, currency: Currency | null) => void { const { inputCurrencyAmount, outputCurrencyAmount } = useLimitOrdersDerivedState() - const navigateOnCurrencySelection = useNavigateOnCurrencySelection() + const navigateOnCurrencySelection = useNavigateOnCurrencySelection({ allowSameToken }) const updateLimitOrdersState = useUpdateLimitOrdersRawState() return useCallback( @@ -44,6 +48,6 @@ export function useOnCurrencySelection(): (field: Field, currency: Currency | nu return navigateOnCurrencySelection(field, currency) }, - [navigateOnCurrencySelection, updateLimitOrdersState, inputCurrencyAmount, outputCurrencyAmount] + [navigateOnCurrencySelection, updateLimitOrdersState, inputCurrencyAmount, outputCurrencyAmount], ) } diff --git a/apps/cowswap-frontend/src/modules/trade/updaters/CommonTradeUpdater.tsx b/apps/cowswap-frontend/src/modules/trade/updaters/CommonTradeUpdater.tsx index 619354fc01..07a31464e2 100644 --- a/apps/cowswap-frontend/src/modules/trade/updaters/CommonTradeUpdater.tsx +++ b/apps/cowswap-frontend/src/modules/trade/updaters/CommonTradeUpdater.tsx @@ -2,8 +2,8 @@ import { useSetupTradeState } from '../hooks/setupTradeState/useSetupTradeState' import { useNotifyWidgetTrade } from '../hooks/useNotifyWidgetTrade' import { useSetupTradeTypeInfo } from '../hooks/useSetupTradeTypeInfo' -export function CommonTradeUpdater() { - useSetupTradeState() +export function CommonTradeUpdater(props: { allowSameToken: boolean }): null { + useSetupTradeState(props) useNotifyWidgetTrade() useSetupTradeTypeInfo() diff --git a/apps/cowswap-frontend/src/modules/yield/containers/YieldWidget/index.tsx b/apps/cowswap-frontend/src/modules/yield/containers/YieldWidget/index.tsx index 1888b6d921..a176e30e59 100644 --- a/apps/cowswap-frontend/src/modules/yield/containers/YieldWidget/index.tsx +++ b/apps/cowswap-frontend/src/modules/yield/containers/YieldWidget/index.tsx @@ -41,6 +41,7 @@ import { TargetPoolPreviewInfo } from '../../pure/TargetPoolPreviewInfo' import { TradeButtons } from '../TradeButtons' import { Warnings } from '../Warnings' import { YieldConfirmModal } from '../YieldConfirmModal' +import { a } from '@react-spring/web' const YIELD_BULLET_LIST_CONTENT: BulletListItem[] = [ { content: 'Maximize your yield on existing LP positions' }, @@ -206,6 +207,7 @@ export function YieldWidget() { priceImpact, disableQuotePolling: isConfirmOpen, customSelectTokenButton: SelectAPoolButton, + allowSameToken: false, } return ( diff --git a/apps/cowswap-frontend/src/modules/yield/hooks/useYieldWidgetActions.ts b/apps/cowswap-frontend/src/modules/yield/hooks/useYieldWidgetActions.ts index 0573c0504e..576a4dfaea 100644 --- a/apps/cowswap-frontend/src/modules/yield/hooks/useYieldWidgetActions.ts +++ b/apps/cowswap-frontend/src/modules/yield/hooks/useYieldWidgetActions.ts @@ -14,7 +14,7 @@ import { useYieldDerivedState } from './useYieldDerivedState' export function useYieldWidgetActions(): TradeWidgetActions { const { inputCurrency, outputCurrency, orderKind } = useYieldDerivedState() const updateYieldState = useUpdateYieldRawState() - const onCurrencySelection = useOnCurrencySelection() + const onCurrencySelection = useOnCurrencySelection({ allowSameToken: false }) const updateCurrencyAmount = useUpdateCurrencyAmount() const onUserInput = useCallback( diff --git a/apps/cowswap-frontend/src/pages/Hooks/index.tsx b/apps/cowswap-frontend/src/pages/Hooks/index.tsx index d2de1a0e85..602240ef3a 100644 --- a/apps/cowswap-frontend/src/pages/Hooks/index.tsx +++ b/apps/cowswap-frontend/src/pages/Hooks/index.tsx @@ -4,7 +4,7 @@ import { SwapUpdaters } from 'modules/swap' export function HooksPage() { return ( <> - + ) diff --git a/apps/cowswap-frontend/src/pages/Swap/index.tsx b/apps/cowswap-frontend/src/pages/Swap/index.tsx index d672663c10..784e0943eb 100644 --- a/apps/cowswap-frontend/src/pages/Swap/index.tsx +++ b/apps/cowswap-frontend/src/pages/Swap/index.tsx @@ -1,4 +1,3 @@ - import { WRAPPED_NATIVE_CURRENCIES as WETH } from '@cowprotocol/common-const' import { useWalletInfo } from '@cowprotocol/wallet' @@ -19,7 +18,7 @@ export function SwapPage() { return ( <> - + ) From 7cfb8e62c80d7a1b38ebb8ced5f05cab72270082 Mon Sep 17 00:00:00 2001 From: Anxo Rodriguez Date: Wed, 6 Nov 2024 18:31:18 +0000 Subject: [PATCH 2/3] feat: allow to quote with same sell as buy --- .../src/api/cowProtocol/api.ts | 21 +++++++++---------- .../legacy/hooks/useRefetchPriceCallback.tsx | 1 + .../src/legacy/utils/price.ts | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/cowswap-frontend/src/api/cowProtocol/api.ts b/apps/cowswap-frontend/src/api/cowProtocol/api.ts index 90ff5493cf..d2caae970b 100644 --- a/apps/cowswap-frontend/src/api/cowProtocol/api.ts +++ b/apps/cowswap-frontend/src/api/cowProtocol/api.ts @@ -37,7 +37,6 @@ import { ApiErrorCodes } from './errors/OperatorError' import QuoteApiError, { mapOperatorErrorToQuoteError, QuoteApiErrorDetails } from './errors/QuoteError' import { getIsOrderBookTypedError } from './getIsOrderBookTypedError' - function getProfileUrl(): Partial> { if (isLocal || isDev || isPr || isBarn) { return { @@ -157,16 +156,16 @@ function _getAppDataQuoteParams(params: FeeQuoteParams) { export async function getQuote(params: FeeQuoteParams): Promise { const { chainId } = params const quoteParams = _mapNewToLegacyParams(params) - const { sellToken, buyToken } = quoteParams - - if (sellToken === buyToken) { - return Promise.reject( - mapOperatorErrorToQuoteError({ - errorType: ApiErrorCodes.SameBuyAndSellToken, - description: QuoteApiErrorDetails.SameBuyAndSellToken, - }), - ) - } + // const { sellToken, buyToken } = quoteParams + + // if (sellToken === buyToken) { + // return Promise.reject( + // mapOperatorErrorToQuoteError({ + // errorType: ApiErrorCodes.SameBuyAndSellToken, + // description: QuoteApiErrorDetails.SameBuyAndSellToken, + // }), + // ) + // } return orderBookApi.getQuote(quoteParams, { chainId }).catch((error) => { if (getIsOrderBookTypedError(error)) { diff --git a/apps/cowswap-frontend/src/legacy/hooks/useRefetchPriceCallback.tsx b/apps/cowswap-frontend/src/legacy/hooks/useRefetchPriceCallback.tsx index 253f5dc137..68328fd39d 100644 --- a/apps/cowswap-frontend/src/legacy/hooks/useRefetchPriceCallback.tsx +++ b/apps/cowswap-frontend/src/legacy/hooks/useRefetchPriceCallback.tsx @@ -109,6 +109,7 @@ function handleQuoteError({ quoteData, error, addUnsupportedToken }: HandleQuote // Some other error getting the quote ocurred console.error('Error quoting price/fee: ' + error) + console.error(error) return 'fetch-quote-error' } } diff --git a/apps/cowswap-frontend/src/legacy/utils/price.ts b/apps/cowswap-frontend/src/legacy/utils/price.ts index 645ebcd241..04e5b8c4ef 100644 --- a/apps/cowswap-frontend/src/legacy/utils/price.ts +++ b/apps/cowswap-frontend/src/legacy/utils/price.ts @@ -44,7 +44,7 @@ export async function getBestQuote({ console.warn( '[GP PRICE::API] getBestQuote - error using COWSWAP price strategy, reason: [', err, - '] - trying back up price sources...' + '] - trying back up price sources...', ) // ATTEMPT LEGACY CALL return getBestQuote({ From cdefd25698449fc401a057aa0f79c6c6a4c6e987 Mon Sep 17 00:00:00 2001 From: Anxo Rodriguez Date: Thu, 7 Nov 2024 18:21:42 +0000 Subject: [PATCH 3/3] fix: fix compile errors --- .../limitOrders/containers/LimitOrdersWarnings/index.tsx | 2 +- .../trade/containers/SellNativeWarningBanner/index.tsx | 4 ++-- .../modules/trade/containers/TradeWidget/TradeWidgetForm.tsx | 2 +- .../src/modules/twap/containers/TwapFormWarnings/index.tsx | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWarnings/index.tsx b/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWarnings/index.tsx index ec34c608a1..ab16bfe047 100644 --- a/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWarnings/index.tsx +++ b/apps/cowswap-frontend/src/modules/limitOrders/containers/LimitOrdersWarnings/index.tsx @@ -99,7 +99,7 @@ export function LimitOrdersWarnings(props: LimitOrdersWarningsProps) { {/*// TODO: must be replaced by */} {showHighFeeWarning && } - {showNativeSellWarning && } + {showNativeSellWarning && } ) : null } diff --git a/apps/cowswap-frontend/src/modules/trade/containers/SellNativeWarningBanner/index.tsx b/apps/cowswap-frontend/src/modules/trade/containers/SellNativeWarningBanner/index.tsx index 02f7159640..f436eab883 100644 --- a/apps/cowswap-frontend/src/modules/trade/containers/SellNativeWarningBanner/index.tsx +++ b/apps/cowswap-frontend/src/modules/trade/containers/SellNativeWarningBanner/index.tsx @@ -9,10 +9,10 @@ import { useDerivedTradeState } from '../../hooks/useDerivedTradeState' import { useNavigateOnCurrencySelection } from '../../hooks/useNavigateOnCurrencySelection' import { useWrappedToken } from '../../hooks/useWrappedToken' -export function SellNativeWarningBanner() { +export function SellNativeWarningBanner({ allowSameToken }: { allowSameToken: boolean }) { const native = useNativeCurrency() const wrapped = useWrappedToken() - const navigateOnCurrencySelection = useNavigateOnCurrencySelection() + const navigateOnCurrencySelection = useNavigateOnCurrencySelection({ allowSameToken }) const state = useDerivedTradeState() diff --git a/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx b/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx index b296713c8f..6866a903ba 100644 --- a/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx +++ b/apps/cowswap-frontend/src/modules/trade/containers/TradeWidget/TradeWidgetForm.tsx @@ -52,7 +52,7 @@ export function TradeWidgetForm(props: TradeWidgetProps) { const { pendingActivity } = useCategorizeRecentActivity() const isWrapOrUnwrap = useIsWrapOrUnwrap() - const { slots, actions, params, disableOutput, allowSameToken } = props + const { slots, actions, params, disableOutput } = props const { settingsWidget, lockScreen, topContent, middleContent, bottomContent, outerContent } = slots const { onCurrencySelection, onUserInput, onSwitchTokens, onChangeRecipient } = actions diff --git a/apps/cowswap-frontend/src/modules/twap/containers/TwapFormWarnings/index.tsx b/apps/cowswap-frontend/src/modules/twap/containers/TwapFormWarnings/index.tsx index ec1f665172..fee47eb10f 100644 --- a/apps/cowswap-frontend/src/modules/twap/containers/TwapFormWarnings/index.tsx +++ b/apps/cowswap-frontend/src/modules/twap/containers/TwapFormWarnings/index.tsx @@ -79,7 +79,7 @@ export function TwapFormWarnings({ localFormValidation, isConfirmationModal }: T } if (primaryFormValidation === TradeFormValidation.SellNativeToken) { - return + return } if (localFormValidation === TwapFormState.SELL_AMOUNT_TOO_SMALL) {