igneum/site/wallet.html
igneum-labs a8461a2848 site-ui-4: the header on every page (six items, Download, the burger with its open state and aria), OS marks on the download cards, the footer redesign (icon row GitHub, Discord, Reddit; Contact eyebrow; one baseline grid; the state word and the year), the chip-model text (prize sentence cut, the bounded hot-set row), live-dag.js 2.0.2 narrow options for phones, the nav build check, the word-bounded rig-name check
The owner's orders of 7 October 2026 (header, logos, footer, phone scene) and the Counter ASIC lane's public text (docs/plans/counter-asic-3-public-text-2026-10-07.md, b10c7ac2) with the disclosure prize held back until its publish word.
Header: the one-screen home no longer hides items; the sheet carries exactly Litepaper, Miner, App, Wallet, Live devnet, Ledger and Download; 44 px bar links, 48 px sheet rows, the burger turns into an X; tools/ci/site-nav-check.mjs runs after every build and in the gate.
Cards: the Windows four-pane, Apple and Tux marks from 80c5618, white on the ember card, the card's own text colour on the mono cards (so they flip with the theme).
Footer: the ledger page renders through tools/ledger-page.mjs and now underlines Ledger; the Reddit profile is the one the owner named.
Renderer: narrow, narrowBreak 720, narrowWindow 30, narrowLanes 4, narrowMinNode 11; hairlines off except the selected chain; checkpoint labels as the percent; fps 60 on the home and /live mounts. Measured in headless chromium at 390 with 4x CPU throttling: 50 to 56 frames a second (the cap is 60).
Evidence row 17 rewritten in the table's eight columns. The forbidden list gains "disclosure prize" and the word-bounded rig names.
Tested with Playwright at 390 and 768 in both themes with real taps on every public page and the 404: 48 rows, 0 problems; captures in docs/plans/site-ui-4-shots/chrome.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 09:59:42 +00:00

