Swap Panel

The pay/receive form of a token swap. Price impact is surfaced rather than buried behind a details toggle, and above a threshold the action is disabled outright.

src/components/ui/swap-panel.tsx

About

From the component's own source, where it was written.

The pay/receive form of a token swap.

Price impact is surfaced, not buried behind a details toggle. A swap that moves the pool 12% is a bad trade whether or not the user expanded a panel, and above impactWarn the figure is coloured and above impactBlock the action is disabled outright. Interfaces that hide this are why people lose money to thin liquidity.

The minimum received is shown as an amount rather than only a slippage percentage — "0.5%" is abstract, "you get at least 1,240 USDC" is the number the user is actually agreeing to.

Install

npx astralyx-ui add swap-panel

Usage

import { SwapPanel } from '@/components/ui/swap-panel'

<SwapPanel from={from} to={to} priceImpact={0.8} minimumReceived="1,240 USDC" onSwap={swap} />

Composer

Change the props and the source below follows.

Swap
You payBalance 2.41
0.5ETH
US$1,642.25
You receiveBalance 0.00
1,638.40USDC
US$1,638.40
Rate
1 ETH = 3,284.50 USDC
Price impact
0.40%
Minimum received
1,630.21 USDC
Slippage tolerance
0.5%
Network fee
~$2.14
Props
tsx
<SwapPanel
  from={from}
  to={to}
  priceImpact={0.4}
  minimumReceived="1,630.21 USDC"
  onSwap={swap}
/>

Examples

Healthy and blocked

API

Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.

SwapPanel

The pay/receive form of a token swap.

Extends Omit<ComponentProps<'div'>, 'children'>.

PropTypeDefaultDescription
titlestring'Swap'—
fromSwapSiderequired{ symbol, amount, fiat?, balance?, icon? }.
toSwapSiderequired{ symbol, amount, fiat?, balance?, icon? }.
rateReactNode——
priceImpactnumber—Percentage. Coloured above impactWarn (3) and the action is disabled above impactBlock (15).
minimumReceivedReactNode—An amount, not just a slippage percentage — "0.5%" is abstract, an amount is what the user agrees to.
networkFeeReactNode——
slippagenumber0.5—
impactWarnnumber3—
impactBlocknumber15—
onSwap() => void—The panel performs no routing or quoting of its own.
onFlip() => void—The panel performs no routing or quoting of its own.
onSettings() => void—The panel performs no routing or quoting of its own.
actionReactNode'Swap'—
settingsLabelstring'Swap settings'—
flipLabelstring'Flip direction'—
rateLabelReactNode'Rate'—
priceImpactLabelReactNode'Price impact'—
minimumReceivedLabelReactNode'Minimum received'—
slippageLabelReactNode'Slippage tolerance'—
networkFeeLabelReactNode'Network fee'—
blockedLabelReactNode'Price impact too high'Replaces the action label once impact exceeds impactBlock.
blockedNote(limit: number) => ReactNodeDEFAULT_BLOCKED_NOTEWarning shown at that point, given the threshold.
disabledbooleanfalse—
currencystring'USD'—
localestring'en-GB'—

Types

SwapSide

FieldTypeDescription
symbolReactNode—
amountstring—
fiat?numberFiat value of the amount.
balance?ReactNode—
icon?ReactNode—