diff --git a/src/pages/Swap/LimitOrder/Components/ConfirmLimitOrderModal/index.tsx b/src/pages/Swap/LimitOrder/Components/ConfirmLimitOrderModal/index.tsx index 79373b2ccb..5813870a20 100644 --- a/src/pages/Swap/LimitOrder/Components/ConfirmLimitOrderModal/index.tsx +++ b/src/pages/Swap/LimitOrder/Components/ConfirmLimitOrderModal/index.tsx @@ -33,8 +33,7 @@ export default function ConfirmLimitOrderModal({ fiatValueInput, fiatValueOutput, }: ConfirmLimitOrderModalProps) { - const { limitOrder, buyAmount, sellAmount, limitPrice, expiresAt, expiresAtUnit, kind } = - useContext(LimitOrderContext) + const { buyAmount, sellAmount, limitPrice, expiresAt, expiresAtUnit, kind } = useContext(LimitOrderContext) //hardcoded for now const market = 'CoW Protocol' @@ -54,7 +53,7 @@ export default function ConfirmLimitOrderModal({ const askPrice = `${kind} ${baseTokenAmount?.currency?.symbol} at ${limitPrice} ${quoteTokenAmount?.currency?.symbol}` let { marketPriceDiffPercentage, isDiffPositive } = calculateMarketPriceDiffPercentage( - limitOrder!.kind, + kind ?? Kind.Sell, marketPrices, limitPrice! ) diff --git a/src/pages/Swap/LimitOrder/Components/OrderLimitPriceField/OrderLimitPriceField.tsx b/src/pages/Swap/LimitOrder/Components/OrderLimitPriceField/OrderLimitPriceField.tsx index f3866f1da7..e9b0e10aa1 100644 --- a/src/pages/Swap/LimitOrder/Components/OrderLimitPriceField/OrderLimitPriceField.tsx +++ b/src/pages/Swap/LimitOrder/Components/OrderLimitPriceField/OrderLimitPriceField.tsx @@ -1,13 +1,13 @@ -import { formatUnits, parseUnits } from '@ethersproject/units' +import { parseUnits } from '@ethersproject/units' import { Currency, TokenAmount } from '@swapr/sdk' -import { Dispatch, SetStateAction, useCallback, useEffect, useState } from 'react' +import { Dispatch, SetStateAction, useEffect, useState } from 'react' import { RefreshCw } from 'react-feather' import { useTranslation } from 'react-i18next' import { Kind, LimitOrderBase, MarketPrices } from '../../../../../services/LimitOrders' import { InputGroup } from '../InputGroup' -import { calculateMarketPriceDiffPercentage } from '../utils' +// eslint-disable-next-line @typescript-eslint/no-unused-vars import { MarketPriceButton } from './MarketPriceButton' import { @@ -57,6 +57,7 @@ export interface OrderLimitPriceFieldProps { } export function OrderLimitPriceField({ + // eslint-disable-next-line @typescript-eslint/no-unused-vars marketPrices, fetchMarketPrice, setFetchMarketPrice, @@ -64,18 +65,19 @@ export function OrderLimitPriceField({ sellAmount, buyAmount, kind, + // eslint-disable-next-line @typescript-eslint/no-unused-vars limitOrder = {}, sellToken, buyToken, + // eslint-disable-next-line @typescript-eslint/no-unused-vars setSellAmount, + // eslint-disable-next-line @typescript-eslint/no-unused-vars setBuyAmount, setKind, }: OrderLimitPriceFieldProps) { const { t } = useTranslation('swap') - const [formattedLimitPrice, setFormattedLimitPrice] = useState(marketPrices.buy.toFixed(6)) - - const [{ baseToken, baseTokenAmount: _b, quoteToken, quoteTokenAmount: _q }, setBaseQuoteTokens] = useState( + const [{ baseToken, quoteToken }, setBaseQuoteTokens] = useState( getBaseQuoteTokens({ sellAmount, buyAmount, kind, sellToken, buyToken }) ) @@ -83,64 +85,40 @@ export function OrderLimitPriceField({ setBaseQuoteTokens(getBaseQuoteTokens({ sellAmount, buyAmount, kind, sellToken, buyToken })) }, [sellToken, buyToken, sellAmount, buyAmount, kind]) - const inputGroupLabel = `${kind} ${baseToken?.symbol} at` + const inputGroupLabel = `${kind} 1 ${baseToken?.symbol} at` const toggleCurrencyButtonLabel = `${quoteToken?.symbol}` + const [formattedLimitPrice, setFormattedLimitPrice] = useState(protocol.getTokenLimitPrices()) const [inputLimitPrice, setInputLimitPrice] = useState(formattedLimitPrice) + const [inputFocus, setInputFocus] = useState(false) - const { marketPriceDiffPercentage, isDiffPositive } = calculateMarketPriceDiffPercentage( - kind ?? Kind.Sell, - marketPrices, - formattedLimitPrice.toString() - ) + // const { marketPriceDiffPercentage, isDiffPositive } = calculateMarketPriceDiffPercentage( + // kind ?? Kind.Sell, + // marketPrices, + // formattedLimitPrice.toString() + // ) - const showPercentage = - Number(marketPriceDiffPercentage.toFixed(1)) !== 0 && Number(marketPriceDiffPercentage) !== -100 + // const showPercentage = + // Number(marketPriceDiffPercentage.toFixed(1)) !== 0 && Number(marketPriceDiffPercentage) !== -100 + // useEffect(() => { + // setInputLimitPrice(formattedLimitPrice) + // }, [formattedLimitPrice]) + const limitPrice = protocol.getTokenLimitPrices() useEffect(() => { - setInputLimitPrice(formattedLimitPrice) - }, [formattedLimitPrice]) - - /** - * Handle the base currency change. - */ - const toggleBaseCurrency = useCallback(() => { - // Toggle between buy and sell currency - const kindSelected = kind === Kind.Sell ? Kind.Buy : Kind.Sell - - if (!sellAmount || !buyAmount) return - - const [baseTokenAmount, quoteTokenAmount] = - kindSelected === Kind.Sell ? [sellAmount, buyAmount] : [buyAmount, sellAmount] - - const baseTokenAmountAsFloat = parseFloat( - formatUnits(baseTokenAmount.raw.toString(), baseTokenAmount.currency.decimals) - ) - const quoteTokenAmountAsFloat = parseFloat( - formatUnits(quoteTokenAmount.raw.toString(), quoteTokenAmount.currency.decimals) - ) - - const nextLimitPriceFloat = quoteTokenAmountAsFloat / baseTokenAmountAsFloat - const nextLimitPriceFormatted = nextLimitPriceFloat.toFixed(6) // 6 is the lowest precision we support due to tokens like USDC - //const nextLimitPriceWei = parseUnits(nextLimitPriceFormatted, quoteTokenAmount?.currency?.decimals).toString() - - setKind(kindSelected) - protocol.onLimitPriceChange(nextLimitPriceFormatted) - // protocol.onLimitOrderChange({ - // ...limitOrder, - // kind, - // limitPrice: nextLimitPriceFormatted, - // }) - // update the formatted limit price - setFormattedLimitPrice(nextLimitPriceFormatted) - setInputLimitPrice(nextLimitPriceFormatted) - }, [kind, sellAmount, buyAmount, setKind, protocol]) + setFormattedLimitPrice(limitPrice) + if (!inputFocus) { + setInputLimitPrice(limitPrice) + } + }, [inputFocus, limitPrice]) /** * Handle the limit price input change. Compute the buy amount and update the state. */ const onChangeHandler: React.ChangeEventHandler = event => { - const [_baseTokenAmount, quoteTokenAmount] = kind === Kind.Sell ? [sellAmount, buyAmount] : [buyAmount, sellAmount] + setInputFocus(true) + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const [baseTokenAmount, quoteTokenAmount] = kind === Kind.Sell ? [sellAmount, buyAmount] : [buyAmount, sellAmount] // Parse the limit price const nextLimitPriceFormatted = event.target.value // When the limit price is empty, set the limit price to 0 if (nextLimitPriceFormatted.split('.').length > 2) { @@ -159,7 +137,9 @@ export function OrderLimitPriceField({ return setFormattedLimitPrice('0') } setInputLimitPrice(nextLimitPriceFormatted) - // When price is below or equal to 0, set the limit price to 0, but don't update the state + + // const + // // When price is below or equal to 0, set the limit price to 0, but don't update the state const { buyAmountWei, sellAmountWei, newBuyTokenAmount, newSellTokenAmount } = computeNewAmount( buyAmount, @@ -169,7 +149,7 @@ export function OrderLimitPriceField({ // inputFocus ) - setFormattedLimitPrice(nextLimitPriceFormatted) + // setFormattedLimitPrice(nextLimitPriceFormatted) if (kind === Kind.Sell) { setBuyAmount(newBuyTokenAmount) @@ -184,19 +164,25 @@ export function OrderLimitPriceField({ // setFormattedSellAmount(amount.toString()) protocol.onLimitOrderChange({ ...limitOrder, - limitPrice: parseUnits(nextLimitPriceFormatted, quoteTokenAmount?.currency?.decimals).toString(), + limitPrice: parseUnits(nextLimitPriceFormatted, baseTokenAmount?.currency?.decimals).toString(), sellAmount: sellAmountWei, }) } - - setFetchMarketPrice(false) } } const onClickGetMarketPrice = () => { + setInputFocus(false) setFetchMarketPrice(true) } + // const onChangeHandler = () => {} + + // TODO: fix it + const showPercentage = false + const marketPriceDiffPercentage = 0 + const isDiffPositive = false + return ( @@ -231,7 +217,7 @@ export function OrderLimitPriceField({ onChange={onChangeHandler} /> - + setKind(kind === Kind.Sell ? Kind.Buy : Kind.Sell)}> {toggleCurrencyButtonLabel} diff --git a/src/services/LimitOrders/1Inch/OneInch.ts b/src/services/LimitOrders/1Inch/OneInch.ts index 56f5437ca1..94927fd922 100644 --- a/src/services/LimitOrders/1Inch/OneInch.ts +++ b/src/services/LimitOrders/1Inch/OneInch.ts @@ -82,4 +82,7 @@ export class OneInch extends LimitOrderBase { async getMarketPrice() { return 0 } + getTokenLimitPrices() { + return '0' + } } diff --git a/src/services/LimitOrders/CoW/CoW.ts b/src/services/LimitOrders/CoW/CoW.ts index c87017ba54..86129a8278 100644 --- a/src/services/LimitOrders/CoW/CoW.ts +++ b/src/services/LimitOrders/CoW/CoW.ts @@ -317,6 +317,25 @@ export class CoW extends LimitOrderBase { } as LimitOrder } + getTokenLimitPrices() { + const { buyAmount, sellAmount, kind } = this + if (buyAmount && sellAmount && kind) { + const [baseAmount, quoteAmount] = kind === Kind.Sell ? [sellAmount, buyAmount] : [buyAmount, sellAmount] + const quoteAmountInUnits = parseFloat(quoteAmount.toExact()) + const baseAmountInUnits = parseFloat(baseAmount.toExact()) + if ( + !Number.isNaN(quoteAmountInUnits) && + quoteAmountInUnits > 0 && + !Number.isNaN(baseAmountInUnits) && + baseAmountInUnits > 0 + ) { + const limitPrice = parseFloat(quoteAmount.toExact()) / parseFloat(baseAmount.toExact()) + return limitPrice.toFixed(6) + } + } + return '1' + } + #formatMarketPrice(amount: string, decimals: number, tokenAmount: string) { return parseFloat(formatUnits(amount, decimals) ?? 0) / Number(tokenAmount) } diff --git a/src/services/LimitOrders/LimitOrder.utils.ts b/src/services/LimitOrders/LimitOrder.utils.ts index 38199d3c1f..2853061f0e 100644 --- a/src/services/LimitOrders/LimitOrder.utils.ts +++ b/src/services/LimitOrders/LimitOrder.utils.ts @@ -84,7 +84,7 @@ export abstract class LimitOrderBase { abstract getQuote(): Promise abstract getMarketPrice(): Promise - // abstract setToMarket(sellPricePercentage: number, buyPricePercentage: number): Promise + abstract getTokenLimitPrices(): string abstract onSignerChange({ account, activeChainId, provider }: WalletData): Promise abstract approve(): Promise abstract createOrder(): Promise