Repository navigation
fix: read uptimePercentage/uptimeSeconds from /v1/validators/uptime - #43
Merged
Merged
Conversation
When the appMessage on a /icm/<messageId> view decodes as a recognized ICTT shape, replace the generic source↔destination card with three new sections: 1. Summary card — natural-language one-liner: "Account 0x… transferred N TOKEN from <source> to <dest> via Teleporter ICTT", with the amount formatted against the token's decimals (resolved via useToken on the destination-side TokenRemote contract). Falls back to the raw uint256 with a "(raw)" tag when token metadata isn't in firn's catalog yet — better than silently rendering 12400000000 as a human number. 2. Transfer flow visualization — three nodes (source → relayer → destination) with dashed-line connectors and a per-edge label (LOCK / DELIVER). Source-side timing is N/A because firn here only indexes the destination chain; DELIVER renders the gap between the Receive and MessageExecuted events when both fired in the same destination tx (always near-zero on canonical Teleporter delivery). 3. Overview field list — flattens the per-event cards' useful data into a single labeled list (Message ID, Source/Destination Chain, Token, Amount, Sender/Recipient, Source TX [N/A], Destination TX, Relayer, Reward redeemer, End-to-End). Marks source-only fields N/A with a muted color rather than hiding them. Falls through to the existing SidesCard + timeline for non-ICTT messages (raw Teleporter, custom dapps, Warp-only flows). The timeline below the new sections is unchanged — it still shows every event with full struct fields for users who want the raw data. Headline tag toggles "ICTT · INTERCHAIN TOKEN TRANSFER" vs "ICM · MESSAGE" based on whether the appMessage was recognized. Backend dependency: requires firn >= the icm topic0 + ictt enum + appMessage envelope-unwrap fixes (ava-labs/firn#50). Without those the appMessage on every Teleporter event renders as bare bytesHex and this page falls back to the generic view.
The ICTT preview was rendering the raw uint256 amount in scientific
notation (e.g. "1.4e14") with no token symbol — that's worse than
nothing because it suggests scale the user can't actually read.
Switch to a bulk-resolved token catalog: one useTokens({limit:50})
call at the home page level, address-keyed map passed down to every
row. Format precedence:
1. Catalog hit with decimals → "0.3 HERESY → 0x3c7a…fec"
2. Catalog hit, no decimals → "HERESY → 0x3c7a…fec" (drop amount)
3. Catalog miss → "SINGLE_HOP_SEND → 0x3c7a…fec"
Catalog hit rows render in full ink color so they pop visually; misses
fall back to muted ink-3 so the user can scan for material transfers.
Token lookup uses teleporterMessage.destinationAddress (the on-chain
TokenRemote that received the transfer — and on most ICTT deploys
that contract IS the ERC-20). Falls through cleanly when we're
looking at a Send-side or settlement-only event.
The L1UptimeEntry type was declaring `uptimePercent` and `uptime`,
but firn's /v1/validators/uptime is a verbatim passthrough of
subnet-evm's validators.getCurrentValidators which emits
`uptimePercentage` and `uptimeSeconds`. Every read against those
fields resolved to undefined, so every validator detail page rendered
"no uptime reported · subnet-evm tracks per-L1 uptime locally..." even
when the API was returning a healthy 100% uptime.
Verified live against grotto:
curl /v1/validators/uptime → {validators: [
{nodeID, validationID, weight, isActive: true, isConnected: true,
isL1Validator: true, uptimePercentage: 100, uptimeSeconds: ...},
...
]}
After the rename:
- L1UptimeEntry uses uptimePercentage / uptimeSeconds.
- Three consumers (home ValidatorsCard, /validators index, /validators/
[nodeID]) read the correct fields.
- Comment explains why the names match the upstream wire instead of
some normalized firn shape — firn doesn't rewrite this surface.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The L1UptimeEntry type was declaring
uptimePercentanduptime, but firn's/v1/validators/uptimeis a verbatim passthrough of subnet-evm'svalidators.getCurrentValidatorswhich emitsuptimePercentageanduptimeSeconds. Every read against the wrong field names resolved to undefined, so every validator detail page rendered the "no uptime reported · subnet-evm tracks per-L1 uptime locally..." fallback even when the API was returning a healthy 100%.Verified live against grotto
Changes
L1UptimeEntryusesuptimePercentage/uptimeSeconds.ValidatorsCard,/validatorsindex,/validators/[nodeID]) read the correct fields.Test plan
pnpm exec tsc --noEmitclean100% · via subnet-evm validators.getCurrentValidatorsinstead of the "no uptime reported" fallback