Skip to content

Commit

Permalink
feat: ZapInfoCard
Browse files Browse the repository at this point in the history
  • Loading branch information
0xMasayoshi committed Nov 10, 2024
1 parent a227263 commit 4b2e47f
Show file tree
Hide file tree
Showing 7 changed files with 334 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { AddSectionReviewModalLegacy } from 'src/ui/pool/AddSectionReviewModalLe
import { SelectNetworkWidget } from 'src/ui/pool/SelectNetworkWidget'
import { SelectTokensWidget } from 'src/ui/pool/SelectTokensWidget'
import { ToggleZapCard } from 'src/ui/pool/ToggleZapCard'
import { ZapInfoCard } from 'src/ui/pool/ZapInfoCard'
import { ChainId, ChainKey, TESTNET_CHAIN_IDS } from 'sushi/chain'
import {
SUSHISWAP_V2_ROUTER_ADDRESS,
Expand Down Expand Up @@ -317,6 +318,11 @@ const ZapWidget: FC<ZapWidgetProps> = ({ chainId, pool, poolState, title }) => {
</Checker.Network>
</Checker.Connect>
</CheckerProvider>
<ZapInfoCard
zapResponse={zapResponse}
inputCurrency={inputCurrency}
pool={pool}
/>
</>
)
}
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/ui/pool/SmartPoolLiquidityWidget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const SmartPoolLiquidityWidget: FC<SmartPoolLiquidityWidgetProps> = ({
<ToggleZapCard checked={useZap} onCheckedChange={setUseZap} />
) : null}
{useZap ? (
<SteerPositionZap vault={vault} />
<SteerPositionZap vault={vault} tokenRatios={tokenRatios} />
) : (
<SteerPositionAddProvider>
<SteerPositionAdd vault={vault} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,20 @@ import { useZap } from 'src/lib/hooks'
import { Web3Input } from 'src/lib/wagmi/components/web3-input'
import { Checker } from 'src/lib/wagmi/systems/Checker'
import { CheckerProvider } from 'src/lib/wagmi/systems/Checker/Provider'
import { ZapInfoCard } from 'src/ui/pool/ZapInfoCard'
import { defaultCurrency, isWNativeSupported } from 'sushi/config'
import { Amount, Type, tryParseAmount } from 'sushi/currency'
import { useAccount, useEstimateGas, useSendTransaction } from 'wagmi'

interface SteerPositionAddProps {
vault: VaultV1
tokenRatios?: { token0: number; token1: number }
}

export const SteerPositionZap: FC<SteerPositionAddProps> = ({ vault }) => {
export const SteerPositionZap: FC<SteerPositionAddProps> = ({
vault,
tokenRatios,
}) => {
const { address } = useAccount()

const [inputAmount, setInputAmount] = useState('')
Expand Down Expand Up @@ -117,6 +122,12 @@ export const SteerPositionZap: FC<SteerPositionAddProps> = ({ vault }) => {
</Checker.Connect>
</Checker.Guard>
</CheckerProvider>
<ZapInfoCard
zapResponse={zapResponse}
inputCurrency={inputCurrency}
pool={vault}
tokenRatios={tokenRatios}
/>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export const SteerBaseStrategy: SteerStrategyComponent = ({
<ToggleZapCard checked={useZap} onCheckedChange={setUseZap} />
) : null}
{useZap ? (
<SteerPositionZap vault={vault} />
<SteerPositionZap vault={vault} tokenRatios={tokenRatios} />
) : (
<SteerPositionAddProvider>
<SteerPositionAdd vault={vault} />
Expand Down
85 changes: 85 additions & 0 deletions apps/web/src/ui/pool/ZapInfoCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { SteerVault } from '@sushiswap/steer-sdk'
import {
Card,
CardContent,
Collapsible,
SkeletonBox,
SkeletonText,
classNames,
} from '@sushiswap/ui'
import { FC, useMemo } from 'react'
import { ZapResponse } from 'src/lib/hooks'
import {
warningSeverity,
warningSeverityClassName,
} from 'src/lib/swap/warningSeverity'
import { Type } from 'sushi/currency'
import { Percent, ZERO } from 'sushi/math'
import { SushiSwapV2Pool } from 'sushi/pool'
import { ZapRouteDialog } from './ZapRouteDialog'

interface ZapInfoCardProps {
zapResponse?: ZapResponse
inputCurrency: Type
pool: SushiSwapV2Pool | SteerVault | null
tokenRatios?: { token0: number; token1: number }
}

export const ZapInfoCard: FC<ZapInfoCardProps> = ({
zapResponse,
inputCurrency,
pool,
tokenRatios,
}) => {
const priceImpact = useMemo(
() =>
typeof zapResponse?.priceImpact === 'number'
? new Percent(zapResponse.priceImpact, 10_000)
: undefined,
[zapResponse],
)

return (
<Collapsible open={Boolean(zapResponse)}>
<Card variant="outline">
<CardContent className="!pt-3 !pb-3 !px-5">
<div className="flex justify-between items-center gap-2">
<span className="font-medium">Price impact</span>
<span
className={classNames(
warningSeverityClassName(warningSeverity(priceImpact)),
'text-sm font-medium text-right',
)}
>
{!priceImpact ? (
<SkeletonBox className="h-4 py-0.5 w-[40px]" />
) : priceImpact ? (
`${
priceImpact?.lessThan(ZERO)
? '+'
: priceImpact?.greaterThan(ZERO)
? '-'
: ''
}${Math.abs(Number(priceImpact?.toFixed(2)))}%`
) : null}
</span>
</div>
<div className="flex justify-between items-center gap-2">
<span className="font-medium">Route</span>
{pool ? (
<ZapRouteDialog
inputCurrency={inputCurrency}
pool={pool}
tokenRatios={tokenRatios}
>
<span className="underline font-medium">View Route</span>
</ZapRouteDialog>
) : (
<SkeletonText />
)}
</div>
</CardContent>
</Card>
</Collapsible>
)
}
184 changes: 184 additions & 0 deletions apps/web/src/ui/pool/ZapRouteDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
import { SteerVault } from '@sushiswap/steer-sdk'
import {
Currency,
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@sushiswap/ui'
import { FC, ReactNode, useMemo } from 'react'
import { Token, Type } from 'sushi/currency'
import { formatPercent } from 'sushi/format'
import { SushiSwapV2Pool } from 'sushi/pool'

interface ZapRouteDialogProps {
children: ReactNode
inputCurrency: Type
pool: SushiSwapV2Pool | SteerVault
tokenRatios?: { token0: number; token1: number }
}

export const ZapRouteDialog: FC<ZapRouteDialogProps> = ({
children,
inputCurrency,
pool,
tokenRatios,
}) => {
const [token0, token1] = useMemo(
() => [
pool.token0 instanceof Token ? pool.token0 : new Token(pool.token0),
pool.token1 instanceof Token ? pool.token1 : new Token(pool.token1),
],
[pool],
)

return (
<Dialog>
<DialogTrigger>{children}</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Route</DialogTitle>
</DialogHeader>

<div className="flex flex-col gap-3">
<span className="text-sm text-muted-foreground">Split & Swap</span>
<div className="bg-secondary rounded-xl flex flex-col gap-1">
<div className="px-5 py-2 grid grid-cols-3 gap-3 items-center">
<div className="flex items-center gap-1">
<Currency.Icon
disableLink
currency={inputCurrency}
width={16}
height={16}
/>
<span className="text-sm font-semibold truncate">
{inputCurrency.symbol}
</span>
</div>
<div className="flex flex-col items-center">
<div className="text-sm font-medium truncate">
{pool instanceof SushiSwapV2Pool
? '50%'
: tokenRatios
? `${formatPercent(tokenRatios.token0)}`
: '-%'}
</div>
<span className="text-[10px] font-medium text-muted-foreground truncate">
SushiSwap
</span>
</div>
<div className="flex items-center justify-end gap-1">
<Currency.Icon
disableLink
currency={token0}
width={16}
height={16}
/>
<span className="text-sm font-semibold truncate">
{token0.symbol}
</span>
</div>
</div>
<div className="px-5 py-2 grid grid-cols-3 gap-3 items-center">
<div className="flex items-center gap-1">
<Currency.Icon
disableLink
currency={inputCurrency}
width={16}
height={16}
/>
<span className="text-sm font-semibold truncate">
{inputCurrency.symbol}
</span>
</div>
<div className="flex flex-col items-center">
<div className="text-sm font-medium truncate">
{pool instanceof SushiSwapV2Pool
? '50%'
: tokenRatios
? `${formatPercent(tokenRatios.token1)}`
: '-%'}
</div>
<span className="text-[10px] font-medium text-muted-foreground truncate">
SushiSwap
</span>
</div>
<div className="flex items-center justify-end gap-1">
<Currency.Icon
disableLink
currency={token1}
width={16}
height={16}
/>
<span className="text-sm font-semibold truncate">
{token1.symbol}
</span>
</div>
</div>
</div>
</div>

<div className="flex flex-col gap-3">
<span className="text-sm text-muted-foreground">Add Liquidity</span>
<div className="bg-secondary rounded-xl flex flex-col gap-1">
<div className="px-5 py-2 grid grid-cols-3 gap-3 items-center">
<div className="flex flex-col gap-0.5">
<div className="flex items-center gap-1">
<Currency.Icon
disableLink
currency={token0}
width={16}
height={16}
/>
<span className="text-sm font-semibold truncate">
{token0.symbol}
</span>
</div>
<div className="flex items-center gap-1">
<Currency.Icon
disableLink
currency={token1}
width={16}
height={16}
/>
<span className="text-sm font-semibold truncate">
{token1.symbol}
</span>
</div>
</div>
<div className="flex flex-col items-center">
<div className="text-sm font-medium truncate">100%</div>
<span className="text-[10px] font-medium text-muted-foreground truncate">
Deposit to{' '}
{pool instanceof SushiSwapV2Pool ? 'SushiSwap V2' : 'Steer'}
</span>
</div>
<div className="flex items-center justify-end gap-1">
<span className="inline-flex items-center">
<Currency.Icon
disableLink
currency={token0}
width={16}
height={16}
/>
<div className="-ml-1 inline-flex">
<Currency.Icon
disableLink
currency={token1}
width={16}
height={16}
/>
</div>
</span>
<span className="text-sm font-semibold truncate">
{pool instanceof SushiSwapV2Pool ? 'SLP' : 'Steer LP'}
</span>
</div>
</div>
</div>
</div>
</DialogContent>
</Dialog>
)
}
Loading

0 comments on commit 4b2e47f

Please sign in to comment.