diff --git a/.gitea/workflows/deploy-live.yml b/.gitea/workflows/deploy-live.yml index c978cbf..fb8325d 100644 --- a/.gitea/workflows/deploy-live.yml +++ b/.gitea/workflows/deploy-live.yml @@ -37,7 +37,8 @@ jobs: if [ -z "$BRANCH" ] || [ "$BRANCH" = "HEAD" ]; then BRANCH="$(git rev-parse --abbrev-ref HEAD)" fi - curl -sSf -X POST "${{ secrets.PHOENIX_DEPLOY_URL }}" \ + curl -sSf --connect-timeout 10 --max-time 3600 \ + -X POST "${{ secrets.PHOENIX_DEPLOY_URL }}" \ -H "Authorization: Bearer ${{ secrets.PHOENIX_DEPLOY_TOKEN }}" \ -H "Content-Type: application/json" \ -d "{\"repo\":\"${{ gitea.repository }}\",\"sha\":\"${SHA}\",\"branch\":\"${BRANCH}\",\"target\":\"explorer-live\"}" diff --git a/frontend/libs/frontend-ui-primitives/Card.tsx b/frontend/libs/frontend-ui-primitives/Card.tsx index 196f6f7..0db7cdb 100644 --- a/frontend/libs/frontend-ui-primitives/Card.tsx +++ b/frontend/libs/frontend-ui-primitives/Card.tsx @@ -11,12 +11,12 @@ export function Card({ children, className, title }: CardProps) { return (
{title && ( -

+

{title}

)} diff --git a/frontend/src/components/common/BrandLockup.tsx b/frontend/src/components/common/BrandLockup.tsx index 4c33eb5..593288e 100644 --- a/frontend/src/components/common/BrandLockup.tsx +++ b/frontend/src/components/common/BrandLockup.tsx @@ -8,7 +8,7 @@ export default function BrandLockup({ compact = false }: { compact?: boolean }) DBIS Explorer @@ -16,7 +16,7 @@ export default function BrandLockup({ compact = false }: { compact?: boolean }) Chain 138 Explorer by DBIS diff --git a/frontend/src/components/common/BrandMark.tsx b/frontend/src/components/common/BrandMark.tsx index 59049b6..8fcb13c 100644 --- a/frontend/src/components/common/BrandMark.tsx +++ b/frontend/src/components/common/BrandMark.tsx @@ -1,9 +1,9 @@ export default function BrandMark({ size = 'default' }: { size?: 'default' | 'compact' }) { const containerClassName = size === 'compact' - ? 'h-10 w-10 rounded-xl' - : 'h-11 w-11 rounded-2xl' - const iconClassName = size === 'compact' ? 'h-6 w-6' : 'h-7 w-7' + ? 'h-9 w-9 rounded-lg' + : 'h-10 w-10 rounded-lg' + const iconClassName = size === 'compact' ? 'h-5 w-5' : 'h-6 w-6' return ( diff --git a/frontend/src/components/common/Navbar.tsx b/frontend/src/components/common/Navbar.tsx index 46a8963..fd864e5 100644 --- a/frontend/src/components/common/Navbar.tsx +++ b/frontend/src/components/common/Navbar.tsx @@ -703,10 +703,10 @@ export default function Navbar() { <>
-
+
setMobileMenuOpen(false)} aria-label="Go to DBIS Explorer home" > diff --git a/frontend/src/components/common/PageIntro.tsx b/frontend/src/components/common/PageIntro.tsx index d611df4..387286a 100644 --- a/frontend/src/components/common/PageIntro.tsx +++ b/frontend/src/components/common/PageIntro.tsx @@ -17,29 +17,33 @@ export default function PageIntro({ actions?: PageIntroAction[] }) { return ( -
- {eyebrow ? ( -
- {eyebrow} +
+
+
+ {eyebrow ? ( +
+ {eyebrow} +
+ ) : null} +

{title}

+

+ {description} +

- ) : null} -

{title}

-

- {description} -

{actions.length > 0 ? ( -
+
{actions.map((action) => ( {action.label} ))}
) : null} -
+
+
) } diff --git a/frontend/src/pages/tokens/index.tsx b/frontend/src/pages/tokens/index.tsx index ad67f96..3cf8d4e 100644 --- a/frontend/src/pages/tokens/index.tsx +++ b/frontend/src/pages/tokens/index.tsx @@ -128,64 +128,28 @@ export default function TokensPage({ initialCuratedTokens }: TokensPageProps) { ]} /> - -
+ + setQuery(event.target.value)} placeholder="Token symbol, name, or contract address" - className="flex-1 rounded-lg border border-gray-300 px-4 py-2 focus:outline-none focus:ring-2 focus:ring-primary-500" + className="min-h-10 flex-1 rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary-500 dark:border-gray-700 dark:bg-gray-950" /> -

- Contract addresses open dedicated token detail pages with holders, transfers, provenance, and liquidity context. -

-
- -

- Review listed Chain 138 assets with provenance tags such as GRU, compliant, cW public-network, and reference asset before acting on a symbol match. -

-
- - Browse curated tokens โ†’ - -
-
- -

- Add Chain 138 and supported token metadata to MetaMask directly from the explorer wallet tools. -

-
- - Open wallet tools โ†’ - -
-
- -

- Review canonical PMM routes, partner payload templates, and token-routing examples for supported pools. -

-
- - Open liquidity access โ†’ - -
-
-
- -
+
-
+
{featuredCuratedTokens .filter((token): token is TokenListToken & { address: string } => typeof token.address === 'string' && token.address.trim().length > 0) .map((token) => { @@ -194,17 +158,29 @@ export default function TokensPage({ initialCuratedTokens }: TokensPageProps) { -
{token.symbol || token.name || 'Token'}
-

+

+
+
{token.symbol || token.name || 'Token'}
+

{token.name || 'Listed in the Chain 138 token registry.'} -

+

+
+
{market ? ( -
-
Live price: {formatUsd(market.priceUsd)}
-
Visible liquidity: {formatUsd(market.liquidityUsd)}
+
+
+
Price
+
{formatUsd(market.priceUsd)}
+
+
+
Liquidity
+
{formatUsd(market.liquidityUsd)}
+
+
+
) : null} {token.tags && token.tags.length > 0 && ( @@ -221,17 +197,17 @@ export default function TokensPage({ initialCuratedTokens }: TokensPageProps) {
-
+
-
+
{quickSearches.map((token) => (
{token.label}
-

{token.description}

+

{token.description}

))}
diff --git a/frontend/src/services/api/tokenAggregation.ts b/frontend/src/services/api/tokenAggregation.ts index 6512aac..80e1198 100644 --- a/frontend/src/services/api/tokenAggregation.ts +++ b/frontend/src/services/api/tokenAggregation.ts @@ -61,24 +61,76 @@ function toNumber(value: number | string | null | undefined): number | undefined return undefined } +function decimalStringToNumber(value: string | null | undefined, decimals: number | undefined): number | null { + if (!value || decimals == null || decimals < 0) return null + try { + const raw = BigInt(value) + if (raw <= 0n) return 0 + const scale = 10n ** BigInt(decimals) + const whole = raw / scale + const fraction = raw % scale + const normalized = Number(whole) + Number(fraction) / Number(scale) + return Number.isFinite(normalized) ? normalized : null + } catch { + return null + } +} + +function normalizePossiblyRawLiquidityUsd( + liquidityUsd: number | undefined, + totalSupply: string | null | undefined, + decimals: number | undefined, + priceUsd: number | undefined, +): number | undefined { + if (liquidityUsd == null || !(liquidityUsd > 0)) return liquidityUsd + if (!Number.isInteger(decimals) || decimals == null || decimals <= 0) return liquidityUsd + + const supplyUnits = decimalStringToNumber(totalSupply, decimals) + const price = priceUsd != null && priceUsd > 0 ? priceUsd : 1 + if (supplyUnits == null || supplyUnits <= 0) return liquidityUsd + + const plausibleSupplyValue = supplyUnits * price + const normalizedLiquidity = liquidityUsd / 10 ** decimals + + if ( + Number.isFinite(plausibleSupplyValue) && + Number.isFinite(normalizedLiquidity) && + liquidityUsd > plausibleSupplyValue && + normalizedLiquidity <= plausibleSupplyValue + ) { + return normalizedLiquidity + } + + return liquidityUsd +} + function normalizeTokenSnapshot(raw: RawTokenAggregationTokenResponse): TokenAggregationTokenSnapshot | null { const token = raw.token if (!token?.address) { return null } + const decimals = toNumber(token.decimals) + const priceUsd = toNumber(token.market?.priceUsd) + const liquidityUsd = normalizePossiblyRawLiquidityUsd( + toNumber(token.market?.liquidityUsd), + token.totalSupply, + decimals, + priceUsd, + ) + return { chainId: toNumber(token.chainId) ?? 138, address: token.address, name: token.name || undefined, symbol: token.symbol || undefined, - decimals: toNumber(token.decimals), + decimals, totalSupply: token.totalSupply || undefined, market: token.market ? { - priceUsd: toNumber(token.market.priceUsd), + priceUsd, volume24h: toNumber(token.market.volume24h), - liquidityUsd: toNumber(token.market.liquidityUsd), + liquidityUsd, lastUpdated: token.market.lastUpdated || null, } : null, diff --git a/frontend/src/services/api/tokens.test.ts b/frontend/src/services/api/tokens.test.ts index 7253a31..2e8a08a 100644 --- a/frontend/src/services/api/tokens.test.ts +++ b/frontend/src/services/api/tokens.test.ts @@ -29,11 +29,11 @@ describe('tokensApi', () => { symbol: 'cUSDT', name: 'Tether USD (Compliant)', decimals: 6, - totalSupply: '1000', + totalSupply: '928784229000000', market: { priceUsd: 1, volume24h: 2500, - liquidityUsd: 500000, + liquidityUsd: 2270037545568.842, lastUpdated: '2026-04-26T01:00:00.000Z', }, }, @@ -82,7 +82,7 @@ describe('tokensApi', () => { expect(token.data?.symbol).toBe('cUSDT') expect(token.data?.exchange_rate).toBe(1) expect(token.data?.volume_24h).toBe(2500) - expect(token.data?.liquidity_usd).toBe(500000) + expect(token.data?.liquidity_usd).toBe(2270037.545568842) expect(token.data?.price_source).toBe('token-aggregation') expect(holders.data[0].label).toBe('Treasury') expect(transfers.data[0].token_symbol).toBe('cUSDT') diff --git a/frontend/src/styles/globals.css b/frontend/src/styles/globals.css index 59414c4..ca01ae5 100644 --- a/frontend/src/styles/globals.css +++ b/frontend/src/styles/globals.css @@ -18,11 +18,9 @@ body { color: rgb(var(--foreground-rgb)); - background: linear-gradient( - to bottom, - transparent, - rgb(var(--background-end-rgb)) - ) - rgb(var(--background-start-rgb)); + background: #f8fafc; } +.dark body { + background: #030712; +}