Adds `/:chain/about`, linked from the header just before the connection light and the theme toggle — it is about the site rather than the chain, so it sits there instead of in the section nav, and `header: true` on its `SECTIONS` entry keeps it out while still letting the URL parse. The page says what the observer is, that it and the CUDA-optimised miner are built and freely sourced by a member of the Quantus user community rather than by the project, and takes donations in QTC. **The QR is generated in the browser from the address printed beside it, never shipped as an image.** A supplied PNG next to a typed address is two independent claims about where money goes, and nothing on the page could tell a reader if they ever stopped agreeing — a mismatch sends funds somewhere unrecoverable. Verified rather than trusted. The address was put through this crate's own SS58 decoder: checksum and network prefix both hold, and it round-trips to the same string. The QR matrix was then decoded from first principles — function-pattern map, mask 3 unapplied, codewords de-interleaved across version 4-M's two blocks — and reads back the address exactly. A note for whoever checks this again: an independent encoder produces a different matrix for the same string at every mask, because mode segmentation differs, so comparing matrices proves nothing and only a decode does. `the_donation_address_on_the_site_is_a_valid_quantus_address` reads the literal out of the frontend source and validates it, so a typo fails CI rather than costing somebody their money. Confirmed to fail on one changed character. Also on the vesting page, from verifying it live: a "claimable now" figure and a per-grant claimable column. Two grants began vesting at launch while the other forty-six wait for 2027, so 68,871 QTC is already claimable and none of it has been taken — a page that only said "first claimable" would have missed it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
77 lines
2.5 KiB
TypeScript
77 lines
2.5 KiB
TypeScript
/**
|
|
* The site's sections.
|
|
*
|
|
* Every route this site has was reachable only by already knowing an address —
|
|
* a block hash, a preimage, an SS58 string, a spec_version. That is fine for a
|
|
* link somebody sent you and useless for finding out the pages exist at all.
|
|
* This is the answer to "what else is here".
|
|
*
|
|
* The standings are the first entry because they are the front page, and there
|
|
* is no "Miners" beside them for the same reason: the standings already are the
|
|
* index of miners, and a second page listing the same rows under a different
|
|
* address would be two answers to one question.
|
|
*/
|
|
|
|
import { Link } from 'react-router-dom'
|
|
|
|
import type { Window as WindowName } from '../api/generated/Window'
|
|
import { href, isStandings, type Route, SECTIONS } from '../lib/routes'
|
|
|
|
export function SectionNav({
|
|
chain,
|
|
route,
|
|
window: windowName,
|
|
}: {
|
|
chain: string | null
|
|
route: Route
|
|
/** Carried into the standings link so leaving a section and coming back does
|
|
* not silently reset the span someone chose. */
|
|
window: WindowName
|
|
}) {
|
|
if (!chain) return null
|
|
// The standings are current when nothing else is: no panel open, no index.
|
|
const onStandings = isStandings(route)
|
|
|
|
return (
|
|
<nav className="sections" aria-label="Section">
|
|
<Link
|
|
to={href({ chain, window: windowName })}
|
|
className="section-link"
|
|
aria-current={onStandings ? 'page' : undefined}
|
|
>
|
|
Standings
|
|
</Link>
|
|
{/* Straight to block zero. Endowments happen there and are invisible to
|
|
anyone who has not read the chainspec, so somebody who would never
|
|
think to look is given an unmissable way to. Not a `SECTIONS` entry
|
|
because it is not an index — it is one particular block. */}
|
|
<Link
|
|
to={href({ chain, block: '0' })}
|
|
className="section-link"
|
|
aria-current={route.block === '0' ? 'page' : undefined}
|
|
>
|
|
Genesis
|
|
</Link>
|
|
{SECTIONS.filter((s) => !s.header).map((s) => (
|
|
<Link
|
|
key={s.id}
|
|
to={href({ chain, index: s.id })}
|
|
className="section-link"
|
|
// A call's own page belongs to the Calls section, so the nav marks
|
|
// it there rather than nowhere.
|
|
aria-current={
|
|
route.index === s.id ||
|
|
(s.id === 'call' && route.call !== null) ||
|
|
(s.id === 'event' && route.event !== null) ||
|
|
(s.id === 'node' && route.node !== null)
|
|
? 'page'
|
|
: undefined
|
|
}
|
|
>
|
|
{s.label}
|
|
</Link>
|
|
))}
|
|
</nav>
|
|
)
|
|
}
|