406 lines
36 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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 Wallet</title>
<meta name="description" content="A desktop wallet that checks finality itself. 24 words sealed on your machine, send with the fee shown, receive by a QR drawn locally, block rewards and proving payouts in one history, MetaMask export. Reads your own node when the miner is installed.">
<link rel="canonical" href="https://igneum.network/wallet">
<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 Wallet">
<meta property="og:description" content="A desktop wallet that checks finality itself. 24 words sealed on your machine, send with the fee shown, receive by a QR drawn locally, block rewards and proving payouts in one history, MetaMask export.">
<meta property="og:url" content="https://igneum.network/wallet">
<meta property="og:image" content="https://igneum.network/og.png?v=3">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:image:alt" content="Igneum. Mined by GPUs. Proven by fire.">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Igneum Wallet">
<meta name="twitter:description" content="A desktop wallet that checks finality itself. 24 words sealed on your machine, send with the fee shown, receive by a QR drawn locally, rewards and payouts in one history, MetaMask export.">
<meta name="twitter:image" content="https://igneum.network/og.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">
<!-- 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>
<link rel="stylesheet" href="/site.css">
<style>
/* Shared by every page: the head partial, injected by the build 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. The tokens, type and components are in /site.css (docs/plans/site-ui-3.md). */
@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%}
</style>
<script>
/* theme before first paint: the footer control stores "light" or "dark" under igneum-theme; nothing stored means the system setting */
(function(){try{var t=localStorage.getItem("igneum-theme");if(t==="light"||t==="dark")document.documentElement.setAttribute("data-theme",t);}catch(e){}})();
</script>
<!-- head:end -->
<style>
/* page block; tokens, type and components are in /site.css */
--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,5.6vw,56px);--fs-h2:clamp(28px,4.2vw,44px);--fs-h3:clamp(18px,2vw,22px);--fs-tile:clamp(20px,2.2vw,26px)}
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}}
img,svg{max-width:100%}
.mono{font-family:var(--f-mono)}
.eyebrow.ember{color:var(--ember)}
h1,h2,h3{font-family:var(--f-display);margin:0;line-height:1.08;text-wrap:balance}
.btn.primary:hover{background:#FF6A2B;border-color:#FF6A2B;color:var(--ember-ink)}
.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}}
section{padding-block:var(--sec)}
section+section{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}
.pt{font-size:15px;color:var(--ash);max-width:64ch}
.lp{display:inline-block;margin-top:24px;color:var(--ember);font-weight:600;font-size:15px}
.cta{display:flex;flex-wrap:wrap;gap:12px}
.hero{position:relative;padding-block:clamp(48px,8vw,96px) clamp(40px,6vw,72px);overflow:hidden}
.hero::before{content:'';position:absolute;inset:auto -10% -30% 40%;height:70%;background:radial-gradient(closest-side,rgba(242,84,27,.18),rgba(242,84,27,0));pointer-events:none}
.hero .wrap{position:relative;display:grid;gap:36px;grid-template-columns:1fr;align-items:center}
@media (min-width:980px){.hero .wrap{grid-template-columns:.9fr 1.1fr;gap:32px 56px}}
.hero-copy{display:flex;flex-direction:column;gap:22px}
.hero p.lead{font-size:clamp(17px,2vw,20px);color:var(--ink-2);max-width:52ch}
.hero .os{display:flex;flex-wrap:wrap;gap:8px 18px;font-size:14px;color:var(--ash)}
.shot{position:relative;min-width:0}
@media (max-width:720px){.shot::before{display:none}}
.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}
.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)}
/* the three finality states */
.states{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--gap-tile);position:relative}
.state{border:1px solid var(--line);border-radius:var(--tile-r);padding:var(--tile-pad);background:var(--graphite);display:flex;flex-direction:column;gap:8px;position:relative;min-width:0}
.state .pill{display:inline-flex;align-items:center;gap:8px;align-self:flex-start;font-family:var(--f-mono);font-size:12px;letter-spacing:.12em;text-transform:uppercase;padding:6px 10px;border-radius:999px;border:1px solid var(--line-2);color:var(--ash)}
.state .pill i{width:8px;height:8px;border-radius:50%;background:var(--ash);display:inline-block}
.state.block .pill{border-color:rgba(255,179,92,.5);color:var(--molten)}.state.block .pill i{background:var(--molten)}
.state.final .pill{border-color:var(--ember);background:var(--ember);color:var(--ember-ink)}.state.final .pill i{background:var(--ember-ink)}
.state .t{font-family:var(--f-display);font-weight:700;font-size:var(--fs-h3)}
.state p{font-size:14px;color:var(--ash);line-height:1.45}
.state::after{content:'';position:absolute;right:-9px;top:50%;width:14px;height:14px;border-top:2px solid var(--line-2);border-right:2px solid var(--line-2);transform:translateY(-50%) rotate(45deg);z-index:1}
.state:last-child::after{display:none}
@media (max-width:640px){.states{grid-template-columns:1fr}.state::after{right:auto;left:50%;top:auto;bottom:-9px;transform:translateX(-50%) rotate(135deg)}}
.group{display:grid;gap:var(--gap);grid-template-columns:1fr;margin-bottom:var(--sec)}
@media (min-width:900px){.group{grid-template-columns:300px minmax(0,1fr);gap:48px}}
.group:last-child{margin-bottom:0}
.group .g-head{display:flex;flex-direction:column;gap:12px}
.group .g-head p{font-size:15px;color:var(--ash)}
.feats{display:grid;gap:var(--gap-tile);grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr))}
.feat{background:var(--graphite);border:1px solid var(--line);border-radius:var(--tile-r);padding:var(--tile-pad);display:flex;flex-direction:column;gap:6px;min-width:0;transition:border-color .2s ease}
.feat:hover{border-color:var(--line-2)}
.feat b{font-weight:600;font-size:16px}
.feat p{font-size:14px;color:var(--ash);line-height:1.45}
.feat .src{font-family:var(--f-mono);font-size:11px;color:var(--ember);margin-top:4px}
.feat.wide{grid-column:1/-1}
td.num{font-variant-numeric:tabular-nums;white-space:nowrap}
.ol{counter-reset:s;display:grid;gap:var(--gap-tile);grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr));margin:0;padding:0;list-style:none}
.ol li{counter-increment:s;background:var(--graphite);border:1px solid var(--line);border-radius:var(--tile-r);padding:var(--tile-pad);font-size:14px;color:var(--ink-2);line-height:1.45;min-width:0}
.ol li::before{content:counter(s,decimal-leading-zero);display:block;font-family:var(--f-mono);font-size:11px;letter-spacing:.14em;color:var(--ember);margin-bottom:8px}
.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}
.btn.dark{background:var(--obsidian);color:var(--bone);border-color:var(--obsidian)}
.btn.dark:hover{background:#222226;color:var(--bone)}
</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="28" height="28" aria-hidden="true"><rect width="1024" height="1024" rx="160" 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>
<div class="links" id="nav-links">
<a href="/litepaper" data-nav="litepaper">Litepaper</a>
<a href="/miner" data-nav="miner">Miner</a>
<a href="/app" data-nav="app">App</a>
<a href="/wallet" data-nav="wallet" aria-current="page">Wallet</a>
<a href="/live" data-nav="live">Live devnet</a>
<a href="/ledger" data-nav="ledger">Ledger</a>
</div>
<a href="/miner#get" class="btn primary small cta">Download</a>
<button class="burger" id="nav-burger" type="button" aria-expanded="false" aria-controls="nav-sheet" aria-label="Open the menu" aria-haspopup="true"><span class="bars" aria-hidden="true"></span></button>
<div class="nav-sheet" id="nav-sheet">
<a href="/litepaper" data-nav="litepaper">Litepaper</a>
<a href="/miner" data-nav="miner">Miner</a>
<a href="/app" data-nav="app">App</a>
<a href="/wallet" data-nav="wallet">Wallet</a>
<a href="/live" data-nav="live">Live devnet</a>
<a href="/ledger" data-nav="ledger">Ledger</a>
<a href="/miner#get" class="btn primary">Download</a>
</div>
</div>
</nav>
<script>
(function(){
// the menu: open on the button, closed by any link, Escape (focus back on the button) or a resize past 900 px
var n=document.querySelector('.nav'),b=document.getElementById('nav-burger'),s=document.getElementById('nav-sheet');if(!n||!b||!s)return;
function set(o){n.classList.toggle('open',o);b.setAttribute('aria-expanded',o?'true':'false');b.setAttribute('aria-label',o?'Close the menu':'Open the menu');document.documentElement.style.overflow=o?'hidden':'';}
b.addEventListener('click',function(){set(!n.classList.contains('open'));});
s.addEventListener('click',function(e){if(e.target.closest('a'))set(false);});
document.addEventListener('keydown',function(e){if(e.key==='Escape'&&n.classList.contains('open')){set(false);b.focus();}});
var mq=window.matchMedia('(min-width:901px)');if(mq.addEventListener)mq.addEventListener('change',function(){set(false);});
})();
</script>
<!-- nav:end -->
<main id="main">
<header class="hero" id="top">
<div class="wrap">
<div class="hero-copy">
<div class="eyebrow ember">Igneum Wallet · desktop</div>
<h1>Your coins. Final means final.</h1>
<p class="lead">A desktop wallet that holds the key the miner made for you, or one you make here from 24 words. It sends, receives and reads your history, and it verifies every finality certificate itself with the node's own code. No confirmation counts, no trusting the node.</p>
<div class="cta">
<a href="#get" class="btn primary">Download: public testnet</a>
<a href="#finality" class="btn">How final works</a>
</div>
<div class="os"><span>macOS first</span><span>Windows next</span><span>MetaMask export</span></div>
</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-dark.webp" width="2240" height="1560" class="img-dark" alt="The wallet window, Home: a balance of 31.6321 IGN with the devnet note that coins have no value, an example address with Copy, Send and Receive, the node line synced to the miner app's node and verified to a checkpoint, and the recent transfers with their state words" fetchpriority="high" decoding="async">
<img src="/img/wallet-home-light.webp" width="2240" height="1560" class="img-light" alt="The wallet window, Home, in light mode: a balance of 31.6321 IGN, an example address with Copy, Send and Receive, the node line and the recent transfers" fetchpriority="high" decoding="async">
<figcaption>Igneum Wallet 0.1.5, rendered from the wallet’s own mock state: example keys, 7 October 2026.</figcaption>
</figure>
</div>
</div>
</header>
<section id="finality">
<div class="wrap">
<div class="sec-head reveal">
<h2>Three states, checked here</h2>
<p>Every transfer in the history is pending, in a block, or final. The third one is the wallet's own verdict.</p>
</div>
<div class="states reveal">
<div class="state pending"><span class="pill"><i></i>pending</span><div class="t">Waiting for a block</div><p>Signed on this machine and handed to the node. Nothing has carried it yet.</p></div>
<div class="state block"><span class="pill"><i></i>in a block</span><div class="t">Chain block 8</div><p>A block carries it and the chain's height passed it. It can still be reorganised until a checkpoint covers it.</p></div>
<div class="state final"><span class="pill"><i></i>final · cp 5</span><div class="t">Under a verified checkpoint</div><p>Its block sits under a 30-second checkpoint whose certificate this wallet verified: the voter list, the aggregate BLS signature, two thirds of all weight.</p></div>
</div>
<div class="shot reveal" style="margin-top:var(--gap);max-width:880px">
<figure class="frame" style="margin:0">
<div class="bar"><i></i><i></i><i></i><b>History</b></div>
<img src="/img/wallet-history-dark.webp" width="2240" height="1560" class="img-dark" alt="The wallet's History page: every transfer with the node's word, pending, proven, executed, finalised under a checkpoint verified here, and one failed with the fee still paid" loading="lazy" decoding="async">
<img src="/img/wallet-history-light.webp" width="2240" height="1560" class="img-light" alt="The wallet's History page in light mode: every transfer with the node's word, pending, proven, executed, finalised under a checkpoint verified here" loading="lazy" decoding="async">
<figcaption>Every transfer with the node’s word: pending, proven, executed, finalised under a checkpoint this wallet verified. Igneum Wallet 0.1.5, rendered from its mock state with example keys, 7 October 2026.</figcaption>
</figure>
</div>
<div class="reveal" style="margin-top:var(--gap)">
<div class="eyebrow" style="margin-bottom:12px">What the wallet checks before it says final</div>
<ol class="ol">
<li>The certificate as a block carried it: the finality section of the blocks after the checkpoint.</li>
<li>The canonical voter list: every key above dust and not stripped, sorted by key hash, as many as the certificate says.</li>
<li>The aggregate signature over the checkpoint, by the keys the bitmap names.</li>
<li>The rule: signed weight at least two thirds of the active weight and of the total weight. Then the transfer's block must sit under the checkpoint on the chain.</li>
</ol>
<p class="pt" style="margin-top:16px">The same steps the browser verifier on the home page runs, with the node's own finality code compiled into the wallet. The node's own "locked" field is never read.</p>
</div>
</div>
</section>
<section id="features">
<div class="wrap">
<div class="sec-head reveal">
<h2>Every feature, one line each</h2>
<p>Version 1, built on the miner's bones: the same local server, the same signed update manifest, the same key code.</p>
</div>
<div class="group reveal" id="keys">
<div class="g-head"><div class="eyebrow ember">01 · Your key</div><h3>Create or import, sealed on your disk</h3><p>The password is never written anywhere. The plaintext only ever exists in the engine's memory and is zeroed when the wallet locks.</p></div>
<div class="feats">
<div class="feat"><b>Create: 24 words</b><p>256 bits of entropy from the operating system, as 24 English words. The wallet asks for three of them typed back before it goes on.</p></div>
<div class="feat"><b>Import</b><p>Your 24 words, a raw private key, or the miner's own payout key file. One click brings the key the miner pays to into the wallet.</p></div>
<div class="feat"><b>Sealed with a password</b><p>Argon2id (64 MiB, 3 passes) turns the password into a key; XChaCha20-Poly1305 seals the secret under it. The vault is one file in your user folder.</p></div>
<div class="feat"><b>The Ethereum path</b><p>Keys follow BIP-39 and BIP-44 at the Ethereum path, so the same 24 words open the same account in MetaMask.</p></div>
</div>
</div>
<div class="group reveal" id="money">
<div class="g-head"><div class="eyebrow ember">02 · Send, receive, history</div><h3>Everything on one screen</h3><p>Signing happens in the engine, in Rust. Nothing on the window side ever holds the key.</p></div>
<div class="feats">
<div class="feat"><b>Balance</b><p>Read from your node every few seconds, in IGN, with the block it was read at.</p></div>
<div class="feat"><b>Send with the fee shown</b><p>An EIP-1559 transfer. The review shows the amount, the fee at most as base fee plus tip, and what leaves the wallet at most. The zero address and more than the balance are refused.</p></div>
<div class="feat"><b>Receive by QR</b><p>The code is drawn on your machine as SVG. No image service, no call across the network.</p></div>
<div class="feat"><b>History with rewards</b><p>Transfers in and out, block rewards from the execution records, one per blue block, and proving payouts when a block carries a proof record.</p></div>
<div class="feat"><b>Finality per transaction</b><p>Pending, in a block, or final with the checkpoint index, verified here. <a href="#finality" style="color:var(--ember)">How it checks</a>.</p></div>
<div class="feat"><b>Lock</b><p>One button locks the wallet and zeroes the key in memory. The password opens it again.</p></div>
</div>
</div>
<div class="group reveal" id="node">
<div class="g-head"><div class="eyebrow ember">03 · Your node</div><h3>Reads the miner's node first</h3><p>When the miner is installed, the wallet uses its node on this machine. Nobody else sees your balance.</p></div>
<div class="feats">
<div class="feat"><b>1 · The miner app's node</b><p>Found on this machine and used as it is. Nothing is started.</p></div>
<div class="feat"><b>2 · A public RPC</b><p>Balances, sending and history work without a local node. Finality verification needs a node, so transfers stay "in a block" until one is there, and the wallet says so.</p></div>
<div class="feat"><b>3 · The bundled node</b><p>The wallet starts its own copy of the node on its own ports, no mining, and stops it when the wallet quits.</p></div>
<div class="feat"><b>Updates, signed</b><p>The same Ed25519 key as the miner's manifest, checked an hour apart. The download is checked against the manifest's hash before Install now opens it.</p></div>
</div>
</div>
<div class="group reveal" id="metamask">
<div class="g-head"><div class="eyebrow ember">04 · MetaMask</div><h3>Export and add the network</h3><p>For people who already live in MetaMask. The key leaves this app only when you copy it.</p></div>
<div class="feats">
<div class="feat"><b>Add to MetaMask</b><p>One click adds the Igneum network with its chain id and RPC. Copy network settings puts the same values on the clipboard.</p></div>
<div class="feat"><b>Export the key</b><p>Behind the password, behind a warning: a copied key can be stolen from the clipboard, a screenshot or a notes app. Paste it straight into MetaMask and clear the clipboard.</p></div>
<div class="feat"><b>Desktop first</b><p>macOS now, as a disk image. The Windows host is written and untested. No browser extension and no phone app yet.</p></div>
</div>
</div>
</div>
</section>
<section id="measured">
<div class="wrap">
<div class="sec-head reveal">
<h2>The first run, timed</h2>
<p>A private test network, 5 Oct 2026: one node, one CPU miner paying to wallet A, wallet A sending to wallet B. The log entry ships with the wallet.</p>
</div>
<div class="tbl reveal"><table>
<thead><tr><th>Step</th><th>From the node's start</th><th>What was seen</th></tr></thead>
<tbody>
<tr><td>Wallet A created, 24 words, three typed back</td><td class="num">0.3 s</td><td>an address</td></tr>
<tr><td>Wallet B: a wrong word refused, then created</td><td class="num">0.4 to 0.5 s</td><td>"word 1 is not right"</td></tr>
<tr><td>A's balance from block rewards</td><td class="num">3.5 s</td><td>10.14 IGN at block 4</td></tr>
<tr><td>Zero address, 999,999,999 IGN, a short address</td><td class="num">4.5 s</td><td>all three refused by the quote</td></tr>
<tr><td>Quote for 1.5 IGN to B</td><td class="num">4.6 s</td><td>gas 25,380; base fee 1 gwei; tip 1 gwei; fee at most 0.00007614 IGN</td></tr>
<tr><td>In a block</td><td class="num">5.6 s</td><td>chain block 8</td></tr>
<tr><td>First locked checkpoint on the network</td><td class="num">about 170 s</td><td>index 5</td></tr>
<tr><td>Final in wallet A</td><td class="num">175.2 s</td><td>under checkpoint 5, certificate verified by the wallet: 1 of 1 voters, 100% of total weight</td></tr>
<tr><td>B's view of the same transfer</td><td class="num">175 s</td><td>1.5 IGN, final</td></tr>
</tbody>
</table></div>
<p class="pt reveal" style="margin-top:16px">Send to final: 170.6 s, all of it the network's first lock on a fresh chain. On the live devnet checkpoints lock every 30 seconds once the weight window is full. 13 unit tests cover the words, the path, the vault, the signing and the finality state machine.</p>
</div>
</section>
<section id="get">
<div class="wrap">
<div class="sec-head reveal">
<h2>Get the wallet</h2>
<p>Download only from this domain. Nobody from Igneum will ask for your seed. The file below is the one the wallet's signed manifest names, with its version and size.</p>
<p data-testnet-notice style="margin-top:10px;font-weight:600;color:var(--molten)">Public testnet: not yet open; the devnet build is here for people who want to look.</p>
<p data-devnet-notice style="margin-top:6px;font-weight:600;color:var(--molten)">Devnet: coins have no value and the chain may be reset.</p>
</div>
<div class="cta reveal" style="align-items:center">
<a data-dl="wallet-mac" href="https://dl.igneum.network/public/igneum-wallet-mac.dmg" class="btn primary"><svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" aria-hidden="true"><path d="M16.4 12.6c0-2.3 1.9-3.4 2-3.5-1.1-1.6-2.8-1.8-3.4-1.8-1.4-.1-2.8.8-3.5.8-.7 0-1.8-.8-3-.8-1.5 0-3 .9-3.8 2.3-1.6 2.8-.4 7 1.2 9.3.8 1.1 1.7 2.4 2.9 2.3 1.2 0 1.6-.7 3-.7s1.8.7 3 .7c1.3 0 2-1.1 2.8-2.3.9-1.3 1.2-2.6 1.3-2.6-.1 0-2.5-.9-2.5-3.7zM14.1 5.8c.6-.8 1.1-1.9.9-3-.9 0-2 .6-2.7 1.4-.6.7-1.1 1.8-1 2.9 1.1.1 2.1-.5 2.8-1.3z"/></svg>macOS <span data-dl-meta="wallet-mac" style="font-weight:400;opacity:.85">v0.1.5 · 20.1 MB</span></a>
<span class="btn" aria-disabled="true" style="opacity:.7;cursor:default"><svg viewBox="0 0 24 24" width="18" height="18" fill="currentColor" aria-hidden="true"><path d="M3 5.5l7.5-1v7H3zM11.5 4.3L21 3v8.5h-9.5zM3 12.5h7.5v7L3 18.5zM11.5 12.5H21V21l-9.5-1.3z"/></svg>Windows <span style="font-weight:400;opacity:.85">next</span></span>
<a href="#metamask" class="btn"><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round" aria-hidden="true"><path d="M4 4l5 3h6l5-3-1.5 7 1.5 5-3 4H7l-3-4 1.5-5z"/><path d="M9 13h2M13 13h2"/></svg>MetaMask</a>
</div>
<p class="pt reveal" style="margin-top:20px">The wallet reads this machine's node when the <a href="/miner" style="color:var(--ember)">miner</a> is installed. Without it, a public RPC for balances and sending, or the bundled node for everything.</p>
<a href="/litepaper#miners" class="lp reveal">Read more in the litepaper</a>
</div>
</section>
</main>
<div class="band">
<div class="wrap">
<div style="display:flex;flex-direction:column;gap:8px">
<h2>The miner pays this wallet.</h2>
<p>Install the miner, press Start, and the address it makes is the one this wallet imports with one click.</p>
</div>
<a href="/miner" class="btn dark">The miner</a>
</div>
</div>
<!-- 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="26" height="26" aria-hidden="true"><rect width="1024" height="1024" rx="160" 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 class="social" aria-label="Igneum elsewhere">
<a href="https://github.com/igneum-network/spec" target="_blank" rel="noopener" aria-label="Igneum on GitHub: the spec, the vectors and the issues"><svg viewBox="0 0 24 24" width="22" height="22" 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></a>
<a href="https://discord.gg/igneum" target="_blank" rel="noopener" aria-label="The Igneum Discord"><svg viewBox="0 0 24 24" width="22" height="22" fill="currentColor" aria-hidden="true"><path d="M19.6 5.3A17 17 0 0 0 15.4 4l-.2.4a15.6 15.6 0 0 1 3.9 1.9 13.6 13.6 0 0 0-14.2 0A15.6 15.6 0 0 1 8.8 4.4L8.6 4a17 17 0 0 0-4.2 1.3C1.8 9.2 1.1 13 1.4 16.7a17.1 17.1 0 0 0 5.2 2.6l1.1-1.8a10.8 10.8 0 0 1-1.7-.8l.4-.3a12.2 12.2 0 0 0 11.2 0l.4.3-1.7.8 1.1 1.8a17 17 0 0 0 5.2-2.6c.4-4.3-.7-8-3-11.4zM8.7 14.4c-1 0-1.8-.9-1.8-2.1s.8-2.1 1.8-2.1 1.9 1 1.8 2.1c0 1.2-.8 2.1-1.8 2.1zm6.6 0c-1 0-1.8-.9-1.8-2.1s.8-2.1 1.8-2.1 1.9 1 1.8 2.1c0 1.2-.8 2.1-1.8 2.1z"></path></svg></a>
<a data-social="reddit" href="https://www.reddit.com/user/Igneum_network/" target="_blank" rel="noopener" aria-label="Igneum on Reddit"><svg viewBox="0 0 24 24" width="22" height="22" fill="currentColor" aria-hidden="true"><path d="M22 12.1a2.2 2.2 0 0 0-3.7-1.6 10.8 10.8 0 0 0-5.8-1.8l1-4.6 3.2.7a1.5 1.5 0 1 0 .2-.9l-3.6-.8a.5.5 0 0 0-.5.4l-1.1 5.2a10.8 10.8 0 0 0-5.9 1.8A2.2 2.2 0 1 0 3.4 14a4.3 4.3 0 0 0 0 .7c0 3.4 3.9 6.1 8.6 6.1s8.6-2.7 8.6-6.1a4.3 4.3 0 0 0 0-.7 2.2 2.2 0 0 0 1.4-1.9zM7 13.6a1.5 1.5 0 1 1 1.5 1.5A1.5 1.5 0 0 1 7 13.6zm8.6 4.1a5.7 5.7 0 0 1-3.6 1.1 5.7 5.7 0 0 1-3.6-1.1.4.4 0 0 1 .6-.6 4.9 4.9 0 0 0 3 .9 4.9 4.9 0 0 0 3-.9.4.4 0 0 1 .6.6zm-.3-2.6a1.5 1.5 0 1 1 1.5-1.5 1.5 1.5 0 0 1-1.5 1.5z"></path></svg></a>
</div>
</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="/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="/app">The app</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="/litepaper#roadmap">Journey</a>
<a href="/metamask">Add to MetaMask</a>
<a href="/miner#get">Downloads: devnet build</a>
</nav>
<nav class="foot-col" aria-label="Contact">
<div class="eyebrow">Contact</div>
<a href="mailto:hello@igneum.network">hello@igneum.network</a>
<a href="https://github.com/igneum-network/spec/issues" rel="noopener">An issue on the spec</a>
<span class="foot-note">Report a flaw by either. Nobody from Igneum will ask for your seed.</span>
</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</span>
<span class="foot-state"><span class="dot off" id="foot-dot"></span><span id="foot-state">devnet</span></span>
<span class="theme" role="group" aria-label="Theme"><button type="button" data-theme-set="system" aria-pressed="true">System</button><button type="button" data-theme-set="light" aria-pressed="false">Light</button><button type="button" data-theme-set="dark" aria-pressed="false">Dark</button></span>
<span class="mono foot-copy">© 2026 Igneum · not an offer to sell anything</span>
</div>
</div>
</footer>
<script>
(function(){
// theme control: stores light or dark under igneum-theme; system clears it. The head applied the stored value before paint.
var bs=document.querySelectorAll('[data-theme-set]');if(!bs.length)return;
function cur(){try{var t=localStorage.getItem('igneum-theme');return t==='light'||t==='dark'?t:'system';}catch(e){return 'system';}}
function paint(){var c=cur();bs.forEach(function(b){b.setAttribute('aria-pressed',b.getAttribute('data-theme-set')===c?'true':'false');});}
bs.forEach(function(b){b.addEventListener('click',function(){var v=b.getAttribute('data-theme-set');try{if(v==='system')localStorage.removeItem('igneum-theme');else localStorage.setItem('igneum-theme',v);}catch(e){}
if(v==='system')document.documentElement.removeAttribute('data-theme');else document.documentElement.setAttribute('data-theme',v);paint();});});
paint();
// the network state word in the footer: one read of the observer per page view
var fs=document.getElementById('foot-state'),fd=document.getElementById('foot-dot');if(fs&&fd){fetch('/api/live?window=30',{cache:'no-store'}).then(function(r){return r.json();}).then(function(d){var on=d&&d.ok&&d.state&&!d.state.stale;fs.textContent=on?'devnet live':'devnet, observer stale';fd.className='dot '+(on?'live':'off');}).catch(function(){fs.textContent='devnet';});}
})();
</script>
<!-- footer:end -->
<script>
(function(){
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);});
})();
</script>
</body>
</html>