Liquidity Position

A concentrated-liquidity position with its range. In-range versus out-of-range is the headline — a position outside its range earns nothing, and a card showing only "fees earned" while it stopped earning last week is misleading.

src/components/ui/liquidity-position.tsx

About

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

A concentrated-liquidity position, with its range.

In-range versus out-of-range is the headline, not a detail. A position outside its range earns nothing at all — it has quietly become a single-sided holding of whichever asset the price ran away from — and a card that shows only "fees earned: $412" while the position stopped earning last Tuesday is actively misleading.

The range bar plots the current price against the bounds, so "just inside" and "about to exit" look different. A pair of numbers cannot show that.

Install

npx astralyx-ui add liquidity-position

Usage

import { LiquidityPosition } from '@/components/ui/liquidity-position'

<LiquidityPosition pair="ETH / USDC" minPrice={2800} maxPrice={3600} currentPrice={3284} />

Composer

Change the props and the source below follows.

ETH / USDCIn range18.4% APR
2,8003,284USDC per ETH3,600
Position value
$12,480
Uncollected fees
$412.20
Props
tsx
<LiquidityPosition
  pair="ETH / USDC"
  minPrice={2800}
  maxPrice={3600}
  currentPrice={3284}
/>

Examples

In and out of range

API

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

LiquidityPosition

A concentrated-liquidity position, with its range.

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

PropTypeDefaultDescription
pairReactNoderequired—
feesReactNode—Formatting is the caller’s — pair with TokenAmount.
valueReactNode—Formatting is the caller’s — pair with TokenAmount.
minPricenumberrequiredIn-range is derived from these, never passed as a flag.
maxPricenumberrequiredIn-range is derived from these, never passed as a flag.
currentPricenumberrequiredIn-range is derived from these, never passed as a flag.
priceLabelReactNode—e.g. "USDC per ETH"
aprnumber—Formatting is the caller’s — pair with TokenAmount.
onCollect() => void——
onManage() => void——
collectDisabledbooleanfalse—
localestring'en-GB'—
outOfRangeNoteReactNode'Price has left the range — this position is not earning fees.'Shown when the current price sits outside min/max.
valueLabelReactNode'Position value'—
feesLabelReactNode'Uncollected fees'—
collectLabelReactNode'Collect fees'—
manageLabelReactNode'Manage'—

Behaviour

TopicDetailDescription
range barplottedWith padding either side, so an out-of-range price stays visible and "just inside" looks different from "about to exit".