Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/rpc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const (

// uses golang's semver naming convention
// https://pkg.go.dev/golang.org/x/mod/semver
SoftwareVersion = "v0.1.25+beta"
SoftwareVersion = "v0.1.26+beta"
ContentType = "Content-MessageType"
ApplicationJSON = "application/json; charset=utf-8"

Expand Down
39 changes: 1 addition & 38 deletions cmd/rpc/web/explorer/src/components/Home/Stages.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import { motion } from 'framer-motion'
import { useCardData } from '../../hooks/useApi'
import { usePersistentNumber } from '../../hooks/usePersistentNumber'
import { getTotalTransactionCount, getTotalAccountCount, Validators, ValidatorsWithFilters } from '../../lib/api'
import { getTotalTransactionCount, Validators, ValidatorsWithFilters } from '../../lib/api'
import { convertNumber, toCNPY } from '../../lib/utils'
import AnimatedNumber from '../AnimatedNumber'

Expand Down Expand Up @@ -67,20 +67,8 @@ const Stages = () => {
return toCNPY(Number(bonded) || 0)
}, [cardData])

const liquidSupplyCandidate: number | null = React.useMemo(() => {
if (!cardData) return null
const s = (cardData as any)?.supply || {}
const total = Number(s.total ?? 0)
const staked = Number(s.staked ?? 0)
if (total > 0) return toCNPY(Math.max(0, total - staked))
// fallback to other fields if they don't exist
const liquid = s.circulating ?? s.liquidSupply ?? s.liquid ?? 0
return toCNPY(Number(liquid) || 0)
}, [cardData])

// Async stats stay `null` until a fetch succeeds. We never reset them to a
// value on failure, so a transient RPC error can't blank the cards.
const [totalAccountsCandidate, setTotalAccountsCandidate] = React.useState<number | null>(null)
const [totalTxsCandidate, setTotalTxsCandidate] = React.useState<number | null>(null)
const [totalValidatingCandidate, setTotalValidatingCandidate] = React.useState<number | null>(null)
const [totalDelegatingCandidate, setTotalDelegatingCandidate] = React.useState<number | null>(null)
Expand All @@ -107,13 +95,6 @@ const Stages = () => {
}
}

try {
const accountStats = await getTotalAccountCount()
if (!cancelled) setTotalAccountsCandidate(accountStats.total)
} catch (error) {
console.error('Error fetching account stats:', error)
}

