Skip to content

Commit

Permalink
update: Limit order support multi contract (#2188)
Browse files Browse the repository at this point in the history
  • Loading branch information
nguyenhoaidanh authored Sep 5, 2023
1 parent c77a3ad commit c903b3e
Show file tree
Hide file tree
Showing 47 changed files with 565 additions and 577 deletions.
2 changes: 2 additions & 0 deletions src/components/Announcement/Popups/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import CenterPopup from 'components/Announcement/Popups/CenterPopup'
import SnippetPopup from 'components/Announcement/Popups/SnippetPopup'
import { PopupType, PrivateAnnouncementType } from 'components/Announcement/type'
import { ButtonEmpty } from 'components/Button'
import useNotificationLimitOrder from 'components/swapv2/LimitOrder/useNotificationLimitOrder'
import { TIMES_IN_SECS } from 'constants/index'
import { Z_INDEXS } from 'constants/styles'
import { useActiveWeb3React } from 'hooks'
Expand Down Expand Up @@ -149,6 +150,7 @@ export default function Popups() {
}
}, [account, isShowTutorial, addPopup, chainId, userInfo?.identityId])

useNotificationLimitOrder()
const totalTopRightPopup = topRightPopups.length

return (
Expand Down
4 changes: 2 additions & 2 deletions src/components/Header/groups/SwapNavGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { useActiveWeb3React } from 'hooks'
import useMixpanel, { MIXPANEL_TYPE } from 'hooks/useMixpanel'
import { useTutorialSwapGuide } from 'state/tutorial/hooks'
import { useIsDarkMode } from 'state/user/hooks'
import { getLimitOrderContract } from 'utils'
import { isSupportLimitOrder } from 'utils'

import { DropdownTextAnchor, StyledNavLink } from '../styleds'
import NavGroup from './NavGroup'
Expand Down Expand Up @@ -89,7 +89,7 @@ const SwapNavGroup = () => {
</Flex>
</StyledNavLink>

{getLimitOrderContract(chainId) && (
{isSupportLimitOrder(chainId) && (
<StyledNavLink
id="limit-order-nav-link"
to={`${APP_PATHS.LIMIT}/${networkInfo.route}`}
Expand Down
6 changes: 3 additions & 3 deletions src/components/WalletPopup/Transactions/Status.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function StatusIcon({
const [isPendingState, setIsPendingState] = useState<boolean | null>(needCheckActuallyPending ? null : pendingRpc)

const dispatch = useDispatch<AppDispatch>()
const { cancellingOrdersIds, cancellingOrdersNonces, loading } = cancellingOrderInfo
const { loading, isOrderCancelling } = cancellingOrderInfo

const interval = useRef<NodeJS.Timeout>()

Expand All @@ -68,7 +68,7 @@ function StatusIcon({
switch (type) {
case TRANSACTION_TYPE.CANCEL_LIMIT_ORDER:
const orderId = extraInfo?.arbitrary?.order_id
isPending = cancellingOrdersIds.includes(orderId) || cancellingOrdersNonces.length > 0
isPending = isOrderCancelling(orderId)
break
case TRANSACTION_TYPE.BRIDGE: {
const { data: response } = await axios.get(`${BFF_API}/v1/cross-chain-history/multichain-transfers/${hash}`)
Expand All @@ -95,7 +95,7 @@ function StatusIcon({
console.error('Checking txs status error: ', error)
interval.current && clearInterval(interval.current)
}
}, [cancellingOrdersIds, cancellingOrdersNonces, chainId, dispatch, transaction, extraInfo, hash, type, loading])
}, [isOrderCancelling, chainId, dispatch, transaction, extraInfo, hash, type, loading])

const checkStatusDebounced = useMemo(() => debounce(checkStatus, 1000), [checkStatus])

Expand Down
16 changes: 5 additions & 11 deletions src/components/swapv2/LimitOrder/EditOrderModal.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Trans } from '@lingui/macro'
import { ethers } from 'ethers'
import { useEffect, useState } from 'react'
import { X } from 'react-feather'
import { Flex, Text } from 'rebass'
import { useGetTotalActiveMakingAmountQuery } from 'services/limitOrder'
import styled from 'styled-components'

import Modal from 'components/Modal'
Expand All @@ -13,7 +13,6 @@ import { TransactionFlowState } from 'types/TransactionFlowState'

import LimitOrderForm, { Label } from './LimitOrderForm'
import { calcInvert, calcPercentFilledOrder, calcRate, removeTrailingZero } from './helpers'
import { getTotalActiveMakingAmount } from './request'
import { LimitOrder, LimitOrderStatus, RateInfo } from './type'

const Wrapper = styled.div`
Expand Down Expand Up @@ -61,15 +60,10 @@ export default function EditOrderModal({
const defaultRate: RateInfo = { rate, invertRate: calcInvert(rate), invert: false }
const filled = currencyOut ? calcPercentFilledOrder(filledTakingAmount, takingAmount, currencyOut.decimals) : 0

const [defaultActiveMakingAmount, setDefaultActiveMakingAmount] = useState('')

// prefetch
useEffect(() => {
if (!currencyIn || !account) return
getTotalActiveMakingAmount(chainId, currencyIn.wrapped.address, account)
.then(({ activeMakingAmount }) => setDefaultActiveMakingAmount(activeMakingAmount))
.catch(console.error)
}, [currencyIn, account, chainId])
const { data: defaultActiveMakingAmount } = useGetTotalActiveMakingAmountQuery(
{ chainId, tokenAddress: currencyIn?.wrapped.address ?? '', account: account ?? '' },
{ skip: !currencyIn || !account },
)

return (
<Modal isOpen={isOpen && !!currencyIn && !!currencyOut && !!defaultActiveMakingAmount} onDismiss={onDismiss}>
Expand Down
62 changes: 28 additions & 34 deletions src/components/swapv2/LimitOrder/LimitOrderForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ import { rgba } from 'polished'
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { Info, Repeat } from 'react-feather'
import { Flex, Text } from 'rebass'
import {
useCreateOrderMutation,
useCreateOrderSignatureMutation,
useGetLOContractAddressQuery,
useGetTotalActiveMakingAmountQuery,
} from 'services/limitOrder'
import styled from 'styled-components'

import { NotificationType } from 'components/Announcement/type'
Expand Down Expand Up @@ -40,7 +46,6 @@ import { useLimitActionHandlers, useLimitState } from 'state/limit/hooks'
import { tryParseAmount } from 'state/swap/hooks'
import { useCurrencyBalance } from 'state/wallet/hooks'
import { TransactionFlowState } from 'types/TransactionFlowState'
import { getLimitOrderContract } from 'utils'
import { subscribeNotificationOrderCancelled, subscribeNotificationOrderExpired } from 'utils/firebase'
import { maxAmountSpend } from 'utils/maxAmountSpend'

Expand All @@ -63,7 +68,6 @@ import {
parseFraction,
removeTrailingZero,
} from './helpers'
import { clearCacheActiveMakingAmount, getMessageSignature, getTotalActiveMakingAmount, submitOrder } from './request'
import { CreateOrderParam, LimitOrder, RateInfo } from './type'

export const Label = styled.div`
Expand Down Expand Up @@ -144,7 +148,6 @@ const LimitOrderForm = function LimitOrderForm({

const [inputAmount, setInputAmount] = useState(defaultInputAmount)
const [outputAmount, setOuputAmount] = useState(defaultOutputAmount)
const [activeOrderMakingAmount, setActiveOrderMakingAmount] = useState(defaultActiveMakingAmount)

const [rateInfo, setRateInfo] = useState<RateInfo>(defaultRate)
const displayRate = rateInfo.invert ? rateInfo.invertRate : rateInfo.rate
Expand All @@ -160,6 +163,12 @@ const LimitOrderForm = function LimitOrderForm({
const { loading: loadingTrade, tradeInfo } = useBaseTradeInfoLimitOrder(currencyIn, currencyOut)
const deltaRate = useGetDeltaRateLimitOrder({ marketPrice: tradeInfo, rateInfo })

const { data: activeOrderMakingAmount = defaultActiveMakingAmount, refetch: getActiveMakingAmount } =
useGetTotalActiveMakingAmountQuery(
{ chainId, tokenAddress: currencyIn?.wrapped.address ?? '', account: account ?? '' },
{ skip: !currencyIn || !account },
)

const { execute: onWrap, inputError: wrapInputError } = useWrapCallback(currencyIn, currencyOut, inputAmount, true)
const showWrap = !!currencyIn?.isNative

Expand Down Expand Up @@ -276,10 +285,13 @@ const LimitOrderForm = function LimitOrderForm({
}

const parseInputAmount = tryParseAmount(inputAmount, currencyIn ?? undefined)
const { data, isError } = useGetLOContractAddressQuery(chainId)
const limitOrderContract = isError ? undefined : data

const currentAllowance = useTokenAllowance(
currencyIn as Token,
account ?? undefined,
getLimitOrderContract(chainId) ?? '',
limitOrderContract,
) as CurrencyAmount<Currency>

const parsedActiveOrderMakingAmount = useMemo(() => {
Expand Down Expand Up @@ -323,11 +335,7 @@ const LimitOrderForm = function LimitOrderForm({
}
}, [currencyIn?.isNative, currentAllowance, parseInputAmount, parsedActiveOrderMakingAmount])

const [approval, approveCallback] = useApproveCallback(
parseInputAmount,
getLimitOrderContract(chainId) ?? '',
!enoughAllowance,
)
const [approval, approveCallback] = useApproveCallback(parseInputAmount, limitOrderContract || '', !enoughAllowance)

const { inputError, outPutError } = useValidateInputError({
inputAmount,
Expand Down Expand Up @@ -380,20 +388,6 @@ const LimitOrderForm = function LimitOrderForm({
}
}

const getActiveMakingAmount = useCallback(
async (currencyIn: Currency) => {
try {
const address = currencyIn?.wrapped.address
if (!address || !account) return
const { activeMakingAmount } = await getTotalActiveMakingAmount(chainId, address, account)
setActiveOrderMakingAmount(activeMakingAmount)
} catch (error) {
console.log(error)
}
},
[account, chainId],
)

const onResetForm = () => {
setInputAmount(defaultInputAmount)
setOuputAmount(defaultOutputAmount)
Expand All @@ -415,6 +409,7 @@ const LimitOrderForm = function LimitOrderForm({
[setFlowState],
)

const [getMessageSignature] = useCreateOrderSignatureMutation()
const signOrder = async (params: CreateOrderParam) => {
const { currencyIn, currencyOut, inputAmount, outputAmount, signature, salt } = params
if (signature && salt) return { signature, salt }
Expand All @@ -428,7 +423,7 @@ const LimitOrderForm = function LimitOrderForm({
outputAmount,
)} ${currencyOut.symbol}`,
}))
const messagePayload = await getMessageSignature(payload)
const messagePayload = await getMessageSignature(payload).unwrap()

const rawSignature = await library.send('eth_signTypedData_v4', [account, JSON.stringify(messagePayload)])

Expand All @@ -442,6 +437,7 @@ const LimitOrderForm = function LimitOrderForm({
return { signature: ethers.utils.hexlify(bytes), salt: messagePayload?.message?.salt }
}

const [submitOrder] = useCreateOrderMutation()
const onSubmitCreateOrder = async (params: CreateOrderParam) => {
try {
const { currencyIn, currencyOut, account, inputAmount, outputAmount, expiredAt } = params
Expand All @@ -452,7 +448,7 @@ const LimitOrderForm = function LimitOrderForm({
const { signature, salt } = await signOrder(params)
const payload = getPayloadCreateOrder(params)
setFlowState(state => ({ ...state, pendingText: t`Placing order` }))
const response = await submitOrder({ ...payload, salt, signature })
const response = await submitOrder({ ...payload, salt, signature }).unwrap()
setFlowState(state => ({ ...state, showConfirm: false }))

notify(
Expand All @@ -468,6 +464,7 @@ const LimitOrderForm = function LimitOrderForm({
return response?.id
} catch (error) {
handleError(error)
return
}
}

Expand Down Expand Up @@ -526,19 +523,16 @@ const LimitOrderForm = function LimitOrderForm({
const refreshActiveMakingAmount = useMemo(
() =>
debounce(() => {
clearCacheActiveMakingAmount()
if (currencyIn) {
getActiveMakingAmount(currencyIn)
}
try {
getActiveMakingAmount()
} catch (error) {}
}, 100),
[currencyIn, getActiveMakingAmount],
[getActiveMakingAmount],
)

const isInit = useRef(false)
useEffect(() => {
if (isInit.current && currencyIn) getActiveMakingAmount(currencyIn) // skip the first time
isInit.current = true
}, [currencyIn, getActiveMakingAmount, isEdit])
if (currencyIn) refreshActiveMakingAmount()
}, [currencyIn, refreshActiveMakingAmount, isEdit])

// use ref to prevent too many api call when firebase update status
const refSubmitCreateOrder = useRef(onSubmitCreateOrder)
Expand Down
Loading

0 comments on commit c903b3e

Please sign in to comment.