diff --git a/packages/networks/src/defaults/genesis.ts b/packages/networks/src/defaults/genesis.ts index f9e8c1b..9494570 100644 --- a/packages/networks/src/defaults/genesis.ts +++ b/packages/networks/src/defaults/genesis.ts @@ -11,6 +11,9 @@ import type { KnownGenesis } from '../types.js'; // IMPORTANT: Apart from the test relays, this list is limited to live parachains // and live production networks. It does not and should not contain any testnets, // either stand-alone or connected to test relays such as Westend/Rococo +// pezkuwi (the mainnet relay) has no entry while the chain is relaunched from +// genesis: a stale hash would identify a chain that no longer exists, and an +// absent one leaves the app to read the connected node. export const knownGenesis: KnownGenesis = { acala: [ '0xfc41b9bd8ef8fe53d58c7ea67c794c7ec9a73daf05e6d54b14ff6342c99ba64c' @@ -61,9 +64,6 @@ export const knownGenesis: KnownGenesis = { '0x6bfe24dca2a3be10f22212678ac13a6446ec764103c0f3471c71609eac384aae', '0xf73467c6544aa68df2ee546b135f955c46b90fa627e9b5d7935f41061bb8a5a9' ], - dicle: [ - '0xd9d3cd7c1e5d890d969b957f4c5b71a111bbeeabc968f1d0d4538c2663f080a7' - ], edgeware: [ '0x742a2ca70c2fda6cee4f8df98d64c4c670a052d9568058982dad9d5a7a135c5b' ], @@ -138,12 +138,6 @@ export const knownGenesis: KnownGenesis = { pendulum: [ '0x5d3c298622d5634ed019bf61ea4b71655030015bde9beb0d6a24743714462c86' ], - pezkuwi: [ - '0xbb4a61ab0c4b8c12f5eab71d0c86c482e03a275ecdafee678dea712474d33d75' - ], - pezkuwichain: [ - '0x32154fd2c844f928c82964ff66168b41b15fc235f3a956d14393734c1ed4326b' - ], phala: [ '0x1bb969d85965e4bb5a651abbedf21a54b6b31a21f66b5401cc3f1e286268d736' ], @@ -218,7 +212,7 @@ export const knownGenesis: KnownGenesis = { '0x50dd5d206917bf10502c68fb4d18a59fc8aa31586f4e8856b493e43544aa82aa' ], zagros: [ - '0x297f5a4d105b4b28312586ff1915572ffe4ee015ff772b76399ecbff25a22026' + '0x1b0b4727bbb5e44ed587d1056b4ad537ffb330034509a58866a088d77e792cd5' ], zeitgeist: [ '0x1bf2a2ecb4a868de66ea8610f2ce7c8c43706561b6476031315f6640fe38e060' diff --git a/packages/networks/src/index.spec.ts b/packages/networks/src/index.spec.ts index 61b66ce..2a2a938 100644 --- a/packages/networks/src/index.spec.ts +++ b/packages/networks/src/index.spec.ts @@ -3,19 +3,12 @@ /// -import type { BizinikwiNetwork } from './types.js'; - import { knownGenesis, knownIcon, knownLedger, knownTestnet } from './defaults/index.js'; import { allNetworks, availableNetworks, selectableNetworks } from './index.js'; describe('availableNetworks', (): void => { - it('has the correct starting order', (): void => { - expect(availableNetworks.slice(0, 3).map(({ prefix }) => prefix)).toEqual([0, 2, 42]); - }); - - it('has a sorted list (first external, last external)', (): void => { - expect(availableNetworks[3].displayName).toEqual('3DP network'); - expect(availableNetworks[availableNetworks.length - 1].displayName).toEqual('ZERO'); + it('lists the Pezkuwi networks first, in their declared order', (): void => { + expect(availableNetworks.map(({ network }) => network)).toEqual(['pezkuwi', 'zagros', 'bizinikiwi']); }); it('has no ignored networks', (): void => { @@ -70,51 +63,52 @@ describe('availableNetworks', (): void => { ).toEqual([]); }); - it('has all the correct fields', (): void => { - expect(availableNetworks[0]).toEqual({ - decimals: [10], - displayName: 'Polkadot Relay Chain', - genesisHash: [ - '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3' - ], - hasLedgerSupport: true, - icon: 'polkadot', - isIgnored: false, - isTestnet: false, - network: 'polkadot', - prefix: 0, - slip44: 354, - standardAccount: '*25519', - symbols: ['DOT'], - website: 'https://polkadot.network' - }); + // What the nodes report (system_properties) and what a wallet formats + // addresses with must agree: ss58Format 42, HEZ, 12 decimals. + it('gives the Pezkuwi chains the format their nodes report', (): void => { + for (const network of ['pezkuwi', 'zagros']) { + const n = availableNetworks.find((a) => a.network === network); + + expect(n && { decimals: n.decimals, prefix: n.prefix, symbols: n.symbols }).toEqual({ + decimals: [12], + prefix: 42, + symbols: ['HEZ'] + }); + } + }); + + it('knows Zagros by its genesis, and not the mainnet while it is relaunched', (): void => { + expect(availableNetworks.find((a) => a.network === 'zagros')?.genesisHash).toEqual([ + '0x1b0b4727bbb5e44ed587d1056b4ad537ffb330034509a58866a088d77e792cd5' + ]); + expect(availableNetworks.find((a) => a.network === 'pezkuwi')?.genesisHash).toEqual([]); }); }); describe('allNetworks', (): void => { - it('has no ss58 duplicates', (): void => { - const dupes: BizinikwiNetwork[] = []; - const uniques: BizinikwiNetwork[] = []; + // Upstream's registry gives every prefix to one network. The Pezkuwi chains + // share the generic format 42 by design; any other prefix stays unique. + it('shares an ss58 prefix only at 42', (): void => { + const seen = new Map(); - allNetworks.forEach((a): void => { - if (uniques.some((u) => u.prefix === a.prefix)) { - dupes.push(a); - } else { - uniques.push(a); - } + allNetworks.forEach(({ network, prefix }): void => { + seen.set(prefix, [...(seen.get(prefix) || []), network]); }); - expect(dupes).toEqual([]); + expect([...seen.entries()].filter(([prefix, networks]) => prefix !== 42 && networks.length > 1)).toEqual([]); + }); + + it('has no two networks claiming one genesis', (): void => { + const hashes = allNetworks.flatMap(({ genesisHash }) => genesisHash); + + expect(hashes.length).toEqual(new Set(hashes).size); }); }); describe('selectableNetworks', (): void => { - it('has the correct starting order', (): void => { - expect(selectableNetworks.slice(0, 3).map(({ prefix }) => prefix)).toEqual([0, 2, 42]); - }); - - it('has a sorted list (first external, last external)', (): void => { - expect(selectableNetworks[3].displayName).toEqual('3DP network'); - expect(selectableNetworks[selectableNetworks.length - 1].displayName).toEqual('Zeitgeist'); + // selectable = has a genesis, or uses the generic format 42; every Pezkuwi + // network uses 42, so the mainnet stays selectable while it has no genesis + it('offers every Pezkuwi network', (): void => { + expect(selectableNetworks.map(({ network }) => network)).toEqual(['pezkuwi', 'zagros', 'bizinikiwi']); }); }); diff --git a/packages/networks/src/interfaces.ts b/packages/networks/src/interfaces.ts index ba835bf..be0c02c 100644 --- a/packages/networks/src/interfaces.ts +++ b/packages/networks/src/interfaces.ts @@ -5,27 +5,29 @@ import type { BizinikwiNetwork, KnownBizinikiwi, Network } from './types.js'; import { knownGenesis, knownIcon, knownLedger, knownTestnet } from './defaults/index.js'; -// These are known prefixes that are not sorted -const UNSORTED = [0, 2, 42]; +// Prefixes kept in their declared order at the head of the list +const UNSORTED = [42]; const TESTNETS = ['testnet']; const customNetworks: KnownBizinikiwi[] = [ + // The Pezkuwi chains encode addresses with the generic prefix 42, the format + // their nodes report (system_properties: ss58Format 42, HEZ, 12 decimals). { - decimals: [10], + decimals: [12], displayName: 'Pezkuwi Relay Chain', network: 'pezkuwi', - prefix: 0, + prefix: 42, standardAccount: '*25519', - symbols: ['PZW'], + symbols: ['HEZ'], website: 'https://pezkuwichain.io' }, { decimals: [12], displayName: 'Zagros Relay Chain', network: 'zagros', - prefix: 2, + prefix: 42, standardAccount: '*25519', - symbols: ['ZGS'], + symbols: ['HEZ'], website: 'https://zagros.pezkuwichain.io' }, { @@ -36,15 +38,6 @@ const customNetworks: KnownBizinikiwi[] = [ standardAccount: '*25519', symbols: ['BZN'], website: 'https://bizinikiwi.pezkuwichain.io' - }, - { - decimals: [18], - displayName: 'PezkuwiChain', - network: 'pezkuwichain', - prefix: 1453, - standardAccount: '*25519', - symbols: ['PZC'], - website: 'https://network.pezkuwichain.io' } ];