Builder pages and faucet: Devnet 3 chain id 4464 since the class v5 floor (8 October 2026, 13:27 BST reading)
- the faucet reads eth_chainId from its node on every send and in its status (a fixed id signed refused transactions once the floor crossed); FAUCET_CHAIN_ID is gone from the env; the faucet now reads node1-dn3's EVM, the node the public RPC fronts - /build, /faucet, docs/build/first-contract.md, rpc.md and faucet.md: 4464 with the floor note, "read it, never fix it" - a second walkthrough PASS on the 4464 chain from build-2 through the public RPC and faucet: Counter at block 29878, 12 s end to end Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
1513244d55
commit
e15464ac58
10 changed files with 53 additions and 45 deletions
6
docs/build/build.md
vendored
6
docs/build/build.md
vendored
|
|
@ -16,13 +16,13 @@ This file is the source of [igneum.network/build](https://igneum.network/build).
|
|||
|
||||
| | Devnet 3 | Testnet | Mainnet |
|
||||
|---|---|---|---|
|
||||
| Chain id | 4463 (`0x116f`) | 4462 (`0x116e`) | 4461 (`0x116d`) |
|
||||
| Chain id | 4464 (`0x1170`) since its class v5 floor on 8 October 2026; 4463 below it | 4462 (`0x116e`) | 4461 (`0x116d`) |
|
||||
| Network id | `igneum-devnet-3` | `igneum-testnet-1` | not started |
|
||||
| RPC | `https://rpc.devnet.igneum.network` (a node you run serves `http://127.0.0.1:26790`) | `https://rpc.testnet.igneum.network` (answers; nothing mines there yet, so a transaction waits) | none |
|
||||
| Coins | no value, resets without notice | no value, resets with notice | not started |
|
||||
| Symbol, decimals | IGN, 18 | IGN, 18 | IGN, 18 |
|
||||
|
||||
Devnet 3 is where you build today. It is a developer network: it resets without notice and its coins have no value. Its public RPC takes the read methods, `eth_sendRawTransaction` and a wRPC websocket at `/ws`, at 20 requests a second per address. The public testnet exists, its RPC answers, and no blocks are being produced on it until it opens. Mainnet has no date. Devnet 3 answers chain id 4463 until its class v5 floor, then 4464.
|
||||
Devnet 3 is where you build today. It is a developer network: it resets without notice and its coins have no value. Its public RPC takes the read methods, `eth_sendRawTransaction` and a wRPC websocket at `/ws`, at 20 requests a second per address. The public testnet exists, its RPC answers, and no blocks are being produced on it until it opens. Mainnet has no date. Devnet 3 answered 4463 until its class v5 floor at DAA 68,400 on 8 October 2026 and 4464 from it; read it with `eth_chainId` rather than fixing it, since a transaction signed for the wrong id is refused.
|
||||
|
||||
## Endpoints and tools
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ cast send 0xDEPLOYED "increment()" --rpc-url $RPC --private-key $PK
|
|||
cast call 0xDEPLOYED "number()(uint256)" --rpc-url $RPC
|
||||
```
|
||||
|
||||
The call answers `1`. Paste the transaction hash into [the explorer](/explorer). Hardhat, ethers and viem work the same way: chain id 4463, the RPC above.
|
||||
The call answers `1`. Paste the transaction hash into [the explorer](/explorer). Hardhat, ethers and viem work the same way: chain id 4464, the RPC above.
|
||||
|
||||
## The RPC the node serves
|
||||
|
||||
|
|
|
|||
2
docs/build/faucet.md
vendored
2
docs/build/faucet.md
vendored
|
|
@ -5,7 +5,7 @@
|
|||
## What it is
|
||||
|
||||
- A small Node service on a build box, `infra/build-server/faucet/faucet.mjs`, behind Caddy at `faucet.igneum.network`. The page on igneum.network posts to it.
|
||||
- It signs a plain transfer with its own key and sends it to the Devnet 3 node on the same box by address (`FAUCET_RPC`), never chosen by chain id: Devnet 3 answers the same chain id as the shared devnet.
|
||||
- It signs a plain transfer with its own key and sends it to the Devnet 3 node on the same box by address (`FAUCET_RPC`), never chosen by chain id. The chain id it signs with is read from that node on every send: Devnet 3 moved from 4463 to 4464 at its class v5 floor on 8 October 2026.
|
||||
- The key lives only in the service's environment file on that box. It is not in the repository and not on the site.
|
||||
|
||||
## The rules, as the code enforces them
|
||||
|
|
|
|||
8
docs/build/first-contract.md
vendored
8
docs/build/first-contract.md
vendored
|
|
@ -10,7 +10,7 @@ With Foundry. Tested end to end on Devnet 3 from a build box on 8 October 2026;
|
|||
|
||||
```
|
||||
export RPC=https://rpc.devnet.igneum.network
|
||||
cast chain-id --rpc-url $RPC # 4463
|
||||
cast chain-id --rpc-url $RPC # 4464 (4463 before the class v5 floor of 8 October 2026)
|
||||
```
|
||||
|
||||
## 1. A key, for the devnet only
|
||||
|
|
@ -89,3 +89,9 @@ PASS 10:17:23Z: Devnet 3 chain id 4463, faucet drip 0x8620e9d894484e824e4ac33002
|
|||
```
|
||||
|
||||
Through the public endpoints, `https://rpc.devnet.igneum.network` and `https://faucet.igneum.network`, from the box: the first faucet drip and the first reader-path deploy on Devnet 3.
|
||||
|
||||
After the class v5 floor moved the chain id to 4464 the same afternoon, from a second box:
|
||||
|
||||
```
|
||||
PASS 12:38:39Z: Devnet 3 chain id 4464, faucet drip 0xa54fdb7e964dab095aaccaab36ea548fc3fa8727acb809b593c2d4d1359c233f, deployed Counter at 0x7de503a4F39feEBCE8c4ABbAcC04282EE75120Fe (tx 0x6ccdbb4f6393fcf09e58ba2f4de1af98c547eeab6f02d93eacfebae883200dc6), increment then setNumber(41) read back 41, receipt status 1 (success), block 29878, 12 s end to end, Foundry 1.8.5
|
||||
```
|
||||
|
|
|
|||
4
docs/build/rpc.md
vendored
4
docs/build/rpc.md
vendored
|
|
@ -9,9 +9,9 @@ Transport: HTTP POST, JSON-RPC 2.0, one request per call, no batches tested. The
|
|||
| Method | Note |
|
||||
|---|---|
|
||||
| `web3_clientVersion` | `igneumd/<version>/execution-layer-v3` |
|
||||
| `net_version` | the chain id as a decimal string, `"4463"` |
|
||||
| `net_version` | the chain id as a decimal string, `"4464"` (`"4463"` before the class v5 floor) |
|
||||
| `net_listening`, `net_peerCount` | |
|
||||
| `eth_chainId` | `0x116f` (4463) on Devnet 3; `0x1170` after its class v5 floor |
|
||||
| `eth_chainId` | `0x1170` (4464) on Devnet 3 since its class v5 floor at DAA 68,400 on 8 October 2026; `0x116f` (4463) below it. Read it, never fix it |
|
||||
| `eth_blockNumber` | the executed chain tip |
|
||||
| `eth_syncing` | `false` when the executor is at the tip |
|
||||
| `eth_mining` | `false` from the RPC's point of view: mining is the miner's, not the node's |
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
// append-only JSONL file next to the service (FAUCET_STATE, default ./grants.jsonl); the window is read from it at start.
|
||||
// Environment (EnvironmentFile=/srv/faucet/env on the box, mode 600; the key is nowhere else): FAUCET_KEY (0x + 64 hex),
|
||||
// FAUCET_RPC (the Devnet 3 node by address, never chosen by chain id: Devnet 3 answers the same id as the shared devnet),
|
||||
// FAUCET_CHAIN_ID (4463), FAUCET_PORT (8790), FAUCET_ORIGIN (the page's origin for CORS, https://igneum.network).
|
||||
// FAUCET_PORT (8790), FAUCET_ORIGIN (the page's origin for CORS, https://igneum.network). The chain id is READ FROM THE NODE on
|
||||
// every send (eth_chainId): Devnet 3 moved from 4463 to 4464 at its class v5 floor on 8 October 2026 and a fixed id signs refused transactions.
|
||||
// Signing: site/lib/eth.mjs, copied next to this file by faucet.sh (zero dependencies).
|
||||
// node faucet.mjs the service
|
||||
// node faucet.mjs --self-test the limiter and the handler against a fake node: known-failed cases first
|
||||
|
|
@ -58,7 +59,7 @@ const ignOf = wei => (Number(BigInt(wei) / 10n ** 12n) / 1e6).toFixed(6);
|
|||
|
||||
export function createHandler({ env = process.env, rpc, lim, record = () => {}, now = () => Date.now() } = {}) {
|
||||
const key = env.FAUCET_KEY || '', rpcUrl = env.FAUCET_RPC || '';
|
||||
const chainId = Number(env.FAUCET_CHAIN_ID || 4463);
|
||||
const chainIdOf = async () => Number(BigInt(await rpc('eth_chainId')));
|
||||
const origin = env.FAUCET_ORIGIN || 'https://igneum.network';
|
||||
if (AMOUNT_IGN > HARD_CAP_IGN) throw new Error(`AMOUNT_IGN ${AMOUNT_IGN} is over the ${HARD_CAP_IGN} IGN cap`);
|
||||
if (!/^0x[0-9a-fA-F]{64}$/.test(key) || !rpcUrl) throw new Error('FAUCET_KEY (0x + 64 hex) and FAUCET_RPC are required');
|
||||
|
|
@ -83,8 +84,8 @@ export function createHandler({ env = process.env, rpc, lim, record = () => {},
|
|||
if (req.method === 'OPTIONS') { res.writeHead(204); return res.end(); }
|
||||
if (path !== '/api/faucet' && path !== '/api/faucet/') return json(res, 404, { ok: false, error: 'not found' });
|
||||
if (req.method === 'GET') {
|
||||
let balance = null;
|
||||
try { balance = ignOf(await rpc('eth_getBalance', [from, 'latest'])); } catch { /* the node is the status */ }
|
||||
let balance = null, chainId = null;
|
||||
try { balance = ignOf(await rpc('eth_getBalance', [from, 'latest'])); chainId = await chainIdOf(); } catch { /* the node is the status */ }
|
||||
return json(res, 200, { ok: true, network: 'igneum-devnet-3', chainId, amount: String(AMOUNT_IGN), window_hours: WINDOW_HOURS, daily_max: DAILY_MAX, address: from, balance_ign: balance, sends_24h: lim.count(), funded: balance !== null && Number(balance) >= AMOUNT_IGN });
|
||||
}
|
||||
if (req.method !== 'POST') { res.setHeader('Allow', 'GET, POST, OPTIONS'); return json(res, 405, { ok: false, error: 'method not allowed' }); }
|
||||
|
|
@ -98,11 +99,12 @@ export function createHandler({ env = process.env, rpc, lim, record = () => {},
|
|||
const row = { t: now(), address: to, ip, tx: null };
|
||||
lim.add(row); // reserved before the send, so two asks in the same second cannot both pass
|
||||
const result = chain.then(async () => {
|
||||
const [nonceHex, block, tipHex, balHex] = await Promise.all([
|
||||
const [nonceHex, block, tipHex, balHex, chainId] = await Promise.all([
|
||||
rpc('eth_getTransactionCount', [from, 'pending']),
|
||||
rpc('eth_getBlockByNumber', ['latest', false]),
|
||||
rpc('eth_maxPriorityFeePerGas').catch(() => '0x3b9aca00'),
|
||||
rpc('eth_getBalance', [from, 'latest']),
|
||||
chainIdOf(),
|
||||
]);
|
||||
const value = toWei(AMOUNT_IGN);
|
||||
if (BigInt(balHex) < value * 2n) throw Object.assign(new Error('The faucet is empty right now. It is being refilled; try again in an hour.'), { status: 503 });
|
||||
|
|
@ -111,12 +113,12 @@ export function createHandler({ env = process.env, rpc, lim, record = () => {},
|
|||
try { gas = BigInt(await rpc('eth_estimateGas', [{ from, to, value: '0x' + value.toString(16) }])); } catch { /* the plain-transfer default */ }
|
||||
const tx = { chainId, nonce: BigInt(nonceHex), maxPriorityFeePerGas: tip, maxFeePerGas: baseFee * 2n + tip, gas, to, value, data: '0x' };
|
||||
const signed = signTransaction(tx, key);
|
||||
return rpc('eth_sendRawTransaction', [signed.raw]);
|
||||
return { hash: await rpc('eth_sendRawTransaction', [signed.raw]), chainId };
|
||||
});
|
||||
chain = result.catch(() => {});
|
||||
try {
|
||||
const hash = await result;
|
||||
row.tx = hash; record(row);
|
||||
const { hash, chainId } = await result;
|
||||
row.tx = hash; row.chainId = chainId; record(row);
|
||||
return json(res, 200, { ok: true, tx: hash, amount: String(AMOUNT_IGN), chainId, to });
|
||||
} catch (e) {
|
||||
lim.drop(row);
|
||||
|
|
@ -129,7 +131,7 @@ if (process.argv.includes('--self-test')) {
|
|||
// known-failed first: a fake node that answers every read and refuses every send must leave the limiter empty and answer 502
|
||||
let t = 1_000_000; const now = () => t;
|
||||
const fakeNode = (sendOk = true) => async (m, p) => ({
|
||||
eth_getTransactionCount: '0x1', eth_getBlockByNumber: { baseFeePerGas: '0x174876e800' }, eth_maxPriorityFeePerGas: '0x3b9aca00',
|
||||
eth_chainId: '0x1170', eth_getTransactionCount: '0x1', eth_getBlockByNumber: { baseFeePerGas: '0x174876e800' }, eth_maxPriorityFeePerGas: '0x3b9aca00',
|
||||
eth_getBalance: '0x' + (10n ** 21n).toString(16), eth_estimateGas: '0x5208',
|
||||
eth_sendRawTransaction: sendOk ? '0x' + 'ab'.repeat(32) : (() => { throw new Error('refused'); })(),
|
||||
})[m];
|
||||
|
|
@ -139,25 +141,25 @@ if (process.argv.includes('--self-test')) {
|
|||
const res = { h: {}, setHeader(k, v) { this.h[k] = v; }, writeHead(s, hh) { this.status = s; Object.assign(this.h, hh || {}); }, end(b) { resolve({ status: this.status, body: b ? JSON.parse(b) : null }); } };
|
||||
h(req, res);
|
||||
});
|
||||
const env = { FAUCET_KEY: '0x' + '11'.repeat(32), FAUCET_RPC: 'http://fake', FAUCET_CHAIN_ID: '4463' };
|
||||
const env = { FAUCET_KEY: '0x' + '11'.repeat(32), FAUCET_RPC: 'http://fake' };
|
||||
const A = '0x' + 'a1'.repeat(20), B = '0x' + 'b2'.repeat(20);
|
||||
let fails = 0; const expect = (c, msg) => { if (!c) { console.error('self-test failed: ' + msg); fails++; } };
|
||||
{ const lim = limiter(now); const h = createHandler({ env, rpc: fakeNode(false), lim, now }); const r = await call(h, 'POST', { address: A }); expect(r.status === 502 && lim.count() === 0, `a refused send must answer 502 and reserve nothing (got ${r.status}, ${lim.count()})`); }
|
||||
{ const lim = limiter(now); const h = createHandler({ env, rpc: fakeNode(), lim, now }); const r = await call(h, 'POST', { address: 'not-an-address' }); expect(r.status === 400, 'a bad address must answer 400'); }
|
||||
{ const lim = limiter(now); const recorded = []; const h = createHandler({ env, rpc: fakeNode(), lim, record: r => recorded.push(r), now });
|
||||
const r1 = await call(h, 'POST', { address: A }); expect(r1.status === 200 && r1.body.ok && r1.body.tx.startsWith('0x'), 'the first ask sends');
|
||||
const r1 = await call(h, 'POST', { address: A }); expect(r1.status === 200 && r1.body.ok && r1.body.tx.startsWith('0x') && r1.body.chainId === 4464, 'the first ask sends with the chain id read from the node');
|
||||
expect(recorded.length === 1 && recorded[0].tx === r1.body.tx, 'the send is recorded with its hash');
|
||||
const r2 = await call(h, 'POST', { address: A }); expect(r2.status === 429 && /address/.test(r2.body.error), 'the same address inside the window is refused');
|
||||
const r3 = await call(h, 'POST', { address: B }); expect(r3.status === 429 && /connection/.test(r3.body.error), 'the same connection inside the window is refused');
|
||||
const r4 = await call(h, 'POST', { address: B }, '2.2.2.2'); expect(r4.status === 200, 'another address from another connection sends');
|
||||
t += WINDOW_MS + 1; const r5 = await call(h, 'POST', { address: A }); expect(r5.status === 200, 'after the window the address sends again');
|
||||
const s = await call(h, 'GET'); expect(s.status === 200 && s.body.network === 'igneum-devnet-3' && s.body.sends_24h === 1 && s.body.funded === true, `the status carries the network and the window count (got ${JSON.stringify(s.body)})`);
|
||||
const s = await call(h, 'GET'); expect(s.status === 200 && s.body.network === 'igneum-devnet-3' && s.body.chainId === 4464 && s.body.sends_24h === 1 && s.body.funded === true, `the status carries the network and the window count (got ${JSON.stringify(s.body)})`);
|
||||
for (let i = 0; i < DAILY_MAX - 1; i++) lim.add({ t: now(), address: '0x' + String(i).padStart(40, '0'), ip: 'x' + i, tx: '0x' });
|
||||
const r6 = await call(h, 'POST', { address: '0x' + 'c3'.repeat(20) }, '3.3.3.3'); expect(r6.status === 429 && /today/.test(r6.body.error), 'the daily total refuses the next ask'); }
|
||||
{ let threw = false; try { createHandler({ env: { ...env, FAUCET_KEY: 'bad' }, rpc: fakeNode(), now }); } catch { threw = true; } expect(threw, 'a bad key must refuse to start'); }
|
||||
expect(AMOUNT_IGN <= HARD_CAP_IGN, 'the amount is under the cap');
|
||||
if (fails) process.exit(1);
|
||||
console.log(`self-test passed: a refused send reserves nothing (502), a bad address 400, the same address and the same connection are refused inside ${WINDOW_HOURS} h (429), another pair sends, the window expires, the status counts, the ${DAILY_MAX}-a-day total refuses, a bad key refuses to start, ${AMOUNT_IGN} IGN is under the ${HARD_CAP_IGN} IGN cap`);
|
||||
console.log(`self-test passed: a refused send reserves nothing (502), a bad address 400, the same address and the same connection are refused inside ${WINDOW_HOURS} h (429), another pair sends, the window expires, the status counts, the ${DAILY_MAX}-a-day total refuses, a bad key refuses to start, the chain id comes from the node, ${AMOUNT_IGN} IGN is under the ${HARD_CAP_IGN} IGN cap`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
# infra/build-server/faucet/faucet.sh status the unit, the loopback status (balance, sends in the window), the Caddy host
|
||||
# infra/build-server/faucet/faucet.sh self-test node faucet.mjs --self-test on the box
|
||||
# /srv/faucet/env (mode 600, the build user's) is written by hand on the box and never by this script: FAUCET_KEY, FAUCET_RPC
|
||||
# (the Devnet 3 node by address), FAUCET_CHAIN_ID, FAUCET_PORT, FAUCET_ORIGIN. The key is nowhere else.
|
||||
# (the Devnet 3 node by address; the chain id is read from it), FAUCET_PORT, FAUCET_ORIGIN. The key is nowhere else.
|
||||
set -euo pipefail
|
||||
HERE=$(cd "$(dirname "$0")" && pwd); ROOT=$(cd "$HERE/../../.." && pwd)
|
||||
KEY="${IGNEUM_BUILD_KEY:-$HOME/.ssh/igneum_ed25519}"; HOST=$(head -1 "${IGNEUM_BUILD_HOST_FILE:-$HOME/.config/igneum/build-server}" | tr -d '[:space:]')
|
||||
|
|
@ -37,7 +37,7 @@ case "$mode" in
|
|||
if [ "$GO" = 0 ]; then
|
||||
say "DRY: scp faucet.mjs, site/lib/eth.mjs -> $HOST:/srv/faucet/; igneum-faucet.service -> root@$IP:/etc/systemd/system/; append to /etc/caddy/Caddyfile unless $FAUCET_HOST is there:"; caddy_block; say "DRY: systemctl daemon-reload, enable --now igneum-faucet; curl 127.0.0.1:$PORT/api/faucet"; exit 0
|
||||
fi
|
||||
"${SSHB[@]}" 'test -s /srv/faucet/env' || { say "/srv/faucet/env is missing on the box: write it by hand first (FAUCET_KEY, FAUCET_RPC, FAUCET_CHAIN_ID, FAUCET_PORT, FAUCET_ORIGIN)"; exit 1; }
|
||||
"${SSHB[@]}" 'test -s /srv/faucet/env' || { say "/srv/faucet/env is missing on the box: write it by hand first (FAUCET_KEY, FAUCET_RPC, FAUCET_PORT, FAUCET_ORIGIN)"; exit 1; }
|
||||
scp -q -i "$KEY" "$HERE/faucet.mjs" "$ROOT/site/lib/eth.mjs" "$HOST:/srv/faucet/"
|
||||
"${SSHB[@]}" 'cd /srv/faucet && node faucet.mjs --self-test' || { say "the self-test failed on the box; nothing started"; exit 1; }
|
||||
scp -q -i "$KEY" "$HERE/igneum-faucet.service" "root@$IP:/etc/systemd/system/igneum-faucet.service"
|
||||
|
|
|
|||
|
|
@ -245,8 +245,8 @@ table{min-width:560px}
|
|||
<p><strong>The EVM you already know.</strong> Solidity deploys unchanged. Standard JSON-RPC, EIP-1559 transactions, the chain id in the signature, <code>cancun</code> as the EVM version. Gas has two dimensions on Igneum, execution and proving, and the node folds the second into the price it quotes, so <code>eth_estimateGas</code> and <code>eth_gasPrice</code> work as they do on Ethereum.</p>
|
||||
</section>
|
||||
<section class="doc-section"><h2 id="networks">Networks</h2>
|
||||
<div class="tbl"><table><thead><tr><th></th><th>Devnet 3</th><th>Testnet</th><th>Mainnet</th></tr></thead><tbody><tr><td>Chain id</td><td>4463 (<code>0x116f</code>)</td><td>4462 (<code>0x116e</code>)</td><td>4461 (<code>0x116d</code>)</td></tr><tr><td>Network id</td><td><code>igneum-devnet-3</code></td><td><code>igneum-testnet-1</code></td><td>not started</td></tr><tr><td>RPC</td><td><code>https://rpc.devnet.igneum.network</code> (a node you run serves <code>http://127.0.0.1:26790</code>)</td><td><code>https://rpc.testnet.igneum.network</code> (answers; nothing mines there yet, so a transaction waits)</td><td>none</td></tr><tr><td>Coins</td><td>no value, resets without notice</td><td>no value, resets with notice</td><td>not started</td></tr><tr><td>Symbol, decimals</td><td>IGN, 18</td><td>IGN, 18</td><td>IGN, 18</td></tr></tbody></table></div>
|
||||
<p>Devnet 3 is where you build today. It is a developer network: it resets without notice and its coins have no value. Its public RPC takes the read methods, <code>eth_sendRawTransaction</code> and a wRPC websocket at <code>/ws</code>, at 20 requests a second per address. The public testnet exists, its RPC answers, and no blocks are being produced on it until it opens. Mainnet has no date. Devnet 3 answers chain id 4463 until its class v5 floor, then 4464.</p>
|
||||
<div class="tbl"><table><thead><tr><th></th><th>Devnet 3</th><th>Testnet</th><th>Mainnet</th></tr></thead><tbody><tr><td>Chain id</td><td>4464 (<code>0x1170</code>) since its class v5 floor on 8 October 2026; 4463 below it</td><td>4462 (<code>0x116e</code>)</td><td>4461 (<code>0x116d</code>)</td></tr><tr><td>Network id</td><td><code>igneum-devnet-3</code></td><td><code>igneum-testnet-1</code></td><td>not started</td></tr><tr><td>RPC</td><td><code>https://rpc.devnet.igneum.network</code> (a node you run serves <code>http://127.0.0.1:26790</code>)</td><td><code>https://rpc.testnet.igneum.network</code> (answers; nothing mines there yet, so a transaction waits)</td><td>none</td></tr><tr><td>Coins</td><td>no value, resets without notice</td><td>no value, resets with notice</td><td>not started</td></tr><tr><td>Symbol, decimals</td><td>IGN, 18</td><td>IGN, 18</td><td>IGN, 18</td></tr></tbody></table></div>
|
||||
<p>Devnet 3 is where you build today. It is a developer network: it resets without notice and its coins have no value. Its public RPC takes the read methods, <code>eth_sendRawTransaction</code> and a wRPC websocket at <code>/ws</code>, at 20 requests a second per address. The public testnet exists, its RPC answers, and no blocks are being produced on it until it opens. Mainnet has no date. Devnet 3 answered 4463 until its class v5 floor at DAA 68,400 on 8 October 2026 and 4464 from it; read it with <code>eth_chainId</code> rather than fixing it, since a transaction signed for the wrong id is refused.</p>
|
||||
</section>
|
||||
<section class="doc-section"><h2 id="endpoints-and-tools">Endpoints and tools</h2>
|
||||
<ul><li><strong>Wallet.</strong> Any Ethereum wallet. <a href="/metamask">Add Igneum to MetaMask</a> with one click, or the <a href="/wallet">Igneum wallet</a>.</li><li><strong>Faucet.</strong> <a href="/faucet">10 IGN of Devnet 3 coin</a> per address per day. No account.</li><li><strong>Explorer.</strong> <a href="/explorer">The explorer</a> shows blocks, the DAG, miners and addresses. The EVM views, transactions and contracts, are being built and link from the same page as they land.</li><li><strong>Swap.</strong> <a href="/swap">The swap</a>: test tokens on Devnet 3, every swap in a proven block.</li><li><strong>Source.</strong> <a href="https://git.igneum.network/igneum-network/igneum" rel="noopener">git.igneum.network/igneum-network/igneum</a>: the node, the miner, the site, and these pages under <code>docs/build/</code>.</li></ul>
|
||||
|
|
@ -264,7 +264,7 @@ forge create src/Counter.sol:Counter --rpc-url $RPC --private-key $PK --broadcas
|
|||
<p><code>forge create</code> prints <code>Deployed to: 0x...</code>. Call it:</p>
|
||||
<pre>cast send 0xDEPLOYED "increment()" --rpc-url $RPC --private-key $PK
|
||||
cast call 0xDEPLOYED "number()(uint256)" --rpc-url $RPC</pre>
|
||||
<p>The call answers <code>1</code>. Paste the transaction hash into <a href="/explorer">the explorer</a>. Hardhat, ethers and viem work the same way: chain id 4463, the RPC above.</p>
|
||||
<p>The call answers <code>1</code>. Paste the transaction hash into <a href="/explorer">the explorer</a>. Hardhat, ethers and viem work the same way: chain id 4464, the RPC above.</p>
|
||||
</section>
|
||||
<section class="doc-section"><h2 id="the-rpc-the-node-serves">The RPC the node serves</h2>
|
||||
<p>Read from a Devnet 3 node, not from a spec. <code>web3_clientVersion</code> answers <code>igneumd/2.1.0/execution-layer-v3</code>. The full list, served and not served, with the probe that produced it: <a href="https://git.igneum.network/igneum-network/igneum/src/branch/master/docs/build/rpc.md" rel="noopener">docs/build/rpc.md</a>.</p>
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ dt{color:var(--ash)}dd{margin:0;font-family:var(--f-mono);font-size:14px;overflo
|
|||
<div class="eyebrow"><span class="line"></span>Devnet 3 faucet</div>
|
||||
<h1>10 IGN a day, <span class="accent">for building.</span></h1>
|
||||
<p>Paste an address. The faucet sends 10 IGN of Devnet 3 coin and shows you the transaction hash. Once per address per day, once per connection per day. No account, no sign-in, nothing to install.</p>
|
||||
<p class="notice" id="faucet-state">Devnet 3, chain id 4463. The coins have no value and the chain resets without notice. <span id="faucet-balance"></span></p>
|
||||
<p class="notice" id="faucet-state">Devnet 3, chain id 4464 since its class v5 floor. The coins have no value and the chain resets without notice. <span id="faucet-balance"></span></p>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<section class="card" aria-labelledby="ask">
|
||||
|
|
@ -252,7 +252,7 @@ dt{color:var(--ash)}dd{margin:0;font-family:var(--f-mono);font-size:14px;overflo
|
|||
<div class="rule"><span class="num">04</span><div><b>What is stored</b><span>The address, the connection's IP, the transaction hash and the time, on the box that runs the faucet, for 24 hours of rate limiting. Nothing else.</span></div></div>
|
||||
</div>
|
||||
<dl>
|
||||
<dt>Chain id</dt><dd>4463 (Devnet 3)</dd>
|
||||
<dt>Chain id</dt><dd>4464 (Devnet 3; 4463 before 8 October 2026)</dd>
|
||||
<dt>RPC</dt><dd>https://rpc.devnet.igneum.network</dd>
|
||||
<dt>Wallet set-up</dt><dd><a href="/metamask">MetaMask: chain id, RPC, one click</a></dd>
|
||||
<dt>Then</dt><dd><a href="/build">Deploy a contract in five minutes</a></dd>
|
||||
|
|
|
|||
|
|
@ -273,12 +273,12 @@
|
|||
<article class="record"><div class="record-top"><time datetime="2026-10-05">5 Oct 2026</time><span class="badge">log</span></div><h3>Live devnet: real transactions, the first non-empty shard proven and…</h3><p>Live devnet: real transactions, the first non-empty shard proven and paid, and the exporter's block structure fixed</p></article>
|
||||
<article class="record"><div class="record-top"><time datetime="2026-10-05">5 Oct 2026</time><span class="badge">log</span></div><h3>The program id split</h3><p>The program id split: why the Apple M5 Max rejected the RTX 5090 Windows rig's proofs, and the verifier at 114 s</p></article>
|
||||
<article class="record"><div class="record-top"><time datetime="2026-10-05">5 Oct 2026</time><span class="badge">log</span></div><h3>Live devnet: the first shards proven, verified and paid</h3></article>
|
||||
<article class="record"><div class="record-top"><time datetime="2026-10-04">4 Oct 2026</time><span class="badge">log</span></div><h3>Economy simulation: mining versus proving under stress</h3><p>Sim/economy: mining versus proving under stress, agent-based</p></article>
|
||||
<article class="record"><div class="record-top"><time datetime="2026-10-04">4 Oct 2026</time><span class="badge">log</span></div><h3>Difficulty rule attacked seven ways</h3><p>Difficulty rule under attack: pool hopping, pulsed rental, timestamp stretching, short-lane oscillation, epoch games, polluted window, block flood</p></article>
|
||||
<article class="record"><div class="record-top"><time datetime="2026-10-04">4 Oct 2026</time><span class="badge">log</span></div><h3>Timestamp attack on the difficulty rule fixed</h3><p>Difficulty rule: timestamp attack fixed , simulator regression, 3-node forger test</p></article>
|
||||
<article class="record"><div class="record-top"><time datetime="2026-10-04">4 Oct 2026</time><span class="badge">log</span></div><h3>Devnet v4: nine branches merged into one node</h3><p>Devnet-v4 integration: nine branches merged, 3-node test network on the merged node, Windows cross-build</p></article>
|
||||
<article class="record"><div class="record-top"><time datetime="2026-10-04">4 Oct 2026</time><span class="badge">log</span></div><h3>Generator v2 adopted: every hash does 128 distinct reads</h3><p>Generator version 2 adopted: exact load count, fresh-source loads, program acceptance; every vector re-cut, three workers re-checked, 20,000-program census, devnet-v4 binaries rebuilt</p></article>
|
||||
<article class="record"><div class="record-top"><time datetime="2026-10-04">4 Oct 2026</time><span class="badge">log</span></div><h3>First GPU proof of an Igneum block: 1.4 s on an RTX 5090</h3><p>Proving v0 on the RTX 5090: first GPU proof of an Igneum block</p></article></div>
|
||||
<article class="record"><div class="record-top"><time datetime="2026-10-04">4 Oct 2026</time><span class="badge">log</span></div><h3>Devnet v4 live: generator v2, two-thirds floor, fresh chain</h3><p>Devnet v4 cut-over: generator v2, 2/3 floor, three nodes and a seed on a fresh chain</p></article>
|
||||
<article class="record"><div class="record-top"><time datetime="2026-10-04">4 Oct 2026</time><span class="badge">log</span></div><h3>One-click Windows workers</h3><p>One-click Windows workers: what the Apple M5 Max could measure</p></article>
|
||||
<article class="record"><div class="record-top"><time datetime="2026-10-04">4 Oct 2026</time><span class="badge">log</span></div><h3>First live hourly swap: no pause on Mac, NVIDIA or AMD</h3><p>First hourly program swap on the live devnet: compile-ahead, no pause, two cards</p></article>
|
||||
<article class="record"><div class="record-top"><time datetime="2026-10-04">4 Oct 2026</time><span class="badge">log</span></div><h3>Proving: devnet v4 shards on the Apple M5 Max CPU, loaded machine</h3></article>
|
||||
<article class="record"><div class="record-top"><time datetime="2026-10-04">4 Oct 2026</time><span class="badge">log</span></div><h3>First live finality lock: 77.4% of weight, 17 voters</h3><p>First finality lock on the live devnet: checkpoint 242 at 77.4% of all weight, two hours after genesis</p></article>
|
||||
<article class="record"><div class="record-top"><time datetime="2026-10-04">4 Oct 2026</time><span class="badge">log</span></div><h3>The gfx1036 worker fault and what the Apple M5 Max could and could…</h3><p>The gfx1036 worker fault and what the Apple M5 Max could and could not reproduce</p></article></div>
|
||||
<p class="empty-state" data-filter-empty="log" hidden>Nothing in the log matches that.</p>
|
||||
<p class="note">Every entry is a dated heading of <a href="/bench">the engineering log</a>, where the commands and the hardware are. The phases and their gates are the litepaper’s <a href="/litepaper#roadmap">roadmap</a>.</p>
|
||||
<div class="onward"><a href="/bench" class="btn">The engineering log</a><a href="/evidence" class="btn">Every claim and its status</a><a href="/live" class="btn">The live devnet</a></div>
|
||||
|
|
|
|||
|
|
@ -222,33 +222,33 @@
|
|||
},
|
||||
{
|
||||
"date": "2026-10-04",
|
||||
"text": "Sim/economy: mining versus proving under stress, agent-based",
|
||||
"short": "Economy simulation: mining versus proving under stress"
|
||||
"text": "Devnet v4 cut-over: generator v2, 2/3 floor, three nodes and a seed on a fresh chain",
|
||||
"short": "Devnet v4 live: generator v2, two-thirds floor, fresh chain"
|
||||
},
|
||||
{
|
||||
"date": "2026-10-04",
|
||||
"text": "Difficulty rule under attack: pool hopping, pulsed rental, timestamp stretching, short-lane oscillation, epoch games, polluted window, block flood",
|
||||
"short": "Difficulty rule attacked seven ways"
|
||||
"text": "One-click Windows workers: what the Apple M5 Max could measure",
|
||||
"short": "One-click Windows workers"
|
||||
},
|
||||
{
|
||||
"date": "2026-10-04",
|
||||
"text": "Difficulty rule: timestamp attack fixed , simulator regression, 3-node forger test",
|
||||
"short": "Timestamp attack on the difficulty rule fixed"
|
||||
"text": "First hourly program swap on the live devnet: compile-ahead, no pause, two cards",
|
||||
"short": "First live hourly swap: no pause on Mac, NVIDIA or AMD"
|
||||
},
|
||||
{
|
||||
"date": "2026-10-04",
|
||||
"text": "Devnet-v4 integration: nine branches merged, 3-node test network on the merged node, Windows cross-build",
|
||||
"short": "Devnet v4: nine branches merged into one node"
|
||||
"text": "Proving: devnet v4 shards on the Apple M5 Max CPU, loaded machine",
|
||||
"short": "Proving: devnet v4 shards on the Apple M5 Max CPU, loaded machine"
|
||||
},
|
||||
{
|
||||
"date": "2026-10-04",
|
||||
"text": "Generator version 2 adopted: exact load count, fresh-source loads, program acceptance; every vector re-cut, three workers re-checked, 20,000-program census, devnet-v4 binaries rebuilt",
|
||||
"short": "Generator v2 adopted: every hash does 128 distinct reads"
|
||||
"text": "First finality lock on the live devnet: checkpoint 242 at 77.4% of all weight, two hours after genesis",
|
||||
"short": "First live finality lock: 77.4% of weight, 17 voters"
|
||||
},
|
||||
{
|
||||
"date": "2026-10-04",
|
||||
"text": "Proving v0 on the RTX 5090: first GPU proof of an Igneum block",
|
||||
"short": "First GPU proof of an Igneum block: 1.4 s on an RTX 5090"
|
||||
"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…"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue