Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: wire-up confirmed "Add Liquidity" quote #6030

Merged
merged 7 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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