Skip to content

Commit

Permalink
feat: wire-up confirmed "Add Liquidity" quote (#6030)
Browse files Browse the repository at this point in the history
* wip: wire-up confirmed quote

* feat: split AddLiquidity exposed and internal prop types

* feat: improve types

* feat: disable continue while waiting for confirmed quote

* feat: cleanup console.log

* feat: improve types

* fix: use confirmedQuote.opportunityId as routing source of truth for
confirm and status routes
  • Loading branch information
gomesalexandre authored Jan 17, 2024
1 parent 0e0946e commit f04405c
Show file tree
Hide file tree
Showing 5 changed files with 232 additions and 100 deletions.
10 changes: 10 additions & 0 deletions src/lib/utils/thorchain/lp/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,13 @@ export type MidgardTvlHistoryResponse = {
meta: MidgardTvlHistoryItem
intervals: MidgardTvlHistoryItem[]
}

export type ConfirmedQuote = {
assetCryptoLiquidityAmount: string
assetFiatLiquidityAmount: string
runeCryptoLiquidityAmount: string
runeFiatLiquidityAmount: string
shareOfPoolDecimalPercent: string
slippageRune: string
opportunityId: string
}
40 changes: 31 additions & 9 deletions src/pages/ThorChainLP/components/AddLiquitity/AddLiquidity.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AnimatePresence } from 'framer-motion'
import React, { Suspense, useCallback } from 'react'
import React, { Suspense, useCallback, useState } from 'react'
import { MemoryRouter, Route, Switch, useLocation } from 'react-router'
import type { ConfirmedQuote } from 'lib/utils/thorchain/lp/types'

import { AddLiquidityConfirm } from './AddLiquidityConfirm'
import { AddLiquidityInput } from './AddLiquidityInput'
Expand All @@ -21,31 +22,52 @@ export type AddLiquidityProps = {
}

export const AddLiquidity: React.FC<AddLiquidityProps> = ({ opportunityId, headerComponent }) => {
const [confirmedQuote, setConfirmedQuote] = useState<ConfirmedQuote | null>(null)

return (
<MemoryRouter initialEntries={AddLiquidityEntries} initialIndex={0}>
<AddLiquidityRoutes opportunityId={opportunityId} headerComponent={headerComponent} />
<AddLiquidityRoutes
opportunityId={opportunityId}
headerComponent={headerComponent}
setConfirmedQuote={setConfirmedQuote}
confirmedQuote={confirmedQuote}
/>
</MemoryRouter>
)
}

export const AddLiquidityRoutes: React.FC<AddLiquidityProps> = ({
type AddLiquidityRoutesProps = AddLiquidityProps & {
confirmedQuote: ConfirmedQuote | null
setConfirmedQuote: (quote: ConfirmedQuote) => void
}

export const AddLiquidityRoutes: React.FC<AddLiquidityRoutesProps> = ({
headerComponent,
opportunityId,
confirmedQuote,
setConfirmedQuote,
}) => {
const location = useLocation()

const renderAddLiquidityInput = useCallback(
() => <AddLiquidityInput opportunityId={opportunityId} headerComponent={headerComponent} />,
[headerComponent, opportunityId],
() => (
<AddLiquidityInput
opportunityId={opportunityId}
headerComponent={headerComponent}
setConfirmedQuote={setConfirmedQuote}
confirmedQuote={confirmedQuote}
/>
),
[confirmedQuote, headerComponent, opportunityId, setConfirmedQuote],
)
const renderAddLiquidityConfirm = useCallback(
() => <AddLiquidityConfirm opportunityId={opportunityId} />,
[opportunityId],
() => (confirmedQuote ? <AddLiquidityConfirm confirmedQuote={confirmedQuote} /> : null),
[confirmedQuote],
)

const renderAddLiquidityStatus = useCallback(
() => <AddLiquidityStatus opportunityId={opportunityId} />,
[opportunityId],
() => (confirmedQuote ? <AddLiquidityStatus confirmedQuote={confirmedQuote} /> : null),
[confirmedQuote],
)

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { SlideTransition } from 'components/SlideTransition'
import { RawText } from 'components/Text'
import { Timeline, TimelineItem } from 'components/Timeline/Timeline'
import { getChainAdapterManager } from 'context/PluginProvider/chainAdapterSingleton'
import type { ConfirmedQuote } from 'lib/utils/thorchain/lp/types'
import { usePools } from 'pages/ThorChainLP/hooks/usePools'
import { AsymSide } from 'pages/ThorChainLP/hooks/useUserLpData'
import { selectAssetById } from 'state/slices/assetsSlice/selectors'
Expand All @@ -45,14 +46,16 @@ const dividerStyle = {
}

type AddLiquidityConfirmProps = {
opportunityId?: string
confirmedQuote: ConfirmedQuote
}

export const AddLiquidityConfirm = ({ opportunityId }: AddLiquidityConfirmProps) => {
export const AddLiquidityConfirm = ({ confirmedQuote }: AddLiquidityConfirmProps) => {
const translate = useTranslate()
const history = useHistory()
const backIcon = useMemo(() => <ArrowBackIcon />, [])

const { opportunityId } = confirmedQuote

const { data: parsedPools } = usePools()

const foundPool = useMemo(() => {
Expand Down Expand Up @@ -120,27 +123,51 @@ export const AddLiquidityConfirm = ({ opportunityId }: AddLiquidityConfirmProps)

return (
<Stack direction='row' divider={divider} position='relative'>
{assets.map(_asset => (
<Card
display='flex'
alignItems='center'
justifyContent='center'
flexDir='column'
gap={4}
py={6}
px={4}
flex={1}
>
<AssetIcon size='sm' assetId={_asset.assetId} />
<Stack textAlign='center' spacing={0}>
<Amount.Crypto fontWeight='bold' value='100' symbol={_asset.symbol} />
<Amount.Fiat fontSize='sm' color='text.subtle' value='100' />
</Stack>
</Card>
))}
{assets.map(_asset => {
const amountCryptoPrecision =
_asset.assetId === thorchainAssetId
? confirmedQuote.runeCryptoLiquidityAmount
: confirmedQuote.assetCryptoLiquidityAmount
const amountFiatUserCurrency =
_asset.assetId === thorchainAssetId
? confirmedQuote.runeFiatLiquidityAmount
: confirmedQuote.assetFiatLiquidityAmount

return (
<Card
display='flex'
alignItems='center'
justifyContent='center'
flexDir='column'
gap={4}
py={6}
px={4}
flex={1}
>
<AssetIcon size='sm' assetId={_asset.assetId} />
<Stack textAlign='center' spacing={0}>
<Amount.Crypto
fontWeight='bold'
value={amountCryptoPrecision}
symbol={_asset.symbol}
/>
<Amount.Fiat fontSize='sm' color='text.subtle' value={amountFiatUserCurrency} />
</Stack>
</Card>
)
})}
</Stack>
)
}, [asset, divider, foundPool, rune])
}, [
asset,
confirmedQuote.assetCryptoLiquidityAmount,
confirmedQuote.assetFiatLiquidityAmount,
confirmedQuote.runeCryptoLiquidityAmount,
confirmedQuote.runeFiatLiquidityAmount,
divider,
foundPool,
rune,
])

if (!(foundPool && asset && rune)) return null

Expand Down Expand Up @@ -193,7 +220,7 @@ export const AddLiquidityConfirm = ({ opportunityId }: AddLiquidityConfirmProps)
<Row fontSize='sm'>
<Row.Label>{translate('pools.shareOfPool')}</Row.Label>
<Row.Value>
<Amount.Percent value='0.2' />
<Amount.Percent value={confirmedQuote.shareOfPoolDecimalPercent} />
</Row.Value>
</Row>
</TimelineItem>
Expand Down Expand Up @@ -224,7 +251,10 @@ export const AddLiquidityConfirm = ({ opportunityId }: AddLiquidityConfirmProps)
<Row.Label>{translate('common.slippage')}</Row.Label>
<Row.Value>
<Skeleton isLoaded={true}>
<Amount.Crypto value={'0'} symbol={asset.symbol} />
<Amount.Crypto
value={confirmedQuote.slippageRune ?? 'TODO - loading'}
symbol={rune.symbol}
/>
</Skeleton>
</Row.Value>
</Row>
Expand Down
78 changes: 60 additions & 18 deletions src/pages/ThorChainLP/components/AddLiquitity/AddLiquidityInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ import { bn, bnOrZero, convertPrecision } from 'lib/bignumber/bignumber'
import { isSome } from 'lib/utils'
import { THOR_PRECISION } from 'lib/utils/thorchain/constants'
import { estimateAddThorchainLiquidityPosition } from 'lib/utils/thorchain/lp'
import type { ConfirmedQuote } from 'lib/utils/thorchain/lp/types'
import { usePools } from 'pages/ThorChainLP/hooks/usePools'
import { AsymSide } from 'pages/ThorChainLP/hooks/useUserLpData'
import { selectAssetById, selectAssets, selectMarketDataById } from 'state/slices/selectors'
import { useAppSelector } from 'state/store'

import type { AddLiquidityProps } from './AddLiquidity'
import { DepositType } from './components/DepositType'
import { PoolSummary } from './components/PoolSummary'
import { ReadOnlyAsset } from './components/ReadOnlyAsset'
Expand All @@ -63,9 +63,18 @@ const dividerStyle = {
marginTop: 12,
}

export const AddLiquidityInput: React.FC<AddLiquidityProps> = ({
export type AddLiquidityInputProps = {
headerComponent?: JSX.Element
opportunityId?: string
setConfirmedQuote: (quote: ConfirmedQuote) => void
confirmedQuote: ConfirmedQuote | null
}

export const AddLiquidityInput: React.FC<AddLiquidityInputProps> = ({
headerComponent,
opportunityId,
confirmedQuote,
setConfirmedQuote,
}) => {
const translate = useTranslate()
const { history: browserHistory } = useBrowserRouter()
Expand Down Expand Up @@ -187,30 +196,23 @@ export const AddLiquidityInput: React.FC<AddLiquidityProps> = ({
variant='ghost'
icon={backIcon}
aria-label='go back'
disabled={!confirmedQuote}
/>
{translate('pools.addLiquidity')}
<SlippagePopover />
</CardHeader>
)
}, [backIcon, handleBackClick, headerComponent, translate])
}, [backIcon, confirmedQuote, handleBackClick, headerComponent, translate])

const assetMarketData = useAppSelector(state => selectMarketDataById(state, asset?.assetId ?? ''))
const runeMarketData = useAppSelector(state => selectMarketDataById(state, rune?.assetId ?? ''))

const [assetCryptoLiquidityAmount, setAssetCryptoLiquidityAmount] = React.useState<
string | undefined
>()
const [assetFiatLiquidityAmount, setAssetFiatLiquidityAmount] = React.useState<
string | undefined
>()
const [runeCryptoLiquidityAmount, setRuneCryptoLiquidityAmount] = React.useState<
string | undefined
>()
const [runeFiatLiquidityAmount, setRuneFiatLiquidityAmount] = React.useState<string | undefined>()
const [slippageRune, setSlippageRune] = React.useState<string | undefined>()
const [shareOfPoolDecimalPercent, setShareOfPoolDecimalPercent] = React.useState<
string | undefined
>()
const [assetCryptoLiquidityAmount, setAssetCryptoLiquidityAmount] = useState<string | undefined>()
const [assetFiatLiquidityAmount, setAssetFiatLiquidityAmount] = useState<string | undefined>()
const [runeCryptoLiquidityAmount, setRuneCryptoLiquidityAmount] = useState<string | undefined>()
const [runeFiatLiquidityAmount, setRuneFiatLiquidityAmount] = useState<string | undefined>()
const [slippageRune, setSlippageRune] = useState<string | undefined>()
const [shareOfPoolDecimalPercent, setShareOfPoolDecimalPercent] = useState<string | undefined>()

const runePerAsset = useMemo(() => {
if (!assetMarketData || !runeMarketData) return undefined
Expand Down Expand Up @@ -277,6 +279,40 @@ export const AddLiquidityInput: React.FC<AddLiquidityProps> = ({
})()
}, [asset, assetCryptoLiquidityAmount, runeCryptoLiquidityAmount])

useEffect(() => {
if (
!(
assetCryptoLiquidityAmount &&
assetFiatLiquidityAmount &&
runeCryptoLiquidityAmount &&
runeFiatLiquidityAmount &&
shareOfPoolDecimalPercent &&
slippageRune &&
activeOpportunityId
)
)
return

setConfirmedQuote({
assetCryptoLiquidityAmount,
assetFiatLiquidityAmount,
runeCryptoLiquidityAmount,
runeFiatLiquidityAmount,
shareOfPoolDecimalPercent,
slippageRune,
opportunityId: activeOpportunityId,
})
}, [
activeOpportunityId,
assetCryptoLiquidityAmount,
assetFiatLiquidityAmount,
runeCryptoLiquidityAmount,
runeFiatLiquidityAmount,
setConfirmedQuote,
shareOfPoolDecimalPercent,
slippageRune,
])

const tradeAssetInputs = useMemo(() => {
if (!(asset && rune && foundPool)) return null

Expand Down Expand Up @@ -473,7 +509,13 @@ export const AddLiquidityInput: React.FC<AddLiquidityProps> = ({
borderBottomRadius='xl'
>
{symAlert}
<Button mx={-2} size='lg' colorScheme='blue' onClick={handleSubmit}>
<Button
mx={-2}
size='lg'
colorScheme='blue'
isDisabled={!confirmedQuote}
onClick={handleSubmit}
>
{translate('pools.addLiquidity')}
</Button>
</CardFooter>
Expand Down
Loading

0 comments on commit f04405c

Please sign in to comment.