try {
const [validatorsStats, delegatorsStats] = await Promise.all([
Validators(1, 0),
Expand Down Expand Up @@ -145,8 +126,6 @@ const Stages = () => {
const latestBlockHeight = usePersistentNumber('blockHeight', latestBlockHeightCandidate)
const totalSupplyCNPY = usePersistentNumber('totalSupply', totalSupplyCandidate)
const totalStakeCNPY = usePersistentNumber('totalStake', totalStakeCandidate)
const liquidSupplyCNPY = usePersistentNumber('liquidSupply', liquidSupplyCandidate)
const totalAccounts = usePersistentNumber('totalAccounts', totalAccountsCandidate)
const totalTxs = usePersistentNumber('totalTxs', totalTxsCandidate)
const totalValidating = usePersistentNumber('totalValidating', totalValidatingCandidate)
const totalDelegating = usePersistentNumber('totalDelegating', totalDelegatingCandidate)
Expand All @@ -168,14 +147,6 @@ const Stages = () => {
icon: <i className="fa-solid fa-wallet"></i>,
metric: 'totalSupply',
},
{
title: 'Liquid Supply',
data: convertNumber(liquidSupplyCNPY.value),
loading: !liquidSupplyCNPY.hasValue,
subtitle: <p className={stageCardSubtitleClass}>CNPY</p>,
icon: <i className="fa-solid fa-droplet"></i>,
metric: 'liquidSupply',
},
{
title: 'Total Stake',
data: convertNumber(totalStakeCNPY.value),
Expand All @@ -200,14 +171,6 @@ const Stages = () => {
icon: <i className="fa-solid fa-coins"></i>,
metric: 'totalDelegating',
},
{
title: 'Total Accounts',
data: convertNumber(totalAccounts.value),
loading: !totalAccounts.hasValue,
icon: <i className="fa-solid fa-users"></i>,
metric: 'accounts',
subtitle: <p className={stageCardSubtitleClass}>Indexed accounts</p>,
},
{
title: 'Total Txs',
data: convertNumber(totalTxs.value),
Expand Down
70 changes: 6 additions & 64 deletions cmd/rpc/web/explorer/src/components/staking/SupplyView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,40 +29,22 @@ const SupplyView: React.FC = () => {
return toCNPY(Number(bonded))
}, [cardData])

const liquidSupplyCandidate = React.useMemo(() => {
if (!cardData) return null
const s = (cardData as any)?.supply || {}
const total = Number(s.total ?? 0)
const staked = Number(s.staked ?? 0)
if (total > 0) return Math.max(0, toCNPY(total - staked))
const liquid = s.circulating ?? s.liquidSupply ?? s.liquid ?? 0
return toCNPY(Number(liquid))
}, [cardData])

const totalSupply = usePersistentNumber('totalSupply', totalSupplyCandidate)
const stakedSupply = usePersistentNumber('totalStake', stakedSupplyCandidate)
const liquidSupply = usePersistentNumber('liquidSupply', liquidSupplyCandidate)

const totalSupplyCNPY = totalSupply.value
const stakedSupplyCNPY = stakedSupply.value
const liquidSupplyCNPY = liquidSupply.value

// First-ever load (no cached value yet) → show "Loading…" instead of 0.
const isSupplyLoading = !totalSupply.hasValue
const isStakedLoading = !stakedSupply.hasValue
const isLiquidLoading = !liquidSupply.hasValue
const LoadingValue = () => <span className="text-white/40">Loading…</span>

const stakingRatio = React.useMemo(() => {
if (totalSupplyCNPY <= 0) return 0
return Math.max(0, Math.min(100, (stakedSupplyCNPY / totalSupplyCNPY) * 100))
}, [stakedSupplyCNPY, totalSupplyCNPY])

const liquidRatio = React.useMemo(() => {
if (totalSupplyCNPY <= 0) return Math.max(0, 100 - stakingRatio)
return Math.max(0, Math.min(100, (liquidSupplyCNPY / totalSupplyCNPY) * 100))
}, [liquidSupplyCNPY, stakingRatio, totalSupplyCNPY])

const supplyMetrics = [
{
title: 'Total',
Expand Down Expand Up @@ -92,20 +74,6 @@ const SupplyView: React.FC = () => {
subValue: 'CNPY',
icon: 'fa-solid fa-coins',
},
{
title: 'Liquid',
value: isLiquidLoading ? (
<LoadingValue />
) : (
<AnimatedNumber
value={liquidSupplyCNPY}
format={{ minimumFractionDigits: 2, maximumFractionDigits: 2 }}
className="text-white"
/>
),
subValue: 'CNPY',
icon: 'fa-solid fa-water',
},
{
title: 'Staking Ratio',
value: isSupplyLoading || isStakedLoading ? (
Expand Down Expand Up @@ -156,26 +124,14 @@ const SupplyView: React.FC = () => {
<span>Staked {stakingRatio.toFixed(2)}%</span>
</div>
<div className="text-xs uppercase tracking-[0.2em] text-gray-500">of total supply</div>
<div className="flex items-center gap-2 text-[#216cd0]">
<span>Liquid {liquidRatio.toFixed(2)}%</span>
<span className="h-2 w-2 rounded-full bg-[#216cd0]" />
</div>
</div>
<div className="overflow-hidden rounded-full bg-white/10">
<div className="flex h-3 w-full">
<motion.div
className="bg-[#35cd48]"
initial={{ width: 0 }}
animate={{ width: `${stakingRatio}%` }}
transition={{ duration: 1, delay: 0.5 }}
/>
<motion.div
className="bg-[#216cd0]"
initial={{ width: 0 }}
animate={{ width: `${liquidRatio}%` }}
transition={{ duration: 1, delay: 0.7 }}
/>
</div>
<motion.div
className="h-3 bg-[#35cd48]"
initial={{ width: 0 }}
animate={{ width: `${stakingRatio}%` }}
transition={{ duration: 1, delay: 0.5 }}
/>
</div>
</div>
</motion.div>
Expand Down Expand Up @@ -217,20 +173,6 @@ const SupplyView: React.FC = () => {
)}
</span>
</div>
<div className="flex justify-between items-center">
<span className="text-gray-400">Liquid</span>
<span className="font-medium text-[#216cd0]">
{isLiquidLoading ? <LoadingValue /> : (
<>
<AnimatedNumber
value={liquidSupplyCNPY}
format={{ maximumFractionDigits: 0 }}
className="text-[#216cd0]"
/> CNPY
</>
)}
</span>
</div>
</div>
</div>
</motion.div>
Expand Down
3 changes: 0 additions & 3 deletions cmd/rpc/web/explorer/src/data/stages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
{ "title": "Staking %", "metric": "stakingPercent", "icon": "fa-solid fa-chart-pie", "progress": true },
{ "title": "CNPY Staking", "metric": "cnpyStakingDelta", "icon": "fa-solid fa-coins", "subtitle": "delta" },
{ "title": "Total Supply", "metric": "totalSupply", "icon": "fa-solid fa-wallet", "subtitle": "cnpy" },
{ "title": "Liquid Supply", "metric": "liquidSupply", "icon": "fa-solid fa-droplet", "subtitle": "cnpy" },
{ "title": "Blocks", "metric": "blocks", "icon": "fa-solid fa-cube", "subtitle": "live" },
{ "title": "Total Stake", "metric": "totalStake", "icon": "fa-solid fa-lock", "subtitle": "cnpy" },
{ "title": "Total Accounts", "metric": "accounts", "icon": "fa-solid fa-users", "subtitle": "last24h" },
{ "title": "Total Txs", "metric": "txs", "icon": "fa-solid fa-arrow-right-arrow-left", "subtitle": "last24h" }
]

1 change: 0 additions & 1 deletion cmd/rpc/web/explorer/src/data/staking.json
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,6 @@
"metrics": {
"totalSupply": "Total Supply",
"stakedSupply": "Staked Supply",
"liquidSupply": "Liquid Supply",
"stakingRatio": "Staking Ratio"
},
"table": {
Expand Down
Loading