Copy only, from origin/master c077caa (the fleet's record: docs/analysis/prover-tiers-real-cards.md and the bench-log
entry "Prover tiers on real cards"). The miner hero lead, the proving feat and the homepage lead each carry two
sentences: today's app with the stock SP1 server (a 24 GB NVIDIA card proves the full shard, RTX 4090 5.6 s and
RTX A5000 6.4 s; a 32 GB card mines and proves, RTX 5090 8.4 s; the stock server refuses 16 GB and under), and the
6 October 2026 measurement on eleven rented cards with the patched server (every NVIDIA card from 8 GB proves; 10 GB
and up mine and prove), linked to the bench-log entry and marked "ships when the packaging row lands".
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
935 lines
87 KiB
HTML
935 lines
87 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
<title>Igneum, the GPU-mined layer 1</title>
|
|
<meta name="description" content="A GPU-mined chain whose mining program rewrites itself every hour. Miners also prove the blocks. No premine, no stake, no fee to any team.">
|
|
<link rel="canonical" href="https://igneum.network/">
|
|
<meta name="theme-color" content="#0C0C0E">
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:site_name" content="Igneum">
|
|
<meta property="og:title" content="Igneum, the GPU-mined layer 1">
|
|
<meta property="og:description" content="A GPU-mined chain whose mining program rewrites itself every hour. Miners also prove the blocks. No premine, no stake, no fee to any team.">
|
|
<meta property="og:url" content="https://igneum.network/">
|
|
<meta property="og:image" content="https://igneum.network/og-small.png?v=3">
|
|
<meta property="og:image:width" content="256">
|
|
<meta property="og:image:height" content="256">
|
|
<meta property="og:image:alt" content="Igneum. Mined by GPUs. Proven by fire.">
|
|
<meta name="twitter:card" content="summary">
|
|
<meta name="twitter:title" content="Igneum, the GPU-mined layer 1">
|
|
<meta name="twitter:description" content="A GPU-mined chain whose mining program rewrites itself every hour. Miners also prove the blocks. No premine, no stake, no fee to any team.">
|
|
<meta name="twitter:image" content="https://igneum.network/og-small.png?v=3">
|
|
<meta name="twitter:image:alt" content="Igneum. Mined by GPUs. Proven by fire.">
|
|
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1024 1024'%3E%3Crect width='1024' height='1024' fill='%230C0C0E'/%3E%3Cg transform='translate(166.95 166.95) scale(6.901)'%3E%3Cpolygon points='50,4 74,34 67,58 80,54 61,96 39,96 20,54 33,58 26,34' fill='%23F2541B'/%3E%3Cpolygon points='50,42 59,58 50,82 41,58' fill='%230C0C0E'/%3E%3C/g%3E%3C/svg%3E" type="image/svg+xml">
|
|
<link rel="icon" href="/favicon.ico" sizes="48x48">
|
|
<link rel="icon" href="/favicon-32.png" type="image/png" sizes="32x32">
|
|
<link rel="icon" href="/icon-192.png" type="image/png" sizes="192x192">
|
|
<link rel="icon" href="/icon-512.png" type="image/png" sizes="512x512">
|
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180">
|
|
<link rel="manifest" href="/site.webmanifest">
|
|
<script type="application/ld+json">
|
|
{"@context":"https://schema.org","@type":"Organization","name":"Igneum","url":"https://igneum.network/","logo":"https://igneum.network/icon-512.png","sameAs":["https://github.com/igneum-network"]}
|
|
</script>
|
|
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin>
|
|
<!-- head:start -->
|
|
<link rel="preload" href="/fonts/unbounded-900.woff2" as="font" type="font/woff2" crossorigin>
|
|
<link rel="preload" href="/fonts/plex-sans-400.woff2" as="font" type="font/woff2" crossorigin>
|
|
<style>
|
|
/* Shared by every page. Source: site/partials/head.html, injected by site/build.mjs between the head markers. Edit the partial, not the page. */
|
|
/* Fonts, self-hosted (latin subsets, OFL): Unbounded 500/700/900, IBM Plex Sans 400/500/600, IBM Plex Mono 400/500. Fallbacks carry size and ascent overrides so the swap does not move the layout. */
|
|
@font-face{font-family:'Unbounded';font-style:normal;font-weight:500;font-display:swap;src:url(/fonts/unbounded-500.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
|
|
@font-face{font-family:'Unbounded';font-style:normal;font-weight:700;font-display:swap;src:url(/fonts/unbounded-700.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
|
|
@font-face{font-family:'Unbounded';font-style:normal;font-weight:900;font-display:swap;src:url(/fonts/unbounded-900.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
|
|
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/plex-sans-400.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
|
|
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:500;font-display:swap;src:url(/fonts/plex-sans-500.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
|
|
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/plex-sans-600.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
|
|
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/plex-mono-400.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
|
|
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url(/fonts/plex-mono-500.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
|
|
@font-face{font-family:'Unbounded Fallback';src:local('Arial Black'),local('Arial-Black'),local('Impact');size-adjust:114%;ascent-override:87.5%;descent-override:21.5%;line-gap-override:0%}
|
|
@font-face{font-family:'Plex Sans Fallback';src:local('Arial'),local('Helvetica Neue'),local('Helvetica');size-adjust:100.5%;ascent-override:102%;descent-override:27.4%;line-gap-override:0%}
|
|
@font-face{font-family:'Plex Mono Fallback';src:local('Courier New'),local('Menlo');size-adjust:100%;ascent-override:102.5%;descent-override:27.5%;line-gap-override:0%}
|
|
:root{--f-sans:'IBM Plex Sans','Plex Sans Fallback',system-ui,-apple-system,sans-serif;--f-display:'Unbounded','Unbounded Fallback',sans-serif;--f-mono:'IBM Plex Mono','Plex Mono Fallback',ui-monospace,Menlo,monospace;
|
|
/* site chrome tokens (nav, footer, skip link). Dark by default; the litepaper sets light values and resets these in dark mode */
|
|
--nav-h:68px;--ui-bg:rgba(12,12,14,.84);--ui-menu:#0C0C0E;--ui-ink:#F4F1EC;--ui-ink-2:#C9C7C2;--ui-ash:#9A9A9E;--ui-line:#2A2A30;--ui-line-2:#3A3A42;--ui-accent:#F2541B;--ui-accent-ink:#0C0C0E;--ui-hot:#FFB35C;--ui-hover:#FF6A2B;--ui-tint:rgba(242,84,27,.12)}
|
|
html{-webkit-text-size-adjust:100%}
|
|
h1,h2,h3{text-wrap:balance}
|
|
p,li,dd,figcaption{text-wrap:pretty}
|
|
a:focus-visible,button:focus-visible,summary:focus-visible,[tabindex]:focus-visible{outline:2px solid var(--ui-accent);outline-offset:3px;border-radius:6px}
|
|
.skip{position:absolute;left:12px;top:-80px;z-index:50;background:var(--ui-accent);color:var(--ui-accent-ink);padding:10px 14px;border-radius:10px;font:600 15px/1.2 var(--f-sans);text-decoration:none}
|
|
.skip:focus{top:12px}
|
|
/* nav: one bar on every page, the mark in its black square, seven links and the miner button, a menu under 941 px (the eight items need 688 px beside the brand at 15 px, so the bar fits from 941 px up without a wrapped label) */
|
|
.nav{position:sticky;top:0;z-index:20;background:var(--ui-bg);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border-bottom:1px solid var(--ui-line);color:var(--ui-ink)}
|
|
.nav .wrap{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:var(--nav-h)}
|
|
.nav a{color:inherit;text-decoration:none}
|
|
.brand{display:inline-flex;align-items:center;gap:10px;color:var(--ui-ink);text-decoration:none;flex:0 0 auto}
|
|
.brand .mark{display:block;flex:0 0 auto}
|
|
.brand .word{font-family:var(--f-display);font-weight:900;font-size:20px;letter-spacing:.06em;line-height:1}
|
|
.nav .links{display:flex;align-items:center;gap:clamp(14px,2vw,26px);font-size:15px;font-weight:500}
|
|
.nav .links a{color:var(--ui-ink-2);padding:4px 0;border-bottom:2px solid transparent;white-space:nowrap;transition:color .15s ease,border-color .15s ease}
|
|
.nav .links a:hover,.nav .brand:hover{color:var(--ui-hot);text-decoration:none}
|
|
.nav .brand:hover{color:var(--ui-ink)}
|
|
.nav .links a[aria-current="page"]{color:var(--ui-ink);border-bottom-color:var(--ui-accent)}
|
|
.nav .links a.cta{display:inline-flex;align-items:center;justify-content:center;min-height:40px;padding:8px 16px;border-radius:10px;font-weight:600;background:var(--ui-accent);color:var(--ui-accent-ink);border:1px solid var(--ui-accent);transition:background .15s ease,transform .15s ease}
|
|
.nav .links a.cta:hover{background:var(--ui-hover);border-color:var(--ui-hover);color:var(--ui-accent-ink);transform:translateY(-1px)}
|
|
.burger{display:none;background:none;border:1px solid var(--ui-line-2);color:var(--ui-ink);border-radius:10px;width:44px;height:44px;align-items:center;justify-content:center;cursor:pointer;padding:0;flex:0 0 auto}
|
|
.burger .x{display:none}.burger[aria-expanded="true"] .x{display:block}.burger[aria-expanded="true"] .bars{display:none}
|
|
@media (max-width:940px){
|
|
.nav .links{display:none;position:absolute;left:0;right:0;top:100%;background:var(--ui-menu);border-bottom:1px solid var(--ui-line);box-shadow:0 24px 40px rgba(0,0,0,.35);padding:10px var(--gutter,16px) 18px;flex-direction:column;align-items:stretch;gap:2px}
|
|
.nav .links a{padding:13px 10px;border-radius:10px;border-bottom:0;font-size:16px}
|
|
.nav .links a[aria-current="page"]{background:var(--ui-tint)}
|
|
.nav .links a.cta{margin-top:8px;min-height:48px}
|
|
.nav .links.open{display:flex}
|
|
.burger{display:inline-flex}
|
|
}
|
|
/* footer, the same on every page */
|
|
.foot{border-top:1px solid var(--ui-line);color:var(--ui-ink);margin-top:var(--sec,64px)}
|
|
.foot .wrap{padding-block:48px 32px}
|
|
.foot-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,200px),1fr));gap:32px}
|
|
.foot-brand{display:flex;flex-direction:column;gap:12px;max-width:34ch}
|
|
.foot-brand .brand{align-self:flex-start}.foot-brand .word{font-size:16px}
|
|
.foot-brand p{color:var(--ui-ash);font-size:14px;margin:0}
|
|
.foot-col{display:flex;flex-direction:column;gap:10px;font-size:15px}
|
|
.foot-col .eyebrow{font-family:var(--f-mono);font-size:12px;letter-spacing:.18em;text-transform:uppercase;color:var(--ui-ash);margin-bottom:4px}
|
|
.foot-col a{color:var(--ui-ink-2);text-decoration:none;display:inline-flex;align-items:center;gap:6px;align-self:flex-start}
|
|
.foot-col a:hover{color:var(--ui-hot);text-decoration:none}
|
|
.foot-base{display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px 24px;margin-top:36px;padding-top:20px;border-top:1px solid var(--ui-line);font-size:13px;color:var(--ui-ash)}
|
|
.foot-base span{text-wrap:balance}.foot-base .mono{font-family:var(--f-mono)}
|
|
.foot-imprint{flex-basis:100%;text-wrap:pretty}.foot-base a{color:inherit;text-decoration:none}.foot-base a:hover{color:var(--ui-hot)}
|
|
@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}}
|
|
</style>
|
|
<!-- head:end -->
|
|
<style>
|
|
:root{--obsidian:#0C0C0E;--graphite:#16161A;--line:#2A2A30;--line-2:#3A3A42;--ember:#F2541B;--molten:#FFB35C;--bone:#F4F1EC;--ash:#9A9A9E;--ink-2:#C9C7C2;--ember-ink:#0C0C0E;
|
|
/* one system for every page: container, gutter, section rhythm, card and tile boxes, heading scale */
|
|
--max:1200px;--gutter:clamp(16px,4vw,32px);--sec:clamp(56px,8vw,96px);--head:clamp(40px,6vw,64px);
|
|
--card-pad:clamp(18px,3vw,28px);--card-r:18px;--tile-pad:18px 20px;--tile-r:14px;--gap:24px;--gap-tile:12px;
|
|
--fs-hero:clamp(32px,8.4vw,76px);--fs-h1:clamp(32px,5.5vw,56px);--fs-h2:clamp(28px,4.2vw,44px);--fs-h3:clamp(18px,2vw,22px);--fs-tile:clamp(20px,2.2vw,26px)}
|
|
*{box-sizing:border-box}
|
|
html{scroll-behavior:smooth}
|
|
/* anchors land with the heading 11 px under the sticky bar at every width: a padded section subtracts its own top padding */
|
|
:root{--sm:84px}
|
|
@media (max-width:900px){:root{--sm:80px}}
|
|
section,[id]{scroll-margin-top:var(--sm)}
|
|
section[id]{scroll-margin-top:calc(var(--sm) - var(--sec))}
|
|
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
|
|
body{margin:0;background:var(--obsidian);color:var(--bone);font-family:var(--f-sans);font-size:17px;line-height:1.55;-webkit-font-smoothing:antialiased;overflow-x:hidden}
|
|
a{color:inherit;text-decoration:none}
|
|
a:hover{color:var(--molten)}
|
|
a:focus-visible,button:focus-visible{outline:2px solid var(--ember);outline-offset:3px;border-radius:6px}
|
|
img,svg,canvas{max-width:100%}
|
|
.wrap{max-width:var(--max);margin:0 auto;padding-inline:var(--gutter)}
|
|
.mono{font-family:var(--f-mono)}
|
|
.eyebrow{font-family:var(--f-mono);font-size:12px;letter-spacing:.18em;text-transform:uppercase;color:var(--ash)}
|
|
.eyebrow.ember{color:var(--ember)}
|
|
h1,h2,h3{font-family:var(--f-display);margin:0;line-height:1.08;text-wrap:balance}
|
|
h1{font-weight:900;font-size:var(--fs-hero);letter-spacing:-.01em}
|
|
h2{font-weight:700;font-size:var(--fs-h2)}
|
|
h3{font-weight:700;font-size:var(--fs-h3)}
|
|
p{margin:0}
|
|
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:48px;padding:12px 22px;border-radius:10px;font-weight:600;font-size:16px;border:1px solid var(--line-2);color:var(--bone);background:transparent;cursor:pointer;transition:transform .15s ease,background .15s ease,border-color .15s ease}
|
|
.btn:hover{transform:translateY(-1px);border-color:var(--ash);color:var(--bone)}
|
|
.btn.primary{background:var(--ember);color:var(--ember-ink);border-color:var(--ember)}
|
|
.btn.primary:hover{background:#FF6A2B;border-color:#FF6A2B;color:var(--ember-ink)}
|
|
.btn.dark{background:var(--obsidian);color:var(--bone);border-color:var(--obsidian)}
|
|
.btn.dark:hover{background:#222226;color:var(--bone)}
|
|
.card{background:var(--graphite);border:1px solid var(--line);border-radius:var(--card-r);padding:var(--card-pad);min-width:0}
|
|
.grid{display:grid;gap:var(--gap);grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr))}
|
|
.reveal{opacity:0;transform:translateY(18px);transition:opacity .7s ease,transform .7s ease}
|
|
.reveal.in{opacity:1;transform:none}
|
|
@media (prefers-reduced-motion:reduce){.reveal{opacity:1;transform:none;transition:none}}
|
|
|
|
/* nav and footer: shared, see site/partials */
|
|
|
|
/* hero */
|
|
.hero{position:relative;padding-block:clamp(56px,9vw,112px) clamp(40px,6vw,72px);overflow:hidden}
|
|
.hero canvas{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;-webkit-mask-image:linear-gradient(90deg,rgba(0,0,0,.08) 0,rgba(0,0,0,.35) 45%,rgba(0,0,0,.9) 100%);mask-image:linear-gradient(90deg,rgba(0,0,0,.08) 0,rgba(0,0,0,.35) 45%,rgba(0,0,0,.9) 100%)}
|
|
@media (max-width:979px){.hero canvas{-webkit-mask-image:linear-gradient(180deg,rgba(0,0,0,.12) 0,rgba(0,0,0,.12) 55%,rgba(0,0,0,.8) 100%);mask-image:linear-gradient(180deg,rgba(0,0,0,.12) 0,rgba(0,0,0,.12) 55%,rgba(0,0,0,.8) 100%)}}
|
|
.hero .wrap{position:relative;display:grid;gap:32px;grid-template-columns:1fr;align-items:center}
|
|
@media (min-width:980px){.hero .wrap{grid-template-columns:1.15fr .85fr;gap:32px 56px}}
|
|
.hero-copy{display:flex;flex-direction:column;gap:24px;container-type:inline-size}
|
|
/* the headline is two lines at every width: the size is capped so "Mined by GPUs." fits the column (Unbounded 900 runs about 0.78 em per character) */
|
|
.hero-copy h1{font-size:min(var(--fs-hero),9cqw)}
|
|
.hero p.lead{font-size:clamp(17px,2vw,20px);color:var(--ink-2);max-width:56ch}
|
|
.cta{display:flex;flex-wrap:wrap;gap:12px}
|
|
/* live stats strip: hidden until the observer reports fresh numbers; spans the full hero width, tiles share the economics tile spec */
|
|
.livestrip{display:none;flex-direction:column;gap:var(--gap-tile);grid-column:1/-1;min-width:0}
|
|
.livestrip.on{display:flex}
|
|
.livestrip-head{display:flex;align-items:center;gap:8px;font-family:var(--f-mono);font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--molten)}
|
|
.livestrip-head a{color:var(--molten)}
|
|
.livestrip-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--gap-tile)}
|
|
.livestrip .tile .v{white-space:nowrap;font-variant-numeric:tabular-nums}
|
|
@media (max-width:700px){.livestrip-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
|
|
.verify{display:flex;flex-direction:column;gap:18px}
|
|
.verify-head{display:flex;justify-content:space-between;align-items:center;gap:12px}
|
|
.live{display:inline-flex;align-items:center;gap:8px;font-family:var(--f-mono);font-size:12px;color:var(--molten)}
|
|
.dot{width:8px;height:8px;border-radius:50%;background:var(--molten);display:inline-block;animation:pulse 2s ease-in-out infinite}
|
|
@keyframes pulse{0%,100%{box-shadow:0 0 0 0 rgba(255,179,92,.5)}50%{box-shadow:0 0 0 8px rgba(255,179,92,0)}}
|
|
.verify-row{display:flex;align-items:center;gap:16px}
|
|
.tick{width:56px;height:56px;border-radius:50%;background:var(--ember);display:flex;align-items:center;justify-content:center;flex:0 0 56px}
|
|
.tick svg path{stroke-dasharray:30;stroke-dashoffset:30;animation:draw 1s .4s ease forwards}
|
|
@keyframes draw{to{stroke-dashoffset:0}}
|
|
.verify-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}
|
|
.cell{background:var(--obsidian);border-radius:12px;padding:14px;display:flex;flex-direction:column;gap:4px}
|
|
.cell .k{font-family:var(--f-mono);font-size:11px;letter-spacing:.12em;color:var(--ash)}
|
|
.cell .v{font-family:var(--f-mono);font-size:15px}
|
|
|
|
/* stats */
|
|
.stats{border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
|
|
.stats .wrap{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:20px 24px;padding-block:28px}
|
|
.stat .v{font-family:var(--f-display);font-weight:700;font-size:var(--fs-tile);color:var(--ember);line-height:1.1}
|
|
.stat .k{margin-top:6px;font-size:14px;color:var(--ash);line-height:1.35;text-wrap:balance}
|
|
|
|
/* rhythm: every section keeps --sec from its content to the next boundary; two dark sections in a row share one */
|
|
section{padding-block:var(--sec)}
|
|
section:not(.light)+section:not(.light){padding-top:0;scroll-margin-top:var(--sm)}
|
|
.sec-head{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:16px;margin-bottom:32px}
|
|
.sec-head p{font-size:16px;color:var(--ash);max-width:46ch}
|
|
|
|
/* dag */
|
|
.viz{overflow:hidden}
|
|
.viz-head{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:10px 20px;margin-bottom:12px}
|
|
.viz-stats{display:flex;gap:18px;font-size:12px;color:var(--ash)}
|
|
.viz-stats b{color:var(--bone);font-weight:500;font-variant-numeric:tabular-nums}
|
|
#chain{display:block;width:100%;height:clamp(200px,36vw,340px);border-radius:12px;background:var(--obsidian)}
|
|
.dag{overflow:hidden}
|
|
.dag-rows{display:flex;flex-direction:column;gap:var(--dg,14px);--bs:34px;--dg:14px}
|
|
@media (max-width:640px){.dag-rows{--bs:26px;--dg:9px}}
|
|
.dag-row{display:flex;gap:var(--dg);align-items:center;overflow:hidden}
|
|
.blk{width:var(--bs);height:var(--bs);flex:0 0 var(--bs);border-radius:calc(var(--bs) * .24);border:2px solid var(--line-2);transition:background .5s ease,border-color .5s ease,transform .3s ease}
|
|
.blk.proving{background:var(--molten);border-color:var(--molten)}
|
|
.blk.proven{background:var(--ember);border-color:var(--ember)}
|
|
.blk.lock{border-color:var(--ember);background:transparent;display:flex;align-items:center;justify-content:center}
|
|
.blk.lock svg{width:50%;height:50%}
|
|
.blk.new{animation:pop .4s ease}
|
|
@keyframes pop{from{transform:scale(.4);opacity:0}to{transform:scale(1);opacity:1}}
|
|
.legend{display:flex;flex-wrap:wrap;gap:20px;margin-top:24px;font-size:14px;color:var(--ink-2)}
|
|
.viz-note{margin:14px 0 0;font-size:13px;line-height:1.5;color:var(--ash);max-width:80ch}
|
|
.legend[hidden]{display:none}
|
|
.legend span{display:inline-flex;align-items:center;gap:8px}
|
|
.sw{width:14px;height:14px;border-radius:4px;display:inline-block}
|
|
pre{margin:0;font-family:var(--f-mono);font-size:13px;line-height:1.6;color:var(--ink-2);white-space:pre-wrap;min-height:9.6em}
|
|
.caret::after{content:'▍';color:var(--ember);animation:blink 1s steps(1) infinite}
|
|
@keyframes blink{50%{opacity:0}}
|
|
.feed{display:flex;flex-direction:column;gap:10px;font-family:var(--f-mono);font-size:13px;color:var(--ink-2)}
|
|
.feed div{display:flex;justify-content:space-between;gap:12px;border-bottom:1px solid var(--line);padding-bottom:8px}
|
|
.feed div:last-child{border-bottom:0}
|
|
|
|
/* jobs cards */
|
|
.jobs{display:grid;gap:var(--gap);grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr))}
|
|
.job{display:flex;flex-direction:column;gap:14px;border:1px solid var(--line);border-radius:var(--card-r);padding:var(--card-pad);transition:border-color .2s ease,transform .2s ease}
|
|
.job:hover{border-color:var(--line-2);transform:translateY(-2px)}
|
|
.job p{font-size:15px;color:var(--ink-2)}
|
|
.job a.more{color:var(--ember);font-weight:600;font-size:15px}
|
|
.pt{font-size:15px;color:var(--ash);max-width:60ch}
|
|
.lp{display:inline-block;margin-top:24px;color:var(--ember);font-weight:600;font-size:15px}
|
|
.light .pt{color:#55534F}
|
|
.cmp{border-collapse:collapse;width:100%;font-size:15px}
|
|
.cmp th,.cmp td{text-align:left;padding:12px 20px;border-top:1px solid var(--line)}
|
|
.cmp thead tr{background:var(--obsidian)}
|
|
.cmp th{border-top:0}
|
|
@media (max-width:480px){.cmp th,.cmp td{padding:10px 12px;font-size:14px}}
|
|
|
|
/* miners */
|
|
.light{background:var(--bone);color:var(--obsidian)}
|
|
.light .card{background:#fff;border-color:#E4E0D8}
|
|
.light .sec-head p{color:#55534F}
|
|
.light .eyebrow{color:#7A776F}
|
|
.light .job p{color:#3D3B37}
|
|
|
|
/* product summaries: a framed screenshot beside the copy, mirrored for the wallet */
|
|
.split{display:grid;gap:var(--gap);grid-template-columns:1fr;align-items:center}
|
|
@media (min-width:980px){.split{grid-template-columns:1.1fr .9fr;gap:32px 56px}.split.rev{grid-template-columns:.9fr 1.1fr}}
|
|
.split-copy{min-width:0}
|
|
.shot{position:relative;min-width:0}
|
|
.shot::before{content:'';position:absolute;inset:12% -6% -8% -6%;background:radial-gradient(closest-side,rgba(242,84,27,.22),rgba(242,84,27,0));filter:blur(12px);pointer-events:none}
|
|
.frame{position:relative;border:1px solid var(--line-2);border-radius:16px;background:#0C0C0E;box-shadow:0 30px 80px rgba(0,0,0,.55);overflow:hidden;color:var(--bone)}
|
|
.light .frame{box-shadow:0 30px 80px rgba(12,12,14,.28)}
|
|
.frame .bar{height:32px;display:flex;align-items:center;gap:7px;padding:0 14px;border-bottom:1px solid var(--line);background:#121215}
|
|
.frame .bar i{width:10px;height:10px;border-radius:50%;background:#2A2A30;display:block}
|
|
.frame .bar b{margin-left:auto;font:500 11px/1 var(--f-mono);letter-spacing:.12em;color:var(--ash);text-transform:uppercase}
|
|
.frame img{display:block;width:100%;height:auto}
|
|
.frame figcaption{padding:10px 14px;font-size:13px;color:var(--ash);border-top:1px solid var(--line);background:#0C0C0E}
|
|
.pills{display:flex;flex-direction:column;gap:10px}
|
|
.pill{display:flex;flex-direction:column;gap:2px;padding:12px 16px;border:1px solid var(--line);border-radius:var(--tile-r);background:var(--graphite);font-size:15px}
|
|
.pill b{font-weight:600}.pill span{font-size:14px;color:var(--ash);line-height:1.4}
|
|
.light .pill{background:#fff;border-color:#E4E0D8}.light .pill span{color:#55534F}
|
|
.states{display:flex;flex-wrap:wrap;gap:10px}
|
|
.state{display:flex;flex-direction:column;gap:6px;flex:1 1 150px;min-width:0;padding:12px 14px;border:1px solid var(--line);border-radius:var(--tile-r);background:var(--graphite);font-size:13px;color:var(--ash)}
|
|
.spill{display:inline-flex;align-items:center;gap:8px;align-self:flex-start;white-space:nowrap;font-family:var(--f-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;padding:5px 9px;border-radius:999px;border:1px solid var(--line-2);color:var(--ash)}
|
|
.spill i{width:7px;height:7px;border-radius:50%;background:var(--ash);display:inline-block}
|
|
.state.block .spill{border-color:rgba(255,179,92,.5);color:var(--molten)}.state.block .spill i{background:var(--molten)}
|
|
.state.final .spill{border-color:var(--ember);background:var(--ember);color:var(--ember-ink)}.state.final .spill i{background:var(--ember-ink)}
|
|
|
|
/* journey */
|
|
.journey{display:grid;gap:var(--gap-tile);grid-template-columns:repeat(auto-fit,minmax(min(100%,280px),1fr))}
|
|
.phase{border:1px solid var(--line);border-radius:var(--tile-r);padding:var(--tile-pad);display:flex;flex-direction:column;gap:6px;position:relative;transition:border-color .2s ease;min-width:0}
|
|
.phase .w{font-family:var(--f-mono);font-size:11px;color:var(--ash)}
|
|
.phase .n{font-weight:600;font-size:15px;text-wrap:balance}
|
|
.phase .g{font-size:12px;color:var(--ash);line-height:1.4;text-wrap:balance}
|
|
.phase.done{border-color:var(--line-2)}
|
|
.phase.done .n::after{content:' ✓';color:var(--molten)}
|
|
.phase.active{border:2px solid var(--ember);box-shadow:0 0 0 0 rgba(242,84,27,.35);animation:glow 2.4s ease-in-out infinite}
|
|
@keyframes glow{50%{box-shadow:0 0 0 10px rgba(242,84,27,0)}}
|
|
.phase.active .w{color:var(--ember)}
|
|
.now{display:inline-flex;align-items:flex-start;gap:8px;font-family:var(--f-mono);font-size:11px;line-height:1.5;color:var(--ember);letter-spacing:.12em;text-wrap:balance}
|
|
.now .dot{margin-top:4px}
|
|
.log{display:flex;flex-direction:column;gap:0;margin-top:var(--gap);border:1px solid var(--line);border-radius:var(--card-r);background:var(--graphite);padding:4px var(--card-pad)}
|
|
.log div{display:flex;gap:18px;padding:14px 0;border-bottom:1px solid var(--line);font-size:15px;color:var(--ink-2)}
|
|
.log div:last-of-type{border-bottom:0}
|
|
.log div.more{display:none}
|
|
.log.open div.more{display:flex}
|
|
.log .log-toggle{align-self:flex-start;margin:12px 0 10px;background:none;border:1px solid var(--line);border-radius:999px;color:var(--ink-2);font:inherit;font-size:13px;padding:8px 14px;cursor:pointer}
|
|
.log .log-toggle:hover{border-color:var(--ink-2)}
|
|
.log .d{font-family:var(--f-mono);font-size:12px;color:var(--ash);flex:0 0 92px;padding-top:3px}
|
|
|
|
/* economics */
|
|
.bar{display:flex;height:22px;border-radius:8px;overflow:hidden}
|
|
.bar div{transition:width 1.2s ease}
|
|
.tiles{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--gap-tile)}
|
|
.tile{background:var(--graphite);border:1px solid var(--line);border-radius:var(--tile-r);padding:var(--tile-pad);min-width:0}
|
|
.tile .v{font-family:var(--f-display);font-weight:700;font-size:var(--fs-tile);line-height:1.1;color:var(--bone)}
|
|
.tile .k{font-size:14px;color:var(--ash);margin-top:6px;line-height:1.35;text-wrap:balance}
|
|
|
|
.band{background:var(--ember);color:var(--ember-ink)}
|
|
.band .wrap{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:24px;padding-block:56px}
|
|
.band h2{font-weight:900;font-size:clamp(26px,3.5vw,36px)}
|
|
.band p{font-size:16px;max-width:56ch}
|
|
.foot{margin-top:0}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- nav:start -->
|
|
<a class="skip" href="#main">Skip to content</a>
|
|
<nav class="nav" aria-label="Main">
|
|
<div class="wrap">
|
|
<a href="/" class="brand" aria-label="Igneum home">
|
|
<svg class="mark" viewBox="0 0 1024 1024" width="36" height="36" aria-hidden="true"><rect width="1024" height="1024" fill="#0C0C0E"></rect><g transform="translate(166.95 166.95) scale(6.901)"><polygon points="50,4 74,34 67,58 80,54 61,96 39,96 20,54 33,58 26,34" fill="#F2541B"></polygon><polygon points="50,42 59,58 50,82 41,58" fill="#0C0C0E"></polygon></g></svg>
|
|
<span class="word">IGNEUM</span>
|
|
</a>
|
|
<button class="burger" id="nav-burger" type="button" aria-expanded="false" aria-controls="nav-links" aria-label="Menu"><svg class="bars" viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M4 7h16M4 12h16M4 17h16"></path></svg><svg class="x" viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"></path></svg></button>
|
|
<div class="links" id="nav-links">
|
|
<a href="/litepaper" data-nav="litepaper">Litepaper</a>
|
|
<a href="/live" data-nav="live">Live devnet</a>
|
|
<a href="/bench" data-nav="bench">Engineering log</a>
|
|
<a href="/miner" data-nav="miner">Miner</a>
|
|
<a href="/wallet" data-nav="wallet">Wallet</a>
|
|
<a href="/evidence" data-nav="evidence">Evidence</a>
|
|
<a href="https://github.com/igneum-network/spec" rel="noopener">GitHub</a>
|
|
<a href="/miner" class="cta">The miner</a>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
<script>
|
|
(function(){
|
|
// the menu: open on the button, closed by any link, a tap outside, Escape (focus back on the button) or a resize past 940 px
|
|
var b=document.getElementById('nav-burger'),l=document.getElementById('nav-links');if(!b||!l)return;
|
|
function set(o){l.classList.toggle('open',o);b.setAttribute('aria-expanded',o?'true':'false');}
|
|
b.addEventListener('click',function(){set(!l.classList.contains('open'));});
|
|
l.addEventListener('click',function(e){if(e.target.closest('a'))set(false);});
|
|
document.addEventListener('click',function(e){if(l.classList.contains('open')&&!l.contains(e.target)&&!b.contains(e.target))set(false);});
|
|
document.addEventListener('keydown',function(e){if(e.key==='Escape'&&l.classList.contains('open')){set(false);b.focus();}});
|
|
var mq=window.matchMedia('(min-width:941px)');if(mq.addEventListener)mq.addEventListener('change',function(){set(false);});
|
|
})();
|
|
</script>
|
|
<!-- nav:end -->
|
|
|
|
<main id="main">
|
|
<header class="hero" id="top">
|
|
<canvas id="bg" aria-hidden="true"></canvas>
|
|
<div class="wrap">
|
|
<div class="hero-copy">
|
|
<div class="eyebrow ember">GPUs are back · for good</div>
|
|
<h1>Mined by GPUs.<br>Proven by fire.</h1>
|
|
<p class="lead">Built for graphics cards. A new mining program every hour, compiled on the card. In our public model the strongest chip reaches 5x to 9x per joule against an RTX 5090 today, about 2x once the lever now in its gates ships: <a href="/bench#counter-asic-2-0-the-numbers" style="color:var(--molten)">the numbers</a>. Every card mines; today's app proves on a 24 GB NVIDIA card and mines and proves on 32 GB. Measured on 6 October 2026 on eleven rented cards with the patched server: every NVIDIA card from 8 GB proves, 10 GB and up mine and prove (<a href="/bench#prover-tiers-on-real-cards-the-rented-fleet-6-october-2026-branch-gpu-fleet" style="color:var(--molten)">the log</a>); ships when the packaging row lands. AMD and Apple cards mine. No premine, no stake, no foundation.</p>
|
|
<div class="cta">
|
|
<a href="#mine" class="btn primary">See the miner</a>
|
|
<a href="/litepaper" class="btn">Read the litepaper</a>
|
|
</div>
|
|
</div>
|
|
<div class="card verify reveal">
|
|
<div class="verify-head">
|
|
<div class="eyebrow">This tab · light client</div>
|
|
<div class="live" data-lc="badge"><span class="dot"></span><span data-lc="badge-text">PREVIEW</span></div>
|
|
</div>
|
|
<div class="verify-row">
|
|
<div class="tick"><svg viewBox="0 0 24 24" width="30" height="30" fill="none" stroke="#0C0C0E" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12.5l4.5 4.5L19 7"></path></svg></div>
|
|
<div>
|
|
<h3 style="font-size:20px">Browser checks Igneum</h3>
|
|
<p style="font-size:14px;color:var(--ash)" data-lc="line">A checkpoint certificate, verified in this tab. Voter list from the node.</p>
|
|
</div>
|
|
</div>
|
|
<div class="verify-grid">
|
|
<div class="cell"><div class="k">BLOCK PROOF</div><div class="v" data-lc="proof" title="No execution proof is on the chain yet. The first off-chain GPU proof of a block was 4 October 2026">not yet</div></div>
|
|
<div class="cell"><div class="k">CHECKPOINT</div><div class="v" data-lc="checkpoint">checking</div></div>
|
|
<div class="cell"><div class="k">PROOF SYSTEM</div><div class="v" data-lc="system">BLS aggregate, version 1</div></div>
|
|
<div class="cell"><div class="k">VERIFIED IN THIS TAB</div><div class="v" style="color:var(--molten)" data-lc="tab">checking</div></div>
|
|
</div>
|
|
<script type="module" src="/verify/verify.js"></script>
|
|
</div>
|
|
<div class="livestrip" id="livestrip" aria-live="off">
|
|
<div class="livestrip-head"><span class="dot"></span><a href="/live">live devnet</a></div>
|
|
<div class="livestrip-grid">
|
|
<div class="tile"><div class="v" id="ls-miners">0</div><div class="k">vote keys active in 10 min (a card runs several)</div></div>
|
|
<div class="tile"><div class="v" id="ls-bps">0.0</div><div class="k">blocks / s</div></div>
|
|
<div class="tile"><div class="v" id="ls-hash">0.0 MH/s</div><div class="k">hash rate</div></div>
|
|
<div class="tile"><div class="v" id="ls-blocks">0</div><div class="k">chain block</div></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="stats">
|
|
<div class="wrap">
|
|
<div class="stat reveal"><div class="v" data-count="1" data-suffix=" / s">1 / s</div><div class="k">blocks, rising to 10</div></div>
|
|
<div class="stat reveal"><div class="v">~60 s</div><div class="k">to a proof at launch, the target. First GPU proof of a block: 1.4 s on an RTX 5090, 4 Oct 2026</div></div>
|
|
<div class="stat reveal"><div class="v" data-count="0">0</div><div class="k">premine</div></div>
|
|
<div class="stat reveal"><div class="v" data-count="4" data-suffix="B">4B</div><div class="k">IGN hard cap, ever</div></div>
|
|
<div class="stat reveal"><div class="v" data-count="100" data-suffix="%">100%</div><div class="k">of emission to miners and provers; the protocol carries no fee</div></div>
|
|
</div>
|
|
</div>
|
|
|
|
<section id="prove">
|
|
<div class="wrap">
|
|
<div class="sec-head reveal">
|
|
<h2>Watch the chain prove itself</h2>
|
|
<p>Blocks every second, proven in shards, locked every 30 seconds. First live lock 4 Oct 2026: checkpoint 242, 77.4% of all weight, two hours after genesis.</p>
|
|
</div>
|
|
<div class="card viz reveal" id="viz-card" aria-label="Block DAG: the live devnet while the observer is fresh, otherwise a simulated preview">
|
|
<div class="viz-head">
|
|
<div class="eyebrow" id="viz-label"><span class="dot" style="background:var(--ember);margin-right:8px"></span>simulated preview</div>
|
|
<div class="viz-stats mono"><span><span id="k-blocks">blocks</span> <b id="c-blocks">0</b></span><span><span id="k-proven">proven</span> <b id="c-proven">0</b></span><span><span id="k-locked">locked</span> <b id="c-locked">0</b></span></div>
|
|
</div>
|
|
<canvas id="chain" aria-hidden="true"></canvas>
|
|
<div class="legend" id="legend-sim">
|
|
<span><i class="sw" style="border:2px solid var(--line-2)"></i>mined</span>
|
|
<span><i class="sw" style="background:var(--molten)"></i>shards being proven</span>
|
|
<span><i class="sw" style="background:var(--ember)"></i>proven</span>
|
|
<span><i class="sw" style="border:3px solid var(--ember);border-radius:50%;background:transparent"></i>locked checkpoint, final</span>
|
|
</div>
|
|
<div class="legend" id="legend-live" hidden>
|
|
<span><i class="sw" style="border:2px solid var(--line-2)"></i>pending</span>
|
|
<span><i class="sw" style="border:2px solid var(--ember)"></i>included</span>
|
|
<span><i class="sw" style="border:2px solid var(--line-2);opacity:.45"></i>excluded</span>
|
|
<span><i class="sw" style="background:var(--ember)"></i>proven</span>
|
|
<span><i class="sw" style="border:3px solid var(--ember);border-radius:50%;background:transparent"></i>locked checkpoint, final to its left</span>
|
|
</div>
|
|
<p class="viz-note" id="viz-note" hidden></p>
|
|
</div>
|
|
<div class="grid" style="margin-top:24px">
|
|
<div class="card reveal" style="display:flex;flex-direction:column;gap:16px">
|
|
<div class="verify-head"><div class="eyebrow">This hour's program</div><div class="mono" style="font-size:12px;color:var(--molten)">next in <span id="countdown">59:59</span></div></div>
|
|
<pre id="program" class="caret"></pre>
|
|
<p class="pt">A new program every hour. Last hour's chip is already obsolete. First live swap 4 Oct 2026: Apple, NVIDIA and AMD kept hashing through it, 0 rejected blocks.</p>
|
|
</div>
|
|
<div class="card reveal" style="display:flex;flex-direction:column;gap:16px">
|
|
<div class="eyebrow">Proofs sold to other chains</div>
|
|
<div class="feed">
|
|
<div><span>rollup · batch proof</span><span style="color:var(--molten)">at testnet</span></div>
|
|
<div><span>bridge · state proof</span><span style="color:var(--molten)">at testnet</span></div>
|
|
<div><span>rollup · fault proof</span><span style="color:var(--ash)">at testnet</span></div>
|
|
<div><span>IGN burned from jobs</span><span style="color:var(--ember)">phase two</span></div>
|
|
</div>
|
|
<p class="pt">The same cards sell proofs to rollups and bridges. Jobs are paid on the customer's chain at launch; settlement in IGN with a 10% burn follows the proof bridge in phase two. Live rows arrive with the public testnet, August 2027.</p>
|
|
</div>
|
|
</div>
|
|
<a href="/litepaper#proving" class="lp reveal">Read more in the litepaper</a>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="randomx">
|
|
<div class="wrap">
|
|
<div class="sec-head reveal">
|
|
<h2>Monero's idea, finished for GPUs</h2>
|
|
<p>The random program that has kept chips off Monero since 2019 (approximate), rebuilt for graphics cards.</p>
|
|
</div>
|
|
<div class="card reveal" style="overflow-x:auto;padding:0;max-width:640px">
|
|
<table class="cmp">
|
|
<thead><tr><th class="eyebrow">Property</th><th class="eyebrow">RandomX</th><th class="eyebrow"><span style="color:var(--ember)">Igneum</span></th></tr></thead>
|
|
<tbody>
|
|
<tr><td>Who mines</td><td>CPUs</td><td>GPUs</td></tr>
|
|
<tr><td>Program changes</td><td>Every hash</td><td>Every hour</td></tr>
|
|
<tr><td>Memory</td><td>2 GB, fixed</td><td>2 GB, growing (the proposed schedule, fixed at the testnet genesis: 2 GB, doubling at years 4, 12 and 28)</td></tr>
|
|
<tr><td>Verified by</td><td>Any CPU</td><td>Any CPU</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<p class="pt reveal" style="margin-top:20px">The program keeps changing on a schedule fixed at genesis. Nobody touches it.</p>
|
|
<a href="/litepaper#randomx" class="lp reveal">Read more in the litepaper</a>
|
|
<p class="reveal" style="margin-top:28px;font-size:14px;color:var(--ash);max-width:72ch">Built on the shoulders: Kaspa's GHOSTDAG and node, Monero's RandomX idea, Chia's class-group VDF, Ethereum's EVM, Succinct's SP1, BLS12-381 and Bitcoin's address format.<br>What changed, why, and how it is measured: <a href="/litepaper#shoulders" style="color:var(--ember)">the provenance section of the litepaper</a>.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="build">
|
|
<div class="wrap">
|
|
<h2 class="reveal" style="margin-bottom:28px">One chain, three jobs</h2>
|
|
<div class="jobs">
|
|
<div class="job reveal">
|
|
<svg viewBox="0 0 24 24" width="32" height="32" fill="none" stroke="#F2541B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="5" width="18" height="12" rx="2"></rect><path d="M7 9h4M7 13h2M15 9v4M18 9v4M9 21h6"></path></svg>
|
|
<h3>Mine</h3>
|
|
<p>Any 4 GB card at launch, 8 GB from about year 4 under the proposed schedule, fixed at the testnet genesis: 2 GB, doubling at years 4, 12 and 28, approximate. 80% of each block to its finder.</p>
|
|
<a href="#mine" class="more">About the miner</a>
|
|
</div>
|
|
<div class="job reveal">
|
|
<svg viewBox="0 0 24 24" width="32" height="32" fill="none" stroke="#F2541B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3l8 4v5c0 5-3.5 8-8 9-4.5-1-8-4-8-9V7l8-4z"></path><path d="M9 12l2 2 4-4"></path></svg>
|
|
<h3>Prove</h3>
|
|
<p>The same card proves shards and sells proofs to other chains.</p>
|
|
<a href="#prove" class="more">How proving pays</a>
|
|
</div>
|
|
<div class="job reveal">
|
|
<svg viewBox="0 0 24 24" width="32" height="32" fill="none" stroke="#F2541B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 7l-5 5 5 5M16 7l5 5-5 5M14 4l-4 16"></path></svg>
|
|
<h3>Build</h3>
|
|
<p>Ethereum bytecode, with the differences documented. Proofs of any computation from the miners' cards, verified by the chain itself. 20% of priority fees to the contracts that ran, stated at the fee levels that exist.</p>
|
|
<a href="/litepaper#builders-ask" class="more">Deploy on Igneum</a>
|
|
</div>
|
|
</div>
|
|
<a href="/litepaper#building" class="lp reveal">Read more in the litepaper</a>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="mine" class="light">
|
|
<div class="wrap">
|
|
<div class="sec-head reveal">
|
|
<h2>One click. The card mines; a 24 GB NVIDIA card proves as well.</h2>
|
|
<p><span data-product="full">Igneum Ember</span> finds your GPU, makes a wallet for you and runs the node, the miner and the prover as one app.</p>
|
|
</div>
|
|
<div class="split">
|
|
<div class="shot reveal">
|
|
<figure class="frame" style="margin:0">
|
|
<div class="bar"><i></i><i></i><i></i><b><span data-product="app">Igneum Miner</span></b></div>
|
|
<img src="/img/miner-dashboard.webp" width="2880" height="1800" alt="The Mine page of Igneum Miner 0.3.14 on a three-card PC: 169 MH/s at 532 W, one row per card with its rate, watts, MH per watt, temperature, tune line, Tune button and switch" loading="lazy" decoding="async">
|
|
<figcaption><span data-product="caption">Igneum Ember (the app window still says Igneum Miner)</span> 0.3.14 on PC 1 (RTX 5090, RTX 4070, RX 9070 XT), live devnet, 6 Oct 2026.</figcaption>
|
|
</figure>
|
|
</div>
|
|
<div class="split-copy reveal">
|
|
<div class="pills">
|
|
<div class="pill"><b>NVIDIA, AMD, Apple silicon</b><span>Found by itself. One worker per card, several identities each.</span></div>
|
|
<div class="pill"><b>A new program every hour, no pause</b><span>Compiled ahead and swapped in 0.01 ms on the live devnet, 0 rejected blocks.</span></div>
|
|
<div class="pill"><b>Signed updates at a safe moment</b><span>The card keeps mining through the download. The old version comes back if the new one fails to start.</span></div>
|
|
<div class="pill"><b>Four pages: Mine, Earnings, Prove, Settings</b><span>Every card is one row: rate, watts, MH per watt, pounds a day at your electricity price, a Tune button. The node is one line.</span></div>
|
|
<div class="pill"><b>Ember Tune, measured</b><span>An RTX 5090 from 311 W to 227 W for 0.15% of its rate; an RTX 4070 from 106 W to 76 W for none (PC 1, 6 Oct 2026). Every number in the bench table.</span></div>
|
|
</div>
|
|
<div class="cta" style="margin-top:24px;align-items:center">
|
|
<a data-dl="miner-windows" href="https://dl.igneum.network/public/igneum-miner-windows.exe" class="btn dark">Windows <span data-dl-meta="miner-windows" style="font-weight:400;opacity:.8">v0.3.14 · 45.4 MB</span></a>
|
|
<a data-dl="miner-mac" href="https://dl.igneum.network/public/igneum-miner-mac.dmg" class="btn dark">macOS <span data-dl-meta="miner-mac" style="font-weight:400;opacity:.8">v0.3.14 · 41.9 MB</span></a>
|
|
<a href="/miner#get" class="btn" style="color:#0C0C0E;border-color:#0C0C0E">Linux · HiveOS</a>
|
|
</div>
|
|
<p data-devnet-notice style="margin-top:14px;font-size:14px;color:#0C0C0E;font-weight:600">Devnet: coins have no value and the chain may be reset.</p>
|
|
<p data-testnet-notice style="margin-top:14px;font-size:14px;color:#0C0C0E;font-weight:600">Public testnet: not yet open; the devnet build is here for people who want to look.</p>
|
|
<p style="margin-top:12px;font-size:14px;color:#55534F"><a href="/miner" style="color:#0C0C0E">Read more about the miner</a>. The protocol carries no fee. The <span data-product="name">Ember</span> software takes an optional 1% dev fee, like other GPU miners, off with one flag. Download only from this domain. Nobody from Igneum will ask for your seed.</p>
|
|
</div>
|
|
</div>
|
|
<div class="card reveal" id="testnet-terms" style="margin-top:32px;display:flex;flex-direction:column;gap:12px">
|
|
<div class="eyebrow">Testnet terms</div>
|
|
<h3>What you agree to when you run the testnet miner</h3>
|
|
<div style="display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr))">
|
|
<div>
|
|
<p style="font-size:15px;color:#3D3B37;margin:0 0 6px"><strong style="color:#0C0C0E">No value.</strong> Testnet IGN cannot be sold, bought or redeemed, now or at mainnet. There is no airdrop, no points scheme and no promise tied to testnet balances. Mainnet starts from an empty genesis.</p>
|
|
</div>
|
|
<div>
|
|
<p style="font-size:15px;color:#3D3B37;margin:0 0 6px"><strong style="color:#0C0C0E">Resets.</strong> The chain restarts from a fresh genesis when a consensus rule changes. Every reset is announced at least seven days ahead on this page and in the app. Balances, contracts and history do not carry over. The devnet that runs today resets without notice.</p>
|
|
</div>
|
|
<div>
|
|
<p style="font-size:15px;color:#3D3B37;margin:0 0 6px"><strong style="color:#0C0C0E">What the app sends home.</strong> The app version, a random machine id made at install, your operating system, the node version, the hash rate, and the app, node and miner logs (which name the address the card mines to). They go to the project's log intake, a service Igneum runs on Vercel, and are read by the maintainers to find faults. Never your seed phrase, never a key, never a file you did not make with the app. Nothing is sold or shared.</p>
|
|
</div>
|
|
</div>
|
|
<p style="font-size:14px;color:#55534F;margin:0">Wallet set-up for MetaMask: <a href="/metamask">chain id, RPC and the one-click button</a>. The miner software takes an optional 1% fee, off with one flag; the protocol carries no fee to anyone.</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="wallet">
|
|
<div class="wrap">
|
|
<div class="sec-head reveal">
|
|
<h2>Your coins, your wallet</h2>
|
|
<p>Igneum Wallet holds the key the miner makes for you and verifies finality itself. MetaMask works too.</p>
|
|
</div>
|
|
<div class="split rev">
|
|
<div class="split-copy reveal">
|
|
<div class="states">
|
|
<div class="state"><span class="spill"><i></i>pending</span><span>waiting for a block</span></div>
|
|
<div class="state block"><span class="spill"><i></i>in a block</span><span>carried, not yet covered</span></div>
|
|
<div class="state final"><span class="spill"><i></i>final · cp 5</span><span>under a checkpoint this wallet verified</span></div>
|
|
</div>
|
|
<div class="pills" style="margin-top:20px">
|
|
<div class="pill"><b>Sealed on your machine</b><span>24 words, three typed back, a password. Argon2id and XChaCha20-Poly1305. Nothing leaves.</span></div>
|
|
<div class="pill"><b>Rewards in one history</b><span>Block rewards, proving payouts and transfers. Send with the fee shown. Receive by a QR drawn locally.</span></div>
|
|
<div class="pill"><b>Reads your own node</b><span>When the miner is installed, the wallet uses its node. Nobody else sees your balance.</span></div>
|
|
</div>
|
|
<div class="cta" style="margin-top:24px;align-items:center">
|
|
<a href="/wallet" class="btn primary">Read more about the wallet</a>
|
|
<a href="/wallet#metamask" class="btn">MetaMask export</a>
|
|
</div>
|
|
<p style="margin-top:16px;font-size:14px;color:var(--ink-2)">macOS first, Windows next. Public testnet first. Download only from this domain. Nobody from Igneum will ask for your seed.</p>
|
|
</div>
|
|
<div class="shot reveal">
|
|
<figure class="frame" style="margin:0">
|
|
<div class="bar"><i></i><i></i><i></i><b>Igneum Wallet</b></div>
|
|
<img src="/img/wallet-home.webp" width="2240" height="1560" alt="The wallet window: a balance in IGN, an example address with Send and Receive, node and finality panels, and a history of block rewards" loading="lazy" decoding="async">
|
|
<figcaption>Igneum Wallet on a private test network, 5 Oct 2026. The address is an example.</figcaption>
|
|
</figure>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="journey">
|
|
<div class="wrap">
|
|
<div class="sec-head reveal">
|
|
<div>
|
|
<h2>Where Igneum is right now</h2>
|
|
<div class="now" style="margin-top:12px"><span class="dot" style="background:var(--ember)"></span><span id="stage-label">LOADING</span></div>
|
|
</div>
|
|
<p>Thirteen months, four public gates, each a measurement published pass or fail.</p>
|
|
</div>
|
|
<div class="journey reveal" id="phases"></div>
|
|
<p class="pt reveal" style="margin-top:24px;margin-bottom:0">The log below is the engineering log's dated entries, newest first. Day one was 3 October 2026; several entries can share a date because the work is logged as it is run.</p>
|
|
<div class="log reveal" id="log"></div>
|
|
<a href="/litepaper#roadmap" class="lp reveal">Read more in the litepaper</a>
|
|
</div>
|
|
</section>
|
|
|
|
<section id="economics">
|
|
<div class="wrap">
|
|
<div style="display:grid;gap:48px;grid-template-columns:repeat(auto-fit,minmax(min(100%,380px),1fr));align-items:center">
|
|
<div class="reveal" style="display:flex;flex-direction:column;gap:20px">
|
|
<h2>Every coin, mined</h2>
|
|
<p style="color:var(--ink-2)">Hard cap of 4 billion IGN, halving every two years for ever.</p>
|
|
<div style="display:flex;flex-direction:column;gap:10px">
|
|
<div class="bar" id="bar"><div style="width:0;background:var(--ember)" data-w="80%"></div><div style="width:0;background:var(--molten)" data-w="20%"></div></div>
|
|
<div class="legend mono" style="margin-top:4px;font-size:13px">
|
|
<span><i class="sw" style="background:var(--ember)"></i>80% miners</span>
|
|
<span><i class="sw" style="background:var(--molten)"></i>20% provers</span>
|
|
<span><i class="sw" style="border:1px solid var(--line-2)"></i>0% anyone else in the protocol</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="tiles reveal">
|
|
<div class="tile"><div class="v">0</div><div class="k">premine</div></div>
|
|
<div class="tile"><div class="v">0</div><div class="k">stake, anywhere</div></div>
|
|
<div class="tile"><div class="v">0</div><div class="k">admin keys in consensus</div></div>
|
|
<div class="tile"><div class="v">90%</div><div class="k">of blocks must signal to upgrade</div></div>
|
|
</div>
|
|
</div>
|
|
<p class="pt reveal" style="margin-top:28px">No premine, no stake, no fee to any team in the protocol. Base fee burned. The one payment to the project is the Ember software's optional 1% dev fee, off with one flag. On the devnet today the coinbase's 20% output is burned under the tag igneum-proving-pool-v0, and provers are paid from a separate escrow in the execution state credited with the same 20%.</p>
|
|
<a href="/litepaper#economics" class="lp reveal">Read more in the litepaper</a>
|
|
</div>
|
|
</section>
|
|
|
|
<div class="band">
|
|
<div class="wrap">
|
|
<div style="display:flex;flex-direction:column;gap:8px">
|
|
<h2>Read what Igneum does not claim.</h2>
|
|
<p>The litepaper states the limits before anyone else does. Proof lag, chip economics, the market size, and the one rule external review will try hardest to break.</p>
|
|
</div>
|
|
<a href="/litepaper" class="btn dark">Litepaper</a>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<!-- footer:start -->
|
|
<footer class="foot">
|
|
<div class="wrap">
|
|
<div class="foot-grid">
|
|
<div class="foot-brand">
|
|
<a href="/" class="brand" aria-label="Igneum home"><svg class="mark" viewBox="0 0 1024 1024" width="30" height="30" aria-hidden="true"><rect width="1024" height="1024" fill="#0C0C0E"></rect><g transform="translate(166.95 166.95) scale(6.901)"><polygon points="50,4 74,34 67,58 80,54 61,96 39,96 20,54 33,58 26,34" fill="#F2541B"></polygon><polygon points="50,42 59,58 50,82 41,58" fill="#0C0C0E"></polygon></g></svg><span class="word">IGNEUM</span></a>
|
|
<p>Mined by GPUs. Proven by fire.</p>
|
|
</div>
|
|
<nav class="foot-col" aria-label="Read">
|
|
<div class="eyebrow">Read</div>
|
|
<a href="/litepaper">Litepaper</a>
|
|
<a href="/litepaper#limits">What Igneum does not claim</a>
|
|
<a href="/litepaper#randomx">Igneum vs RandomX</a>
|
|
<a href="/litepaper#shoulders">Built on the shoulders</a>
|
|
<a href="/bench">Engineering log</a>
|
|
<a href="/evidence">Evidence</a>
|
|
<a href="/ledger">Ledger: every criticism</a>
|
|
</nav>
|
|
<nav class="foot-col" aria-label="Run">
|
|
<div class="eyebrow">Run</div>
|
|
<a href="/miner">The miner</a>
|
|
<a href="/wallet">The wallet</a>
|
|
<a href="/miners">GPU bench table</a>
|
|
<a href="/miner#fee">The dev fee</a>
|
|
<a href="/faucet">Testnet faucet</a>
|
|
</nav>
|
|
<nav class="foot-col" aria-label="Follow">
|
|
<div class="eyebrow">Follow</div>
|
|
<a href="/live">Live devnet</a>
|
|
<a href="/explorer">Explorer</a>
|
|
<a href="/#journey">Journey</a>
|
|
<a href="/wallet">Add Igneum to MetaMask</a>
|
|
<a href="https://github.com/igneum-network/spec" rel="noopener"><svg viewBox="0 0 24 24" width="15" height="15" fill="currentColor" aria-hidden="true"><path d="M12 .5C5.7.5.5 5.7.5 12c0 5.1 3.3 9.4 7.9 10.9.6.1.8-.3.8-.6v-2.1c-3.2.7-3.9-1.4-3.9-1.4-.5-1.3-1.3-1.7-1.3-1.7-1-.7.1-.7.1-.7 1.2.1 1.8 1.2 1.8 1.2 1 1.8 2.7 1.3 3.4 1 .1-.8.4-1.3.7-1.6-2.6-.3-5.3-1.3-5.3-5.7 0-1.3.5-2.3 1.2-3.1-.1-.3-.5-1.5.1-3.1 0 0 1-.3 3.2 1.2.9-.3 1.9-.4 2.9-.4s2 .1 2.9.4c2.2-1.5 3.2-1.2 3.2-1.2.6 1.6.2 2.8.1 3.1.8.8 1.2 1.8 1.2 3.1 0 4.4-2.7 5.4-5.3 5.7.4.4.8 1.1.8 2.2v3.2c0 .3.2.7.8.6 4.6-1.5 7.9-5.8 7.9-10.9C23.5 5.7 18.3.5 12 .5z"></path></svg>GitHub, spec and vectors</a>
|
|
<a href="/miner#get">Miner downloads: public testnet</a>
|
|
<a href="mailto:hello@igneum.network">Report a flaw: hello@igneum.network</a>
|
|
<a href="https://github.com/igneum-network/spec/issues" rel="noopener">Or open an issue on the spec</a>
|
|
</nav>
|
|
</div>
|
|
<div class="foot-base">
|
|
<span class="foot-imprint">Igneum Labs LTD · Unit IH-00-01-01-OF-01, Level 01, Innovation One, Dubai International Financial Centre · <a href="mailto:hello@igneum.network">hello@igneum.network</a></span>
|
|
<span>© 2026 Igneum. Nothing on this page is an offer to sell anything.</span>
|
|
<span class="mono">igneum.network</span>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
<!-- footer:end -->
|
|
|
|
<!-- journey:start -->
|
|
<script type="application/json" id="journey-data">{"updated":"2026-10-06","stage":"phase-3","phases":[{"id":"phase-1","name":"Specification","when":"Oct to Nov 2026","status":"active","line":"Mining generator, shard proving, finality rules, written for external review"},{"id":"phase-2","name":"Prove the proving","when":"Nov 2026 to Jan 2027","status":"active","line":"Mining program proven on Apple, NVIDIA and AMD; shard proving benchmark on consumer cards still to run","gate":"A fixed published workload, job received to accepted proof on a declared consumer card, sustained with no growing backlog, reproduced by three independent operators"},{"id":"phase-3","name":"Devnet","when":"Started 3 Oct 2026, 20 nodes by Mar 2027","status":"active","line":"BlockDAG node mining on the new program, GPU miners on three vendors, EVM execution in build","gate":"1 block a second held with proofs under 60 s behind the tip"},{"id":"phase-4","name":"Finality and job market","when":"Apr to Jul 2027","status":"next","line":"Sustained-mining finality, external proving jobs, miner client with auto-switching","gate":"Finality design passes external review and one rollup signs for testnet"},{"id":"phase-5","name":"Public testnet","when":"Aug to Oct 2027","status":"next","line":"One-click miner app on Windows, macOS and Linux, HiveOS, pools, the first rollup as a proving customer, no coin yet","gate":"1,000 independent miners run 30 days and rollup proofs are delivered on time"},{"id":"phase-6","name":"Mainnet fair launch","when":"Nov 2027","status":"next","line":"Genesis with no premine, 30-day ramp. No listing is arranged, promised or sought by the project"}],"log":[{"date":"2026-10-06","text":"Counter ASIC 3.0 item 2: the per-day derivation","short":"Counter ASIC 3.0 item 2"},{"date":"2026-10-06","text":"Counter ASIC 3.0 item 8: program work in the latency shadow","short":"Counter ASIC 3.0 item 8"},{"date":"2026-10-06","text":"Counter ASIC 3.0 item 6: the reserve families' step costs","short":"Counter ASIC 3.0 item 6"},{"date":"2026-10-06","text":"Counter ASIC 3.0 gate run, the hash side","short":"Counter ASIC 3.0 gate run, the hash side"},{"date":"2026-10-06","text":"16:01Z: Ember run 6 on PC 1","short":"16:01Z: Ember run 6 on PC 1"},{"date":"2026-10-06","text":"00:4xZ, the empty `/api/state` reply","short":"00:4xZ, the empty `/api/state` reply"},{"date":"2026-10-06","text":"07:12Z to 07:17Z, the host's chain mode with --save-shards records and --prev, on the Apple M5 Max's CPU","short":"07:12Z to 07:17Z, the host's chain mode with --save-shards records…"},{"date":"2026-10-06","text":"07:52Z to 08:24Z, the segment-aligned prover beside the miner on PC 2's RTX 5090","short":"07:52Z to 08:24Z, the segment-aligned prover beside the miner on PC…"},{"date":"2026-10-06","text":"08:26Z to 08:35Z, the fast-time harness on the fresh-record rule","short":"08:26Z to 08:35Z, the fast-time harness on the fresh-record rule"},{"date":"2026-10-06","text":"12:25 to 13:20Z, the finality route: why 26 fresh nodes lost the seed every checkpoint","short":"12:25 to 13:20Z, the finality route: why 26 fresh nodes lost the…"},{"date":"2026-10-05","text":"The 9070 XT on the eGPU: why 17.9 MH/s, and what moved","short":"The 9070 XT on the eGPU"},{"date":"2026-10-05","text":"Ember Tune: the two-knob efficiency tune, the fleet prior, and what PC 1 could measure tonight","short":"Ember Tune: the two-knob efficiency tune, the fleet prior"},{"date":"2026-10-05","text":"Read width of the lottery hash: 4, 16 and 64-byte loads, a per-load mix, a written scratch; three cards","short":"Read width of the lottery hash"},{"date":"2026-10-05","text":"The hot table on the M5 Max: a second table sized to GPU cache beside the 1 GiB dataset","short":"The hot table on the M5 Max"},{"date":"2026-10-05","text":"Mixer x4 and the cache growth rule: the class v3 dataset construction, with the x8 candidate","short":"Mixer x4 and the cache growth rule"},{"date":"2026-10-05","text":"The SP1 CPU prover on PC 1 beside the miners, and the backend survey: no zkVM proves on AMD","short":"The SP1 CPU prover on PC 1 beside the miners, and the backend survey"},{"date":"2026-10-05","text":"Proving v1: segment records, the chain rule, the unproven rule; what was measured tonight","short":"Proving v1: segment records, the chain rule"},{"date":"2026-10-05","text":"Dp4a-class throughput on the M5 Max: the dot4 emulation against the ALU chain","short":"Dp4a-class throughput on the M5 Max"},{"date":"2026-10-05","text":"Layer 3 scratch soundness","short":"Layer 3 scratch soundness"},{"date":"2026-10-05","text":"Epoch length as an era parameter : the Apple M5 Max's compile-ahead per program","short":"Epoch length as an era parameter"},{"date":"2026-10-05","text":"Aggregation cost on the RTX 5090: what a per-block aggregation spends and what each lever gives","short":"Aggregation cost on the RTX 5090"},{"date":"2026-10-05","text":"The C4 fix: certificate-driven reorg","short":"The C4 fix: certificate-driven reorg"},{"date":"2026-10-05","text":"EVM transaction relay: three nodes in a chain, every transaction sent to one end included by the other two miners","short":"EVM transaction relay"},{"date":"2026-10-05","text":"The prover carries both fee tables and the height switch: one pinned guest on either side of DAA 210,000","short":"The prover carries both fee tables and the height switch"},{"date":"2026-10-05","text":"FUD ledger sweep round 6","short":"FUD ledger sweep round 6"},{"date":"2026-10-05","text":"Live devnet: real transactions, the first non-empty shard proven and paid, and the exporter's block structure fixed","short":"Live devnet: real transactions, the first non-empty shard proven and…"},{"date":"2026-10-05","text":"The program id split: why the Apple M5 Max rejected PC 2's proofs, and the verifier at 114 s","short":"The program id split"},{"date":"2026-10-05","text":"Live devnet: the first shards proven, verified and paid","short":"Live devnet: the first shards proven, verified and paid"},{"date":"2026-10-04","text":"One-click Windows workers: what the Apple M5 Max could measure","short":"One-click Windows workers"},{"date":"2026-10-04","text":"The gfx1036 worker fault and what the Apple M5 Max could and could not reproduce","short":"The gfx1036 worker fault and what the Apple M5 Max could and could…"},{"date":"2026-10-04","text":"Difficulty rule v2: the live oscillation, its cause, the DAG replay, the fix behind a height switch","short":"Difficulty rule v2"},{"date":"2026-10-04","text":"The observer stored nothing for 78 minutes, then 7,022 blocks in two minutes","short":"The observer stored nothing for 78 minutes, then 7,022 blocks in two…"},{"date":"2026-10-04","text":"PC 2 at the 14:20 boundary: a worker stuck on the previous epoch","short":"PC 2 at the 14:20 boundary: a worker stuck on the previous epoch"},{"date":"2026-10-04","text":"Shard proving on the RTX 5090: a full shard compressed in 10.9 s, a two-shard block aggregated in 2.2 s, all verified","short":"Shard layer on the RTX 5090: a full shard proven in 10.9 s, a block aggregated in 2.2 s"},{"date":"2026-10-04","text":"First outside machine on the devnet: an Apple silicon laptop through the Igneum Miner app","short":"First outside machine: a friend's Mac mining through the app"},{"date":"2026-10-04","text":"Cloud devnet: 12 igneumd nodes in 5 locations, inter-region latency, two Singapore partitions, hash-rate steps","short":"Cloud devnet: 12 igneumd nodes in 5 locations, inter-region latency"},{"date":"2026-10-04","text":"Correction: the 78-minute observer gap was the Apple M5 Max hibernating","short":"Correction: the 78-minute observer gap was the Apple M5 Max hibernating"},{"date":"2026-10-04","text":"Difficulty v2 rollout rehearsal on the 12-node the cloud provider network, binaries for the devnet, the devnet plan","short":"Difficulty v2 rollout rehearsal on the 12-node the cloud provider…"},{"date":"2026-10-04","text":"Difficulty rule v2 activated on the live devnet at DAA 33,000 by height switch, no fresh chain","short":"Difficulty rule v2 switched on the live devnet by height, no fresh chain"},{"date":"2026-10-04","text":"First machine in the United States: a Windows laptop on an Intel integrated GPU, synced and voting","short":"First machine in the United States: a laptop on an integrated GPU, synced and voting"}]}</script>
|
|
<!-- journey:end -->
|
|
<script>
|
|
(function(){
|
|
var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
|
|
// reveal on scroll
|
|
var io=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){e.target.classList.add('in');io.unobserve(e.target);}});},{threshold:.12});
|
|
document.querySelectorAll('.reveal').forEach(function(el){io.observe(el);});
|
|
|
|
// emission bar
|
|
var bar=document.getElementById('bar');
|
|
var bio=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){bar.querySelectorAll('div').forEach(function(d){d.style.width=d.getAttribute('data-w');});bio.disconnect();}});},{threshold:.4});
|
|
bio.observe(bar);
|
|
|
|
// live observer: ONE fetch of /api/live every 2 s feeds the hero, the stats strip and the chain scene.
|
|
// Subscribers get (fresh, d): the sampled new blocks since the last pull and the whole response, or ([], null) when off or stale.
|
|
// live.reason says why the feed is off, in plain words, for the scene's label: 'connecting', 'live feed unavailable' (the fetch
|
|
// failed or the function errored), or 'observer offline, last update N s ago' (the observer's row is older than 30 s).
|
|
var live={on:false,rate:1.3,seen:{},minerOf:{},subs:[],reason:'connecting'};
|
|
live.sub=function(fn){live.subs.push(fn);};
|
|
function emitLive(fresh,d){live.subs.forEach(function(fn){fn(fresh,d);});}
|
|
function fmtAge(sec){sec=Math.round(sec);return sec<90?sec+' s':sec<5400?Math.round(sec/60)+' min':Math.round(sec/3600)+' h';}
|
|
function liveOff(reason){live.on=false;live.reason=reason;emitLive([],null);return false;}
|
|
function pullLive(first){return fetch('/api/live',{cache:'no-store'}).then(function(r){if(!r.ok)throw new Error('HTTP '+r.status);return r.json();}).then(function(d){
|
|
if(!d||!d.ok)return liveOff('live feed unavailable');
|
|
if(!d.state||!d.blocks||!d.miners)return liveOff('live feed unavailable');
|
|
if(d.state.stale)return liveOff('observer offline'+(d.state.age_s!==null&&d.state.age_s!==undefined?', last update '+fmtAge(d.state.age_s)+' ago':''));
|
|
live.on=true;live.reason=null;
|
|
var fresh=d.blocks.filter(function(b){return !live.seen[b.hash];});if(first)fresh=fresh.slice(-12);
|
|
// the response is a 90 s window, so both maps are rebuilt from it and stay bounded
|
|
var seen={},minerOf={};d.blocks.forEach(function(b){seen[b.hash]=1;minerOf[b.hash]=b.miner||'?';});live.seen=seen;live.minerOf=minerOf;
|
|
/* the scenes keep a calm pace; faster chains are sampled, the counters stay true */
|
|
if(fresh.length>3){var step=fresh.length/3,pick=[];for(var i=0;i<3;i++)pick.push(fresh[Math.floor(i*step)]);fresh=pick;}
|
|
emitLive(fresh,d);return true;
|
|
}).catch(function(){return liveOff('live feed unavailable');});}
|
|
|
|
// live stats strip under the hero buttons: shown only while the observer is fresh
|
|
var strip=document.getElementById('livestrip');
|
|
function lsSet(id,v){var el=document.getElementById(id);if(el)el.textContent=v;}
|
|
function fmtHash(h){if(h===null||h===undefined||!(h>0))return 'pending';return h>=1e9?(h/1e9).toFixed(1)+' GH/s':(h/1e6).toFixed(1)+' MH/s';}
|
|
live.sub(function(fresh,d){var on=live.on&&!!d;if(strip)strip.classList.toggle('on',on);if(!on)return;var s=d.state;
|
|
lsSet('ls-miners',s.miners_10m!==null&&s.miners_10m!==undefined?s.miners_10m:d.miners.length);
|
|
lsSet('ls-bps',s.blocks_60s!==null&&s.blocks_60s!==undefined?(s.blocks_60s/60).toFixed(1):'pending');
|
|
lsSet('ls-hash',fmtHash(s.hashes_per_second_estimate));
|
|
lsSet('ls-blocks',s.height!==null&&s.height!==undefined?Number(s.height).toLocaleString('en-GB'):'pending');});
|
|
|
|
// hero background: a block graph that grows left to right, proves, and locks.
|
|
// Live: each dot is one miner seen in the last ten minutes (at most 24, no ids drawn); it flashes when that
|
|
// miner finds a sampled block and a faint line joins it to the miners of the block's parents for a moment.
|
|
var cv=document.getElementById('bg'),ctx=cv.getContext('2d'),nodes=[],W,H,dpr=Math.min(window.devicePixelRatio||1,2),lanes=5,count=0;
|
|
function size(){W=cv.clientWidth;H=cv.clientHeight;cv.width=W*dpr;cv.height=H*dpr;ctx.setTransform(dpr,0,0,dpr,0,0);}
|
|
size();window.addEventListener('resize',size);
|
|
var spacing=function(){return W<700?74:92;};
|
|
function laneY(l){return H*(0.18+l*(0.64/(lanes-1)));}
|
|
function edge(a,b){ctx.beginPath();ctx.moveTo(a.x,a.y);var mx=(a.x+b.x)/2;ctx.bezierCurveTo(mx,a.y,mx,b.y,b.x,b.y);ctx.stroke();}
|
|
function spawn(x){count++;var lane=Math.floor(Math.random()*lanes);var y=laneY(lane)+(Math.random()*18-9);
|
|
var cands=nodes.slice(-7).filter(function(p){return p.x<x-30;});var parents=[];
|
|
cands.sort(function(a,b){return b.x-a.x;});if(cands.length)parents.push(cands[0]);
|
|
cands.slice(1).forEach(function(p){if(Math.random()<0.45&&parents.length<3)parents.push(p);});
|
|
nodes.push({x:x,y:y,born:performance.now(),state:0,lock:count%10===0,parents:parents});if(nodes.length>60)nodes.shift();}
|
|
function seed(){nodes=[];count=0;var sp=spacing();for(var i=0;i<Math.ceil(W/sp)+2;i++){spawn(W-i*sp);nodes[nodes.length-1].born=performance.now()-i*1000;}}
|
|
var last=0,speed=0.22;
|
|
// live state: hm = miner dots, links = parent lines, hq = sampled blocks waiting to flash, simA = simulation opacity
|
|
var hm=[],links=[],hq=[],hLive=false,simA=1,hLast=0,MAXDOTS=24;
|
|
function minerDot(id){for(var i=0;i<hm.length;i++)if(hm[i].id===id)return hm[i];return null;}
|
|
function joinMiner(id){var m=minerDot(id);if(m){m.gone=false;return m;}
|
|
var used={};hm.forEach(function(q){used[q.slot]=1;});var s=-1;for(var i=0;i<MAXDOTS;i++)if(!used[i]){s=i;break;}if(s<0)return null;
|
|
m={id:id,slot:s,fx:0.06+0.88*((s*0.618034)%1),lane:s%lanes,jy:Math.random()*18-9,ph:Math.random()*Math.PI*2,a:0,gone:false,flash:0,x:0,y:0};hm.push(m);return m;}
|
|
live.sub(function(fresh,d){
|
|
if(reduce)return;
|
|
var on=live.on&&!!d;
|
|
if(on!==hLive){hLive=on;if(!on){hm.forEach(function(m){m.gone=true;});hq=[];}}
|
|
if(!on)return;
|
|
var keep={};d.miners.slice(0,MAXDOTS).forEach(function(m){if(!m.id)return;keep[m.id]=1;joinMiner(m.id);});
|
|
hm.forEach(function(m){if(!keep[m.id])m.gone=true;}); // not seen in ten minutes: fade out
|
|
fresh.forEach(function(b){hq.push(b);});if(hq.length>6)hq=hq.slice(-6);
|
|
});
|
|
function frame(t){
|
|
ctx.clearRect(0,0,W,H);
|
|
// simulation: unchanged while the observer is off or stale, fades out behind the live dots when it is on
|
|
simA=Math.max(0,Math.min(1,simA+(hLive?-0.02:0.02)));
|
|
if(!hLive){if(!nodes.length)seed();if(t-last>1000){spawn(W+16);last=t;}}
|
|
if(simA>0){
|
|
ctx.globalAlpha=simA;
|
|
nodes.forEach(function(n){n.x-=speed;var age=t-n.born;if(age>3500)n.state=2;else if(age>1800)n.state=1;});
|
|
ctx.lineWidth=1;
|
|
nodes.forEach(function(n){n.parents.forEach(function(p){if(nodes.indexOf(p)<0)return;var proven=n.state===2&&p.state===2;ctx.strokeStyle=proven?'rgba(242,84,27,0.35)':'rgba(154,154,158,0.18)';edge(n,p);});});
|
|
nodes.forEach(function(n){var r=n.state===2?5:4;
|
|
if(n.state===2&&n.lock){ctx.beginPath();ctx.arc(n.x,n.y,11,0,Math.PI*2);ctx.strokeStyle='rgba(242,84,27,0.9)';ctx.lineWidth=1.5;ctx.stroke();ctx.lineWidth=1;}
|
|
if(n.state===2){var g=ctx.createRadialGradient(n.x,n.y,0,n.x,n.y,16);g.addColorStop(0,'rgba(242,84,27,0.35)');g.addColorStop(1,'rgba(242,84,27,0)');ctx.fillStyle=g;ctx.beginPath();ctx.arc(n.x,n.y,16,0,Math.PI*2);ctx.fill();}
|
|
ctx.beginPath();ctx.arc(n.x,n.y,r,0,Math.PI*2);ctx.fillStyle=n.state===2?'#F2541B':(n.state===1?'#FFB35C':'#0C0C0E');ctx.fill();
|
|
if(n.state===0){ctx.strokeStyle='rgba(154,154,158,0.8)';ctx.stroke();}});
|
|
ctx.globalAlpha=1;
|
|
} else if(nodes.length) nodes=[];
|
|
// live: release one sampled block at the chain scene's pace; its miner flashes, lines reach its parents' miners
|
|
if(hLive&&hq.length&&t-hLast>Math.max(60,1000/live.rate)){var b=hq.shift();hLast=t;var m=joinMiner(b.miner||'?');
|
|
if(m){m.flash=1;var done={};(b.parents||[]).forEach(function(h){var pid=live.minerOf[h];if(!pid||pid===m.id||done[pid])return;done[pid]=1;var p=minerDot(pid);if(p&&!p.gone)links.push({a:m,b:p,born:t});});if(links.length>24)links=links.slice(-24);}}
|
|
hm.forEach(function(m){m.a=Math.max(0,Math.min(1,m.a+(m.gone?-0.012:0.012)));
|
|
m.fx-=speed/W;if(m.fx<-0.02){m.fx+=1.04;m.a=0;} // the same slow drift; a dot that leaves on the left fades back in on the right
|
|
m.x=W*m.fx+Math.sin(t/9000+m.ph)*14;m.y=laneY(m.lane)+m.jy+Math.cos(t/12000+m.ph*1.7)*6;
|
|
if(m.flash>0)m.flash=Math.max(0,m.flash-0.018);});
|
|
hm=hm.filter(function(m){return !(m.gone&&m.a<=0);});
|
|
links=links.filter(function(l){return t-l.born<1600&&hm.indexOf(l.a)>=0&&hm.indexOf(l.b)>=0;});
|
|
ctx.lineWidth=1;
|
|
links.forEach(function(l){if(Math.abs(l.a.x-l.b.x)>W*0.6)return;var p=(t-l.born)/1600;ctx.strokeStyle='rgba(242,84,27,'+(0.35*(1-p)*Math.min(l.a.a,l.b.a)).toFixed(3)+')';edge(l.a,l.b);});
|
|
hm.forEach(function(m){if(m.a<=0)return;var f=m.flash;ctx.globalAlpha=m.a;var gr=16+8*f;
|
|
var g=ctx.createRadialGradient(m.x,m.y,0,m.x,m.y,gr);g.addColorStop(0,'rgba(242,84,27,'+(0.2+0.35*f).toFixed(3)+')');g.addColorStop(1,'rgba(242,84,27,0)');ctx.fillStyle=g;ctx.beginPath();ctx.arc(m.x,m.y,gr,0,Math.PI*2);ctx.fill();
|
|
ctx.beginPath();ctx.arc(m.x,m.y,4+2*f,0,Math.PI*2);ctx.fillStyle='#F2541B';ctx.fill();
|
|
if(f>0){ctx.beginPath();ctx.arc(m.x,m.y,2+1.5*f,0,Math.PI*2);ctx.fillStyle='rgba(255,179,92,'+f.toFixed(3)+')';ctx.fill();}
|
|
ctx.globalAlpha=1;});
|
|
requestAnimationFrame(frame);
|
|
}
|
|
if(!reduce){seed();requestAnimationFrame(frame);}
|
|
|
|
// chain scene: blocks stream in, miners fly in to prove shards, locks ripple
|
|
(function(){
|
|
var c=document.getElementById('chain'),x=c.getContext('2d'),W,H,blocks=[],sparks=[],ripples=[],n=0,proven=0,locked=0,lanes=5,S,GAP,speed,k=1;
|
|
var cb=document.getElementById('c-blocks'),cp=document.getElementById('c-proven'),cl=document.getElementById('c-locked');
|
|
function size(){W=c.clientWidth;H=c.clientHeight;c.width=W*dpr;c.height=H*dpr;x.setTransform(dpr,0,0,dpr,0,0);S=W<600?18:26;GAP=W<600?S*2.5:S*3.1;speed=GAP/1000;k=Math.max(0.22,Math.min(1,(W/speed)/22000));}
|
|
size();window.addEventListener('resize',size);
|
|
function laneY(l){return H*0.14+l*(H*0.72/(lanes-1));}
|
|
// live path state: when the devnet observer is fresh, real blocks (lb) from the shared poller replace the random spawner
|
|
var liveMode=false,liveQ=[],liveLanes={},byHash={};
|
|
// a live block takes the observer's words: color pending / blue (included) / red (excluded), shards planned / proving / verified / paid,
|
|
// locked = a locked checkpoint block, final = at or before the newest lock. Re-applied on every poll so a block on screen updates.
|
|
function applyLive(b,src){b.color=src.color||'pending';b.chain=!!src.chain;b.isFinal=!!src.final;var sh=src.shards||[];
|
|
var done=function(x){return x.state==='verified'||x.state==='paid';};
|
|
var allProven=sh.length>0&&sh.every(done),anyProving=sh.some(function(x){return x.state==='proving'||done(x);});
|
|
if(allProven){if(b.state!=='proven'){b.state='proven';b.glow=1;}}else if(anyProving)b.state='proving';else b.state='mined';
|
|
b.shards=[0,0,0,0];sh.slice(0,4).forEach(function(x,i){b.shards[i]=done(x)?1:0;});
|
|
if(src.locked&&!b.locked){b.locked=true;ripples.push({x:b.x,y:b.y,r:S,a:1});ripples.push({x:b.x,y:b.y,r:S*0.5,a:1});}}
|
|
function spawn(px,lb){n++;var lane=lb?lb.lane:Math.floor(Math.random()*lanes);var b={id:n,x:px,y:laneY(lane),born:performance.now(),shards:[0,0,0,0],claimed:[false,false,false,false],state:'mined',cp:n%6===0,parents:[],glow:0,flash:0,hash:lb?lb.hash:null};
|
|
if(lb){byHash[lb.hash]=b;if(lb.src)applyLive(b,lb.src);lb.parents.forEach(function(h){var q=byHash[h];if(q&&blocks.indexOf(q)>=0&&b.parents.length<4)b.parents.push(q);});if(!b.parents.length){var prev=blocks.slice(-6).filter(function(q){return q.x<px-S;}).sort(function(a2,b2){return b2.x-a2.x;});if(prev.length)b.parents.push(prev[0]);if(prev.length>1&&Math.random()<0.5)b.parents.push(prev[1]);}}
|
|
else{var cands=blocks.slice(-8).filter(function(q){return q.x<px-S;}).sort(function(a2,b2){return b2.x-a2.x;});
|
|
if(cands.length)b.parents.push(cands[0]);cands.slice(1).forEach(function(q){if(Math.random()<0.4&&b.parents.length<3)b.parents.push(q);});}
|
|
blocks.push(b);if(blocks.length>80){var old=blocks.shift();if(old.hash)delete byHash[old.hash];}if(!liveMode)cb.textContent=n;}
|
|
function rr(px,py,w,h,r){x.beginPath();x.moveTo(px+r,py);x.arcTo(px+w,py,px+w,py+h,r);x.arcTo(px+w,py+h,px,py+h,r);x.arcTo(px,py+h,px,py,r);x.arcTo(px,py,px+w,py,r);x.closePath();}
|
|
var last=0,lastShard=0,prevT=0;
|
|
function frame(t){
|
|
if(liveMode){if(liveQ.length&&t-last>Math.max(60,1000/live.rate)){spawn(W+S,liveQ.shift());last=t;}}
|
|
else if(t-last>1000){spawn(W+S);last=t;}
|
|
// real frame time, capped: a fixed 16 ms ran the scene at double speed on 120 Hz displays (found 6 Oct 2026)
|
|
var dt=prevT?Math.min(50,t-prevT):16;prevT=t;
|
|
var sp=liveMode?speed*live.rate:speed;blocks.forEach(function(b){b.x-=sp*dt;var age=t-b.born;
|
|
if(!liveMode&&b.state==='mined'&&age>1200*k)b.state='proving';
|
|
if(!liveMode&&b.state==='proving'){for(var i=0;i<4;i++){if(!b.claimed[i]&&Math.random()<0.012/k){b.claimed[i]=true;var fromTop=Math.random()<0.5;sparks.push({x:Math.random()*W,y:fromTop?-6:H+6,tx:b.x,ty:b.y,b:b,i:i,p:0});}}
|
|
if(b.shards.every(function(v){return v>=1;})){b.state='proven';b.glow=1;proven++;if(!liveMode)cp.textContent=proven;if(b.cp)setTimeout(function(){b.locked=true;locked++;if(!liveMode)cl.textContent=locked;ripples.push({x:b.x,y:b.y,r:S,a:1});ripples.push({x:b.x,y:b.y,r:S*0.5,a:1});},1800*k);}}
|
|
if(b.glow>0)b.glow-=0.02;});
|
|
sparks.forEach(function(sp){sp.p+=Math.min(0.08,0.035/k);sp.tx=sp.b.x;sp.ty=sp.b.y;if(sp.p>=1){sp.done=true;sp.b.shards[sp.i]=1;}});
|
|
sparks=sparks.filter(function(sp){return !sp.done;});
|
|
ripples.forEach(function(r){r.r+=2.2;r.a-=0.012;r.x-=sp*dt;});ripples=ripples.filter(function(r){return r.a>0;});
|
|
x.clearRect(0,0,W,H);
|
|
// faint lane rails
|
|
x.strokeStyle='rgba(42,42,48,0.6)';x.lineWidth=1;for(var l=0;l<lanes;l++){x.beginPath();x.moveTo(0,laneY(l));x.lineTo(W,laneY(l));x.stroke();}
|
|
// edges
|
|
blocks.forEach(function(b){b.parents.forEach(function(q){if(blocks.indexOf(q)<0)return;var both=b.state==='proven'&&q.state==='proven';x.strokeStyle=both?'rgba(242,84,27,0.45)':'rgba(154,154,158,0.22)';x.lineWidth=both?1.5:1;x.beginPath();x.moveTo(b.x,b.y);var mx=(b.x+q.x)/2;x.bezierCurveTo(mx,b.y,mx,q.y,q.x,q.y);x.stroke();});});
|
|
// lock line: everything left of the newest locked block is final
|
|
var lk=null;blocks.forEach(function(b){if(b.locked&&(!lk||b.x>lk.x))lk=b;});
|
|
if(lk){x.strokeStyle='rgba(242,84,27,0.55)';x.lineWidth=1.5;x.setLineDash([5,6]);x.beginPath();x.moveTo(lk.x,6);x.lineTo(lk.x,H-6);x.stroke();x.setLineDash([]);var topBusy=blocks.some(function(q){return Math.abs(q.x-lk.x)<S*2.2&&q.y<H*0.3;});var ly=topBusy?H-10:14;x.fillStyle='rgba(154,154,158,0.9)';x.font='500 '+Math.max(10,Math.round(S*0.42))+'px IBM Plex Mono, monospace';x.textAlign='right';x.fillText('final',lk.x-8,ly);}
|
|
// blocks
|
|
blocks.forEach(function(b){var h=S/2;
|
|
// proving v0: a faint second glint behind a real block once every shard of it is verified on the devnet (nothing before activation)
|
|
if(b.glow>0){var g=x.createRadialGradient(b.x,b.y,0,b.x,b.y,S*1.6);g.addColorStop(0,'rgba(242,84,27,'+(0.45*b.glow)+')');g.addColorStop(1,'rgba(242,84,27,0)');x.fillStyle=g;x.beginPath();x.arc(b.x,b.y,S*1.6,0,Math.PI*2);x.fill();}
|
|
if(b.state==='proven'){x.fillStyle='#F2541B';rr(b.x-h,b.y-h,S,S,S*0.24);x.fill();}
|
|
else{var ex=b.color==='red';if(ex)x.globalAlpha=0.45;x.fillStyle='#0C0C0E';rr(b.x-h,b.y-h,S,S,S*0.24);x.fill();
|
|
// live: included (blue or on the selected chain) takes an ember outline, excluded (red) is dimmed, pending stays grey
|
|
x.strokeStyle=b.state==='proving'?'rgba(255,179,92,0.9)':(liveMode&&!ex&&(b.color==='blue'||b.chain))?'rgba(242,84,27,0.75)':'rgba(58,58,66,1)';x.lineWidth=2;rr(b.x-h,b.y-h,S,S,S*0.24);x.stroke();if(ex)x.globalAlpha=1;
|
|
if(b.state==='proving'){var q=S/2-3;for(var i=0;i<4;i++){if(b.shards[i]>=1){x.fillStyle='#FFB35C';var qx=b.x-h+3+(i%2)*q,qy=b.y-h+3+Math.floor(i/2)*q;rr(qx,qy,q-1,q-1,2);x.fill();}}}}
|
|
if(b.locked){var pulse=0.8+0.2*Math.sin(t/350);x.strokeStyle='rgba(242,84,27,'+pulse+')';x.lineWidth=3;x.beginPath();x.arc(b.x,b.y,S*1.15,0,Math.PI*2);x.stroke();x.fillStyle='#F4F1EC';x.beginPath();x.arc(b.x,b.y,S*0.16,0,Math.PI*2);x.fill();}
|
|
});
|
|
// sparks (miners claiming shards)
|
|
sparks.forEach(function(sp){var e=1-Math.pow(1-sp.p,3);var sx=sp.x+(sp.tx-sp.x)*e,sy=sp.y+(sp.ty-sp.y)*e;x.strokeStyle='rgba(255,179,92,'+(0.5*(1-sp.p))+')';x.lineWidth=1;x.beginPath();x.moveTo(sp.x+(sp.tx-sp.x)*Math.max(0,e-0.15),sp.y+(sp.ty-sp.y)*Math.max(0,e-0.15));x.lineTo(sx,sy);x.stroke();x.fillStyle='#FFB35C';x.beginPath();x.arc(sx,sy,2.2,0,Math.PI*2);x.fill();});
|
|
ripples.forEach(function(r){x.strokeStyle='rgba(242,84,27,'+r.a+')';x.lineWidth=1.5;x.beginPath();x.arc(r.x,r.y,r.r,0,Math.PI*2);x.stroke();});
|
|
if(!reduce)requestAnimationFrame(frame);
|
|
}
|
|
var seedN=Math.ceil(W/GAP)+1,pv=Math.min(5,Math.max(2,Math.floor(seedN*0.45)));for(var i=0;i<seedN;i++){spawn(W-i*GAP);var b=blocks[blocks.length-1];b.born=performance.now()-i*1000;if(i>pv){b.state='proven';b.shards=[1,1,1,1];b.claimed=[true,true,true,true];proven++;if(b.cp){b.locked=true;locked++;}}else if(i>1){b.state='proving';b.claimed=[true,true,false,false];b.shards=[1,1,0,0];}}
|
|
cb.textContent=n;cp.textContent=proven;cl.textContent=locked;
|
|
requestAnimationFrame(frame);
|
|
// live path: the shared poller above feeds sampled real blocks; while fresh, the label links to /live
|
|
var label=document.getElementById('viz-label'),note=document.getElementById('viz-note'),legSim=document.getElementById('legend-sim'),legLive=document.getElementById('legend-live');
|
|
var kb=document.getElementById('k-blocks'),kp=document.getElementById('k-proven'),kl=document.getElementById('k-locked');
|
|
var fmtN=function(v){return v===null||v===undefined?'pending':Number(v).toLocaleString('en-GB');};
|
|
function laneFor(m){if(!(m in liveLanes))liveLanes[m]=Object.keys(liveLanes).length%lanes;return liveLanes[m];}
|
|
// three label states: live (the observer is fresh), off with the reason (the simulation runs and its counters count simulated blocks), connecting
|
|
function setLive(on){
|
|
if(on!==liveMode){liveMode=on;if(!on){cb.textContent=n;cp.textContent=proven;cl.textContent=locked;}}
|
|
if(legSim)legSim.hidden=on;if(legLive)legLive.hidden=!on;
|
|
if(kb)kb.textContent=on?'chain block':'blocks';if(kp)kp.textContent=on?'shards proven':'proven';if(kl)kl.textContent=on?'last lock':'locked';
|
|
if(!label)return;
|
|
if(on){label.innerHTML='<span class="dot" style="margin-right:8px"></span><a href="/live" style="color:var(--molten)">live devnet</a>';return;}
|
|
var r=live.reason||'live feed unavailable';
|
|
label.innerHTML='<span class="dot" style="background:var(--ash);animation:none;margin-right:8px"></span>simulated preview'+(r==='connecting'?'':' · '+r);
|
|
if(note){note.hidden=false;note.textContent=r==='connecting'?'Connecting to the devnet observer. Until it answers, this is a simulation and its counters count simulated blocks.':r.charAt(0).toUpperCase()+r.slice(1)+'. This is a simulation and its counters count simulated blocks. The live page shows the last stored state.';}}
|
|
live.sub(function(fresh,d){setLive(live.on);if(!live.on)return;
|
|
// live counters come from the chain, never from the 90 s window: the chain block number, the shards proven and paid on the chain
|
|
// as the observer's node counts them (proofs land minutes behind the tip, so the blocks on screen are still pending), the latest locked checkpoint
|
|
var s=d.state,pv=d.proving,fn=d.finality;
|
|
cb.textContent=fmtN(s.height);
|
|
cp.textContent=!pv||!pv.supported?'no proving layer':!pv.active?'not active':fmtN(pv.paid_shards_total);
|
|
cl.textContent=!fn||!fn.supported?'no finality':!fn.active?'paused':fn.latest_locked_index!==null&&fn.latest_locked_index!==undefined?'#'+fmtN(fn.latest_locked_index):'none yet';
|
|
if(note){var lag=pv&&pv.active&&pv.median_proof_lag_s?Math.round(pv.median_proof_lag_s):null;
|
|
note.hidden=false;note.textContent='One node is read every 2 s. Chain block is the EVM block number. Shards proven is every shard paid on the chain so far'+(pv&&pv.active?' ('+fmtN(pv.shards_paid_10m||0)+' in the last 10 minutes'+(lag?', landing a median '+lag+' s behind the tip, so the newest blocks on screen are still pending':'')+')':'')+'. Last lock is the latest checkpoint the finality rule locked.';}
|
|
// blocks already on screen take their newest words (pending to included, a shard proven, a checkpoint locked)
|
|
d.blocks.forEach(function(src){var q=byHash[src.hash];if(q)applyLive(q,src);});
|
|
fresh.forEach(function(b){liveQ.push({hash:b.hash,parents:b.parents||[],lane:laneFor(b.miner||'?'),src:b});});
|
|
if(liveQ.length>6)liveQ=liveQ.slice(-6);});
|
|
setLive(false);
|
|
})();
|
|
// one fetch on load, then every 2 s while the feed is fresh and every 10 s while it is off, so a feed that comes back is picked up
|
|
function pollLive(on){setTimeout(function(){pullLive(false).then(pollLive);},on?2000:10000);}
|
|
pullLive(true).then(pollLive);
|
|
|
|
// hourly program ticker
|
|
var ops=['rotl','rotr','xor','add','sub','mul','mulhi','mad','or'];
|
|
function hex(){return '0x'+Math.floor(Math.random()*0xFFFFFFFF).toString(16).toUpperCase().padStart(8,'0');}
|
|
function reg(){return 'r'+Math.floor(Math.random()*8);}
|
|
function line(){var o=ops[Math.floor(Math.random()*ops.length)];var r=Math.random();
|
|
if(r<0.25)return reg()+' ^= load(ds, '+reg()+' & MASK)';
|
|
if(r<0.35)return reg()+' = shfl_xor('+reg()+', '+[1,2,4,8,16][Math.floor(Math.random()*5)]+')';
|
|
if(o==='mad')return reg()+' = mad('+reg()+', '+reg()+' | 1, '+reg()+')';
|
|
if(o==='rotl'||o==='rotr')return reg()+' = '+o+'('+reg()+', '+Math.floor(Math.random()*31+1)+')';
|
|
if(o==='mulhi')return reg()+' = mulhi('+reg()+', '+hex()+')';
|
|
return reg()+' = '+reg()+' '+({xor:'^',add:'+',sub:'-',mul:'*',or:'|'})[o]+' '+(Math.random()<0.5?reg():hex());}
|
|
var pre=document.getElementById('program');
|
|
function program(){var ls=['// seed from a locked checkpoint, through a 10 minute delay'];for(var i=0;i<5;i++)ls.push(line());ls.push('// 64 instructions x 8 iterations, regenerated every hour');return ls;}
|
|
function type(ls){pre.textContent='';var i=0,j=0,out='';function t(){if(i>=ls.length)return;if(j<=ls[i].length){out=ls.slice(0,i).join('\n')+(i?'\n':'')+ls[i].slice(0,j);pre.textContent=out;j++;setTimeout(t,reduce?0:14);}else{i++;j=0;t();}}t();}
|
|
type(program());
|
|
if(!reduce)setInterval(function(){type(program());},16000);
|
|
var cd=document.getElementById('countdown');
|
|
function countdown(){var n=new Date();var s=3599-(n.getMinutes()*60+n.getSeconds());cd.textContent=String(Math.floor(s/60)).padStart(2,'0')+':'+String(s%60).padStart(2,'0');}
|
|
countdown();setInterval(countdown,1000);
|
|
|
|
// journey: the build inlines journey.json into #journey-data, so the phases and the log render in the same pass as the
|
|
// page (no fetch, no layout shift); the fetch is the fallback for an unbuilt copy
|
|
var MON=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
|
|
function day(iso){var m=/^(\d{4})-(\d{2})-(\d{2})$/.exec(iso||'');return m?(+m[3])+' '+MON[+m[2]-1]+' '+m[1]:(iso||'');}
|
|
function journey(j){
|
|
var ph=document.getElementById('phases'),lg=document.getElementById('log'),lab=document.getElementById('stage-label');
|
|
var active=j.phases.filter(function(p){return p.status==='active';});
|
|
var names=active.map(function(p){return p.name;}),list=names.length>1?names.slice(0,-1).join(', ')+' and '+names[names.length-1]:names.join('');
|
|
lab.textContent=('NOW · '+list+' · updated '+day(j.updated)).toUpperCase();
|
|
j.phases.forEach(function(p,i){var d=document.createElement('div');d.className='phase '+p.status;d.innerHTML='<div class="w">'+p.when.toUpperCase()+'</div><div class="n">'+(i+1)+'. '+p.name+'</div>'+(p.gate?'<div class="g">gate: '+p.gate+'</div>':'<div class="g">'+p.line+'</div>');ph.appendChild(d);});
|
|
var SHOW=8,last='';
|
|
j.log.forEach(function(e,i){var d=document.createElement('div');if(i>=SHOW)d.className='more';var same=e.date===last;last=e.date;
|
|
d.innerHTML='<span class="d"'+(same?' aria-hidden="true"':'')+'>'+(same?'':day(e.date))+'</span><span>'+(e.short||e.text)+'</span>';lg.appendChild(d);});
|
|
if(j.log.length>SHOW){var t=document.createElement('button');t.type='button';t.className='log-toggle';t.setAttribute('aria-expanded','false');t.textContent='Show all '+j.log.length+' entries';
|
|
t.onclick=function(){var open=lg.classList.toggle('open');t.setAttribute('aria-expanded',open?'true':'false');t.textContent=open?'Show the latest '+SHOW:'Show all '+j.log.length+' entries';};lg.appendChild(t);}
|
|
}
|
|
var inline=document.getElementById('journey-data'),data=null;
|
|
try{if(inline&&inline.textContent.trim())data=JSON.parse(inline.textContent);}catch(e){data=null;}
|
|
if(data)journey(data);
|
|
else fetch('/journey.json').then(function(r){return r.json();}).then(journey).catch(function(){document.getElementById('stage-label').textContent='PHASE 3 · DEVNET';});
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|