diff --git a/lib/format.ts b/lib/format.ts index c41eb1e6..621e39ca 100644 --- a/lib/format.ts +++ b/lib/format.ts @@ -33,6 +33,29 @@ export function formatTokenAmount(value: bigint, decimals: number): string { return num.toExponential(2); } +/** + * Format a small decimal using subscript-zero notation: $0.0₄6262 + * Counts leading zeros after the decimal and renders the count as a + * Unicode subscript digit, followed by 4 significant digits. + */ +export function formatSubscriptPrice(v: number, prefix = "$"): string { + const str = v.toFixed(20); + const afterDot = str.split(".")[1]; + let leadingZeros = 0; + for (const c of afterDot) { + if (c === "0") leadingZeros++; + else break; + } + const significant = afterDot.slice(leadingZeros, leadingZeros + 4); + const subscriptMap: Record = { + "0": "\u2080", "1": "\u2081", "2": "\u2082", "3": "\u2083", + "4": "\u2084", "5": "\u2085", "6": "\u2086", "7": "\u2087", + "8": "\u2088", "9": "\u2089", + }; + const subscriptZeros = leadingZeros.toString().split("").map((d) => subscriptMap[d]).join(""); + return `${prefix}0.0${subscriptZeros}${significant}`; +} + /** Format a token supply or balance for display. Accepts a string or number. */ export function formatSupply(value: string | number): string { const v = typeof value === "string" ? parseFloat(value) : value; diff --git a/lib/usd-price.ts b/lib/usd-price.ts index 3784b058..0a60f71d 100644 --- a/lib/usd-price.ts +++ b/lib/usd-price.ts @@ -12,6 +12,7 @@ import { PLOT_TOKEN } from "./contracts/constants"; import { createServiceRoleClient } from "./supabase"; +import { formatSubscriptPrice } from "./format"; // In-memory cache let cachedPrice: number | null = null; @@ -212,7 +213,5 @@ export function formatUsdTokenPrice(value: number | null): string { if (value === null) return "—"; if (value === 0) return "$0"; if (value >= 0.01) return formatUsdValue(value); - // For very small values, show 2 significant digits - const digits = Math.max(2, -Math.floor(Math.log10(value)) + 1); - return `$${value.toFixed(digits)}`; + return formatSubscriptPrice(value); } diff --git a/package-lock.json b/package-lock.json index b4883bc7..9a15534c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "plotlink", - "version": "0.1.27", + "version": "0.1.47", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "plotlink", - "version": "0.1.27", + "version": "0.1.47", "workspaces": [ "packages/*" ], diff --git a/package.json b/package.json index 1e277dfb..b01272bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "plotlink", - "version": "0.1.46", + "version": "0.1.47", "private": true, "workspaces": [ "packages/*" diff --git a/src/components/PriceChart.tsx b/src/components/PriceChart.tsx index 883c217b..c76a3534 100644 --- a/src/components/PriceChart.tsx +++ b/src/components/PriceChart.tsx @@ -6,6 +6,7 @@ import { type Address, formatUnits } from "viem"; import { supabase } from "../../lib/supabase"; import { RESERVE_LABEL } from "../../lib/contracts/constants"; import { usePlotUsdPrice } from "../hooks/usePlotUsdPrice"; +import { formatSubscriptPrice } from "../../lib/format"; const CHART_W = 320; const CHART_H = 140; @@ -41,7 +42,7 @@ function formatTime(iso: string): string { function formatReservePrice(v: number): string { if (v === 0) return "0"; - if (v < 0.001) return v.toExponential(0); + if (v < 0.001) return formatSubscriptPrice(v, ""); if (v < 1) return v.toFixed(4); return v.toFixed(2); } @@ -50,8 +51,7 @@ function formatUsdPrice(v: number): string { if (v === 0) return "$0"; if (v >= 1) return `$${v.toFixed(2)}`; if (v >= 0.01) return `$${v.toFixed(4)}`; - if (v >= 0.0001) return `$${v.toFixed(6)}`; - return `$${v.toExponential(2)}`; + return formatSubscriptPrice(v); } /**