feat: initial Pezkuwi Apps rebrand from polkadot-apps

Rebranded terminology:
- Polkadot → Pezkuwi
- Kusama → Dicle
- Westend → Zagros
- Rococo → PezkuwiChain
- Substrate → Bizinikiwi
- parachain → teyrchain

Custom logos with Kurdistan brand colors (#e6007a → #86e62a):
- bizinikiwi-hexagon.svg
- sora-bizinikiwi.svg
- hezscanner.svg
- heztreasury.svg
- pezkuwiscan.svg
- pezkuwistats.svg
- pezkuwiassembly.svg
- pezkuwiholic.svg
This commit is contained in:
2026-01-07 13:05:27 +03:00
commit d21bfb1320
5867 changed files with 329019 additions and 0 deletions
@@ -0,0 +1,78 @@
// Copyright 2017-2025 @pezkuwi/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { TFunction } from '../types.js';
import type { LinkOption } from './types.js';
export const CUSTOM_ENDPOINT_KEY = 'pezkuwi-app-custom-endpoints';
interface EnvWindow {
// eslint-disable-next-line camelcase
process_env?: {
WS_URL: string;
}
}
export function createCustom (t: TFunction): LinkOption[] {
const WS_URL = (
(typeof process !== 'undefined' ? process.env?.WS_URL : undefined) ||
(typeof window !== 'undefined' ? (window as EnvWindow).process_env?.WS_URL : undefined)
);
return WS_URL
? [
{
isHeader: true,
text: t('rpc.dev.custom', 'Custom environment', { ns: 'apps-config' }),
textBy: '',
ui: {},
value: ''
},
{
info: 'WS_URL',
text: t('rpc.dev.custom.entry', 'Custom {{WS_URL}}', { ns: 'apps-config', replace: { WS_URL } }),
textBy: WS_URL,
ui: {},
value: WS_URL
}
]
: [];
}
export function createOwn (t: TFunction): LinkOption[] {
try {
// this may not be available, e.g. when running via script
const storedItems = typeof localStorage === 'object' && typeof localStorage.getItem === 'function'
? localStorage.getItem(CUSTOM_ENDPOINT_KEY)
: null;
if (storedItems) {
const items = JSON.parse(storedItems) as string[];
return items.map((textBy) => ({
info: 'local',
text: t('rpc.dev.custom.own', 'Custom', { ns: 'apps-config' }),
textBy,
ui: {},
value: textBy
}));
}
} catch (e) {
console.error(e);
}
return [];
}
export function createDev (t: TFunction): LinkOption[] {
return [
{
dnslink: 'local',
info: 'local',
text: t('rpc.dev.local', 'Local Node', { ns: 'apps-config' }),
textBy: '127.0.0.1:9944',
ui: {},
value: 'ws://127.0.0.1:9944'
}
];
}
@@ -0,0 +1,152 @@
// Copyright 2017-2025 @pezkuwi/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0
/// <reference types="@pezkuwi/dev-test/globals.d.ts" />
import { strict as assert } from 'node:assert';
import { isNumber, isString } from '@pezkuwi/util';
import { createWsEndpoints } from './index.js';
interface Endpoint {
name: string;
provider: string;
value: string;
}
const allEndpoints = createWsEndpoints(undefined, false, false);
const INVALID_CHARS = ['%'];
describe('WS urls are all valid', (): void => {
const endpoints = allEndpoints
.filter(({ value }) =>
value &&
isString(value) &&
!value.includes('127.0.0.1')
)
.map(({ text, textBy, value }): Endpoint => ({
name: text as string,
provider: textBy,
value
}));
for (const { name, provider, value } of endpoints) {
it(`${name}:: ${provider}`, (): void => {
assert(value.startsWith('wss://') || value.startsWith('light://bizinikiwi-connect/'), `${name}:: ${provider} -> ${value} should start with wss:// or light://`);
assert(!INVALID_CHARS.some((c) => value.includes(c)), `${value} should not contain invalid characters such as ${INVALID_CHARS.join(', ')}`);
});
}
});
describe('urls are sorted', (): void => {
let hasDevelopment = false;
let lastHeader = '';
const filtered = allEndpoints.filter(({ isHeader, text }): boolean => {
hasDevelopment = hasDevelopment || (!!isHeader && text === 'Development');
return !hasDevelopment;
});
filtered.forEach(({ isHeader, paraId, text, textBy }, index): void => {
if (isHeader) {
lastHeader = text as string;
} else {
it(`${lastHeader}:: ${text as string}:: ${textBy}`, (): void => {
const item = filtered[index - 1];
assert((
item.isHeader ||
item.linked ||
(
isNumber(item.paraId) &&
(
item.paraId < 2000
? isNumber(paraId) && paraId >= 2000
: false
)
) ||
item.text === '' ||
text === item.text ||
(text as string).localeCompare(item.text as string) === 1
), `${lastHeader}:: ${text as string} needs to be before ${item.text as string}`);
});
}
});
});
describe('urls are not duplicated', (): void => {
let hasDevelopment = false;
let lastHeader = '';
const map = allEndpoints
.filter(({ isDisabled, isHeader, isUnreachable, text }): boolean => {
hasDevelopment = hasDevelopment || (!!isHeader && text === 'Development');
return !hasDevelopment && !isDisabled && !isUnreachable;
})
.reduce((map, { isHeader, text, value }): Record<string, string[]> => {
if (isHeader) {
lastHeader = text as string;
} else {
const path = `${lastHeader} -> ${text as string}`;
const key = value.endsWith('/')
? value.substring(0, value.length - 1)
: value;
map[key] ||= [];
map[key].push(path);
}
return map;
}, {} as Record<string, string[]>);
for (const [url, paths] of Object.entries<string[]>(map)) {
it(`${url}`, (): void => {
assert(paths.length === 1, `${url} appears multiple times - ${paths.map((p) => `\n\t"${p}"`).join('')}`);
});
}
});
describe('endpopints naming', (): void => {
const emoji = /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/;
const endpoints: Record<string, Endpoint> = allEndpoints
.filter(({ value }) =>
value &&
isString(value) &&
!value.includes('127.0.0.1')
)
.map(({ text, textBy, value }): Endpoint => ({
name: text as string,
provider: textBy,
value
}))
.reduce((all, e) => ({
...all,
[`${e.name}:: ${e.provider}`]: e
}), {});
for (const [key, { name, provider }] of Object.entries<Endpoint>(endpoints)) {
describe(`${key}`, (): void => {
it(`[${key}] has no emojis`, (): void => {
assert(!emoji.test(name), `${name} should not contain any emojis`);
assert(!emoji.test(provider), `${name}:: ${provider} should not contain any emojis`);
});
it(`[${key}] not all uppercase`, (): void => {
assert(!provider.includes(' ') || (provider.toLocaleUpperCase() !== provider), `${name}:: ${provider} should not be all uppercase`);
});
it(`[${key}] does not contain "Teyrchain`, (): void => {
assert(!name.includes('Teyrchain'), `${name} should not contain "Teyrchain" (redundant)`);
});
it(`[${key}] does not contain a relay name`, (): void => {
assert(name.includes('Dicle') ? true : !name.includes(' ') || !name.includes('Dicle'), `${name} should not contain "Dicle" (redundant)`);
assert(name.includes('Pezkuwi') ? true : !name.includes(' ') || !name.includes('Pezkuwi'), `${name} should not contain "Pezkuwi" (redundant)`);
assert(name.includes('PezkuwiChain') ? true : !name.includes(' ') || !name.includes('PezkuwiChain'), `${name} should not contain "PezkuwiChain" (redundant)`);
assert(name.includes('Zagros') ? true : !name.includes(' ') || !name.includes('Zagros'), `${name} should not contain "Zagros" (redundant)`);
});
});
}
});
+110
View File
@@ -0,0 +1,110 @@
// Copyright 2017-2025 @pezkuwi/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { TFunction, TOptions } from '../types.js';
import type { LinkOption } from './types.js';
import { createCustom, createDev, createOwn } from './development.js';
import { prodChains, prodRelayDicle, prodRelayPezkuwi } from './production.js';
import { testChains, testRelayZagros } from './testing.js';
import { testRelayPaseo } from './testingRelayPaseo.js';
import { expandEndpoints } from './util.js';
export { CUSTOM_ENDPOINT_KEY } from './development.js';
export * from './production.js';
export * from './testing.js';
function defaultT (keyOrText: string, text?: string | TOptions, options?: TOptions): string {
return (
(options?.replace?.host as string) ||
text?.toString() ||
keyOrText
);
}
export function createWsEndpoints (t: TFunction = defaultT, firstOnly = false, withSort = true): LinkOption[] {
return [
...createCustom(t),
{
isDisabled: false,
isHeader: true,
isSpaced: true,
text: t('rpc.header.favorite', 'Favorite chains', { ns: 'apps-config' }),
textBy: '',
ui: {},
value: ''
},
{
isDisabled: false,
isHeader: true,
isSpaced: true,
text: t('rpc.header.pezkuwi.relay', 'Pezkuwi & teyrchains', { ns: 'apps-config' }),
textBy: '',
ui: {},
value: ''
},
...expandEndpoints(t, [prodRelayPezkuwi], firstOnly, withSort),
{
isDisabled: false,
isHeader: true,
isSpaced: true,
text: t('rpc.header.dicle.relay', 'Dicle & teyrchains', { ns: 'apps-config' }),
textBy: '',
ui: {},
value: ''
},
...expandEndpoints(t, [prodRelayDicle], firstOnly, withSort),
{
isDisabled: false,
isHeader: true,
isSpaced: true,
text: t('rpc.header.zagros.relay', 'Test Zagros & teyrchains', { ns: 'apps-config' }),
textBy: '',
ui: {},
value: ''
},
...expandEndpoints(t, [testRelayZagros], firstOnly, withSort),
{
isDisabled: false,
isHeader: true,
isSpaced: true,
text: t('rpc.header.paseo.relay', 'Test Paseo & teyrchains', { ns: 'apps-config' }),
textBy: '',
ui: {},
value: ''
},
...expandEndpoints(t, [testRelayPaseo], firstOnly, withSort),
{
isDisabled: false,
isHeader: true,
isSpaced: true,
text: t('rpc.header.live', 'Live networks', { ns: 'apps-config' }),
textBy: '',
ui: {},
value: ''
},
...expandEndpoints(t, prodChains, firstOnly, withSort),
{
isDisabled: false,
isHeader: true,
isSpaced: true,
text: t('rpc.header.test', 'Test networks', { ns: 'apps-config' }),
textBy: '',
ui: {},
value: ''
},
...expandEndpoints(t, testChains, firstOnly, withSort),
{
isDevelopment: true,
isDisabled: false,
isHeader: true,
isSpaced: true,
text: t('rpc.header.dev', 'Development', { ns: 'apps-config' }),
textBy: '',
ui: {},
value: ''
},
...createDev(t),
...createOwn(t)
].filter(({ isDisabled }) => !isDisabled);
}
@@ -0,0 +1,742 @@
// Copyright 2017-2025 @pezkuwi/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { EndpointOption } from './types.js';
import { ZKVERIFY_GENESIS } from '../api/constants.js';
import { chains3dpassSVG, chainsAnalogSVG, chainsBittensorPNG, chainsChainflipPNG, chainsCommuneaiPNG, chainsCreditcoinPNG, chainsDebioSVG, chainsFragnovaPNG, chainsJurPNG, chainsLiberlandPNG, chainsLogionPNG, chainsMyriadPNG, chainsPezkuwiCircleSVG, chainsSpannerPNG, chainsTanglePNG, chainsTorusPNG, chainsVaraPNG, chainsVtbPNG } from '../ui/logos/chains/index.js';
import { nodesAresOdysseySVG, nodesAutonomysPNG, nodesCentrifugePNG, nodesCereSVG, nodesChainxSVG, nodesCompetitorsClubPNG, nodesCrownSterlingPNG, nodesCrustSVG, nodesDatahighwayPNG, nodesDockPNG, nodesEdgewareWhitePNG, nodesEfinitySVG, nodesElysiumPNG, nodesHanyonycashPNG, nodesHumanodePNG, nodesInnovatorPNG, nodesJoystreamSVG, nodesKulupuSVG, nodesKusariSVG, nodesMathSVG, nodesMinixPNG, nodesNftmartPNG, nodesNodleSVG, nodesPolkadexSVG, nodesPolymeshSVG, nodesRiochainSVG, nodesRobonomicsSVG, nodesSherpaxPNG, nodesSoraBizinikiwiSVG, nodesStafiPNG, nodesSubgameSVG, nodesSubsocialSVG, nodesSwapdexSVG, nodesTanssiSVG, nodesTernoaSVG, nodesThebifrostPNG, nodesTscsPNG, nodesUniartsPNG, nodesUnitnetworkPNG, nodesVFlowPNG, nodesZkVerifyPNG } from '../ui/logos/nodes/index.js';
export * from './productionRelayDicle.js';
export * from './productionRelayPezkuwi.js';
export const zkVerifyParas: Omit<EndpointOption, 'teleport'>[] = [
{
info: 'VFlow',
paraId: 1,
providers: {
zkVerify: 'wss://vflow-rpc.zkverify.io'
},
relayName: 'zkVerify',
text: 'VFlow',
ui: {
color: '#5C72FF',
logo: nodesVFlowPNG
}
}
];
// The available endpoints that will show in the dropdown. For the most part (with the exception of
// Pezkuwi) we try to keep this to live chains only, with RPCs hosted by the community/chain vendor
// info: The chain logo name as defined in ../ui/logos/index.ts in namedLogos (this also needs to align with @pezkuwi/networks)
// text: The text to display on the dropdown
// providers: The actual hosted secure websocket endpoint
//
// IMPORTANT: Alphabetical based on text
export const prodChains: Omit<EndpointOption, 'teleport'>[] = [
{
info: '3dpass',
providers: {
'3dpass': 'wss://rpc.3dpass.org'
},
text: '3DPass',
ui: {
color: '#323232',
logo: chains3dpassSVG
}
},
{
homepage: 'https://analog.one',
info: 'analog-timechain',
providers: {
'Analog One': 'wss://rpc.timechain.analog.one'
},
text: 'Analog Timechain',
ui: {
color: '#5d3ef8',
identityIcon: 'beachball',
logo: chainsAnalogSVG
}
},
{
info: 'Ares Odyssey',
providers: {
// 'Ares Protocol': 'wss://odyssey.aresprotocol.io' // https://github.com/pezkuwi-js/apps/issues/10411
},
text: 'Ares Odyssey',
ui: {
color: '#1295F0',
logo: nodesAresOdysseySVG
}
},
{
info: 'autonomys-mainnet',
providers: {
Foundation: 'wss://rpc.mainnet.subspace.foundation/ws',
Labs: 'wss://rpc.mainnet.autonomys.xyz/ws'
},
text: 'Autonomys',
ui: {
color: '#5870B3',
logo: nodesAutonomysPNG
}
},
{
info: 'autonomys-mainnet-evm',
providers: {
Labs: 'wss://auto-evm.mainnet.autonomys.xyz/ws'
},
text: 'Autonomys EVM',
ui: {
color: '#5870B3',
logo: nodesAutonomysPNG
}
},
{
info: 'thebifrost-mainnet',
providers: {
'Pilab #1': 'wss://public-01.mainnet.bifrostnetwork.com/wss',
'Pilab #2': 'wss://public-02.mainnet.bifrostnetwork.com/wss'
},
text: 'Bifrost Mainnet',
ui: {
color: '#FF474C',
logo: nodesThebifrostPNG
}
},
{
info: 'bittensor',
providers: {
'Latent Holdings (Lite)': 'wss://lite.sub.latent.to:443',
'OnFinality (Archive)': 'wss://bittensor-finney.api.onfinality.io/public-ws',
'Opentensor Fdn (Archive)': 'wss://entrypoint-finney.opentensor.ai:443'
},
text: 'Bittensor',
ui: {
color: '#252525',
logo: chainsBittensorPNG
}
},
{
info: 'bulletin',
providers: {
Amforc: 'wss://bulletin.rpc.amforc.com',
Interweb: 'wss://rpc.interweb-it.com/bulletin',
TurboFlakes: 'wss://bulletin.rpc.turboflakes.io',
'Web3 Foundation': 'wss://bulletin-rpc.w3f.community'
},
text: 'Bulletin',
ui: {
color: '#6B2D84',
logo: chainsPezkuwiCircleSVG
}
},
{
info: 'creditcoin-classic',
providers: {
'Creditcoin Foundation': 'wss://mainnet.creditcoin.network/ws'
},
text: 'CC Enterprise',
ui: {
color: '#2D353F',
logo: chainsCreditcoinPNG
}
},
{
info: 'centrifuge',
providers: {
// Centrifuge: 'wss://fullnode.centrifuge.io' // https://github.com/pezkuwi-js/apps/issues/8012
},
text: 'Centrifuge Standalone [Archived]',
ui: {
color: '#fcc367',
logo: nodesCentrifugePNG
}
},
{
info: 'cere',
providers: {
'Cere Network': 'wss://archive.mainnet.cere.network/ws'
// 'Republic Crypto | Runtime': 'wss://mainnet.cere-archive.republiccrypto-runtime.com:444' // https://github.com/pezkuwi-js/apps/issues/9828
},
text: 'Cere Network',
ui: {
color: '#B7AEFF',
logo: nodesCereSVG
}
},
{
info: 'chainflip',
providers: {
chainflip: 'wss://mainnet-archive.chainflip.io'
},
text: 'Chainflip',
ui: {
color: '#111111',
logo: chainsChainflipPNG
}
},
{
info: 'chainx',
providers: {
ChainX: 'wss://mainnet.chainx.org/ws'
},
text: 'ChainX',
ui: {
color: '#F6C94A',
logo: nodesChainxSVG
}
},
{
info: 'communeai',
providers: {
// Bitconnect: 'wss://commune-api-node-1.communeai.net' // https://github.com/pezkuwi-js/apps/issues/11950
// OnFinality: 'wss://commune.api.onfinality.io/public-ws'
},
text: 'Commune AI',
ui: {
color: '#060606',
logo: chainsCommuneaiPNG
}
},
{
info: 'competitors-club',
providers: {
// 'Competitors Club': 'wss://node0.competitors.club/wss' // https://github.com/pezkuwi-js/apps/issues/8263
},
text: 'Competitors Club',
ui: {
color: '#213830',
logo: nodesCompetitorsClubPNG
}
},
{
info: 'creditcoin',
providers: {
'Creditcoin Foundation': 'wss://mainnet3.creditcoin.network'
},
text: 'Creditcoin',
ui: {
color: '#2D353F',
logo: chainsCreditcoinPNG
}
},
{
info: 'crown-sterling',
providers: {
// 'Crown Sterling': 'wss://blockchain.crownsterling.io' https://github.com/pezkuwi-js/apps/issues/10289
},
text: 'Crown Sterling',
ui: {
color: '#13264b',
logo: nodesCrownSterlingPNG
}
},
{
info: 'crust',
providers: {
'Crust Network': 'wss://rpc.crust.network',
'Crust Network APP': 'wss://rpc.crustnetwork.app',
'Crust Network CC': 'wss://rpc.crustnetwork.cc',
'Crust Network XYZ': 'wss://rpc.crustnetwork.xyz',
OnFinality: 'wss://crust.api.onfinality.io/public-ws'
},
text: 'Crust Network',
ui: {
color: '#ff8812',
logo: nodesCrustSVG
}
},
{
info: 'debio',
providers: {
// DeBio: 'wss://ws-rpc.debio.network', // https://github.com/pezkuwi-js/apps/issues/10118
// Octopus: 'wss://gateway.mainnet.octopus.network/debionetwork/ae48005a0c7ecb4053394559a7f4069e' // https://github.com/pezkuwi-js/apps/issues/11234
},
text: 'DeBio',
ui: {
color: '#FF56E0',
logo: chainsDebioSVG
}
},
{
info: 'dock-pos-mainnet',
providers: {
// 'Dock Association': 'wss://mainnet-node.dock.io' // https://github.com/pezkuwi-js/apps/issues/11460
},
text: 'Dock',
ui: {
logo: nodesDockPNG
}
},
{
info: 'edgeware',
providers: {
// 'Commonwealth Labs': 'wss://mainnet2.edgewa.re', // https://github.com/pezkuwi-js/apps/issues/10373
'JelliedOwl Bangalore': 'wss://edgeware-rpc3.jelliedowl.net'
// OnFinality: 'wss://edgeware.api.onfinality.io/public-ws' // https://github.com/pezkuwi-js/apps/issues/9795
},
text: 'Edgeware',
ui: {
color: '#111111',
logo: nodesEdgewareWhitePNG
}
},
{
info: 'efinity',
providers: {
// Efinity: 'wss://rpc.efinity.io' // https://github.com/pezkuwi-js/apps/pull/6761
},
text: 'Efinity',
ui: {
color: '#496ddb',
logo: nodesEfinitySVG
}
},
{
info: 'elysium',
providers: {
Elysium: 'wss://ws.elysiumchain.tech'
},
text: 'Elysium',
ui: {
color: '#140533',
logo: nodesElysiumPNG
}
},
{
info: 'fragnova',
providers: {
// 'Fragnova Network': 'wss://ws.fragnova.network' // https://github.com/pezkuwi-js/apps/issues/10172
},
text: 'Fragnova', // The text to display on the dropdown
ui: {
color: '#6b35a8',
logo: chainsFragnovaPNG
}
},
{
info: 'hanonycash',
providers: {
// Hanonycash: 'wss://rpc.hanonycash.com' // https://github.com/pezkuwi-js/apps/runs/2755409009?check_suite_focus=true
},
text: 'Hanonycash',
ui: {
color: '#0099CC',
logo: nodesHanyonycashPNG
}
},
{
info: 'humanode',
providers: {
Humanode: 'wss://explorer-rpc-ws.mainnet.stages.humanode.io'
},
text: 'Humanode',
ui: {
logo: nodesHumanodePNG
}
},
{
info: 'innovatorchain',
providers: {
// Innovator: 'wss://rpc.innovatorchain.com' // https://github.com/pezkuwi-js/apps/issues/10373
},
text: 'Innovator Chain',
ui: {
color: '#0067F4',
logo: nodesInnovatorPNG
}
},
{
info: 'joystream',
providers: {
Joyutils: 'wss://rpc.joyutils.org',
Jsgenesis: 'wss://rpc.joystream.org',
'l1.media': 'wss://rpc.l1.media'
},
text: 'Joystream',
ui: {
color: '#4038FF',
logo: nodesJoystreamSVG
}
},
{
info: 'jur',
providers: {
// 'Iceberg Nodes': 'wss://jur-mainnet-archive-rpc-1.icebergnodes.io' // https://github.com/pezkuwi-js/apps/issues/10289
// 'Simply Staking': 'wss://jur-archive-mainnet-1.simplystaking.xyz/VX68C07AR4K2/ws' // https://github.com/pezkuwi-js/apps/issues/10172
},
text: 'Jur',
ui: {
color: '#203050',
logo: chainsJurPNG
}
},
{
info: 'kulupu',
providers: {
// Kulupu: 'wss://rpc.kulupu.corepaper.org/ws' https://github.com/pezkuwi-js/apps/issues/11157
},
text: 'Kulupu',
ui: {
color: '#003366',
logo: nodesKulupuSVG
}
},
{
info: 'kusari',
providers: {
// Swapdex: 'wss://ws.kusari.network' // https://github.com/pezkuwi-js/apps/issues/9712
},
text: 'Kusari',
ui: {
color: '#b8860b',
logo: nodesKusariSVG
}
},
{
info: 'Liberland',
providers: {
Dwellir: 'wss://liberland-rpc.n.dwellir.com',
'Liberland Government': 'wss://mainnet.liberland.org'
},
text: 'Liberland mainnet',
ui: {
color: 'rgb(13, 52, 93)',
logo: chainsLiberlandPNG
}
},
{
info: 'logion',
providers: {
// 'Logion 1': 'wss://rpc01.logion.network' // https://github.com/pezkuwi-js/apps/issues/10667
},
text: 'Logion Solochain (Archive)',
ui: {
color: 'rgb(21, 38, 101)',
logo: chainsLogionPNG
}
},
{
info: 'mathchain',
providers: {
// MathWallet: 'wss://mathchain-asia.maiziqianbao.net/ws', // https://github.com/pezkuwi-js/apps/issues/8525
// 'MathWallet Backup': 'wss://mathchain-us.maiziqianbao.net/ws' // https://github.com/pezkuwi-js/apps/issues/8525
},
text: 'MathChain',
ui: {
color: '#000000',
logo: nodesMathSVG
}
},
{
info: 'minix',
providers: {
// ChainX: 'wss://minichain-mainnet.coming.chat/ws' // https://github.com/pezkuwi-js/apps/issues/7182
},
text: 'MiniX',
ui: {
color: '#5152f7',
logo: nodesMinixPNG
}
},
{
info: 'myriad',
providers: {
// Myriad: 'wss://ws-rpc.myriad.social', // https://github.com/pezkuwi-js/apps/issues/10172
// Octopus: 'wss://gateway.mainnet.octopus.network/myriad/a4cb0a6e30ff5233a3567eb4e8cb71e0' // https://github.com/pezkuwi-js/apps/issues/11263
},
text: 'Myriad',
ui: {
color: '#7342CC',
logo: chainsMyriadPNG
}
},
{
info: 'neatcoin',
providers: {
// Neatcoin: 'wss://rpc.neatcoin.org/ws' https://github.com/pezkuwi-js/apps/issues/11157
},
text: 'Neatcoin',
ui: {}
},
{
info: 'nftmart',
providers: {
NFTMart: 'wss://mainnet.nftmart.io/rpc/ws'
},
text: 'NFTMart',
ui: {
logo: nodesNftmartPNG
}
},
{
info: 'nodle',
providers: {
// Nodle: 'wss://main3.nodleprotocol.io', // https://github.com/pezkuwi-js/apps/issues/7652
// OnFinality: 'wss://nodle.api.onfinality.io/public-ws' // https://github.com/pezkuwi-js/apps/issues/8013
},
text: 'Nodle',
ui: {
color: '#1ab394',
logo: nodesNodleSVG
}
},
{
info: 'polkadex',
providers: {
// OnFinality: 'wss://polkadex.api.onfinality.io/public-ws', // https://github.com/pezkuwi-js/apps/issues/11827
PolkadexSup: 'wss://so.polkadex.ee',
RadiumBlock: 'wss://polkadex.public.curie.radiumblock.co/ws'
},
text: 'Polkadex',
ui: {
color: '#7C30DD',
logo: nodesPolkadexSVG
}
},
{
info: 'polymesh',
providers: {
Polymesh: 'wss://mainnet-rpc.polymesh.network'
},
text: 'Polymesh Mainnet',
ui: {
color: 'linear-gradient(197deg, #FF2E72, #4A125E)',
logo: nodesPolymeshSVG
}
},
{
info: 'riochain',
providers: {
// RioChain: 'wss://node.v1.riochain.io' // https://github.com/pezkuwi-js/apps/issues/9054
},
text: 'RioChain',
ui: {
color: 'rgb(77, 135, 246)',
logo: nodesRiochainSVG
}
},
{
info: 'robonomics',
providers: {
// Airalab: 'wss://dicle.rpc.robonomics.network/' // https://github.com/pezkuwi-js/apps/pull/6761
},
text: 'Robonomics',
ui: {
color: '#2949d3',
logo: nodesRobonomicsSVG
}
},
{
info: 'sherpax',
providers: {
// ChainX: 'wss://mainnet.sherpax.io' // https://github.com/pezkuwi-js/apps/issues/9712
},
text: 'SherpaX',
ui: {
color: '#6bbee8',
logo: nodesSherpaxPNG
}
},
{
info: 'sora-bizinikiwi',
providers: {
OnFinality: 'wss://sora.api.onfinality.io/public-ws',
'SORA Parliament Ministry of Finance': 'wss://ws.mof.sora.org',
'SORA Parliament Ministry of Finance #2': 'wss://mof2.sora.org'
// 'SORA Parliament Ministry of Finance #3': 'wss://mof3.sora.org' // https://github.com/pezkuwi-js/apps/issues/12007
},
text: 'SORA',
ui: {
color: '#2D2926',
logo: nodesSoraBizinikiwiSVG
}
},
{
info: 'spanner',
providers: {
// Spanner: 'wss://wss.spannerprotocol.com' // https://github.com/pezkuwi-js/apps/issues/6547
},
text: 'Spanner',
ui: {
color: '#EC3D3D',
logo: chainsSpannerPNG
}
},
{
info: 'stafi',
providers: {
// 'Stafi Foundation': 'wss://mainnet-rpc.stafi.io' // Cannot find type ChainId
},
text: 'Stafi',
ui: {
color: '#00F3AB',
logo: nodesStafiPNG
}
},
{
info: 'subgame',
providers: {
// SubGame: 'wss://mainnet.subgame.org/' // https://github.com/pezkuwi-js/apps/issues/9030
},
text: 'SubGame',
ui: {
color: '#EB027D',
logo: nodesSubgameSVG
}
},
{
info: 'subsocial',
providers: {
// DappForce: 'wss://rpc.subsocial.network' // https://github.com/pezkuwi-js/apps/issues/8046
},
text: 'Subsocial',
ui: {
color: '#b9018c',
logo: nodesSubsocialSVG
}
},
{
info: 'swapdex',
providers: {
// Swapdex: 'wss://ws.swapdex.network' // https://github.com/pezkuwi-js/apps/issues/10030
},
text: 'Swapdex',
ui: {
color: '#E94082',
logo: nodesSwapdexSVG
}
},
{
info: 'tangle',
providers: {
Dwellir: 'wss://tangle-mainnet-rpc.n.dwellir.com',
Webb: 'wss://rpc.tangle.tools'
},
text: 'Tangle',
ui: {
color: '#7578fb',
logo: chainsTanglePNG
}
},
{
info: 'tanssi',
isPeople: true,
providers: {
'Tanssi Foundation': 'wss://services.tanssi-mainnet.network/tanssi'
},
text: 'Tanssi',
ui: {
color: '#149b9bff',
logo: nodesTanssiSVG
}
},
{
info: 'ternoa',
providers: {
CapsuleCorp: 'wss://mainnet.ternoa.network' // https://github.com/pezkuwi-js/apps/issues/10172
},
text: 'Ternoa',
ui: {
color: '#d622ff',
logo: nodesTernoaSVG
}
},
{
info: 'torus',
providers: {
mainnet: 'wss://api.torus.network'
},
text: 'Torus',
ui: {
color: '#070A0E',
logo: chainsTorusPNG
}
},
{
info: 'tscs-mainnet',
providers: {
SuperEX: 'wss://testnetrpc.scschain.com'
},
text: 'TSCS Network',
ui: {
color: '#FFAB75',
logo: nodesTscsPNG
}
},
{
info: 'uniarts',
providers: {
// UniArts: 'wss://mainnet.uniarts.vip:9443' // https://github.com/pezkuwi-js/apps/issues/9059
},
text: 'UniArts',
ui: {
color: 'linear-gradient(150deg, #333ef7 0%, #55adff 100%)',
logo: nodesUniartsPNG
}
},
{
info: 'unitnetwork',
providers: {
// UnitNetwork: 'wss://www.unitnode3.info:443' // Duplicated in PezkuwiChain
},
text: 'UnitNetwork',
ui: {
color: '#a351ef',
logo: nodesUnitnetworkPNG
}
},
{
info: 'vara',
isPeopleForIdentity: false,
providers: {
// Blast: 'wss://vara-mainnet.public.blastapi.io', // https://github.com/pezkuwi-js/apps/issues/11577
Gear: 'wss://rpc.vara.network'
// 'P2P.org': 'wss://vara.bizinikiwi-rpc.p2p.org/' // https://github.com/pezkuwi-js/apps/issues/11337
},
text: 'Vara',
ui: {
color: '#00a87a',
logo: chainsVaraPNG
}
},
{
info: 'vtb',
providers: {
'VTB Community': 'wss://bizinikiwinode.vtbcfoundation.org/explorer'
},
text: 'VTB',
ui: {
color: '#1d79bb',
logo: chainsVtbPNG
}
},
{
info: 'westlake',
providers: {
// DataHighway: 'wss://westlake.datahighway.com' // https://github.com/pezkuwi-js/apps/issues/7293
},
text: 'Westlake',
ui: {
color: 'linear-gradient(-90deg, #9400D3 0%, #5A5CA9 50%, #00BFFF 100%)',
logo: nodesDatahighwayPNG
}
},
{
genesisHash: ZKVERIFY_GENESIS,
info: 'zkVerify',
isRelay: true,
linked: [
...zkVerifyParas
],
providers: {
zkverify: 'wss://zkverify-rpc.zkverify.io'
},
text: 'zkVerify',
ui: {
color: '#B5FFA5',
logo: nodesZkVerifyPNG
}
}
];
@@ -0,0 +1,107 @@
// Copyright 2017-2025 @pezkuwi/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { EndpointOption } from './types.js';
import { DICLE_GENESIS } from '../api/constants.js';
import { getTeleports } from './util.js';
// Dicle Network Endpoints (Canary Network)
// Dicle is the canary network for Pezkuwi
export const prodParasDicle: Omit<EndpointOption, 'teleport'>[] = [
{
homepage: 'https://pezkuwichain.io',
info: 'asset-hub-dicle',
isPeopleForIdentity: true,
paraId: 1000,
providers: {
'Pezkuwi Foundation': 'wss://dicle-asset-hub-rpc.pezkuwichain.io'
},
relayName: 'dicle',
text: 'Asset Hub',
ui: {
color: '#f47738',
logo: 'chainsDicleSVG'
}
},
{
homepage: 'https://pezkuwichain.io',
info: 'bridge-hub-dicle',
paraId: 1002,
providers: {
'Pezkuwi Foundation': 'wss://dicle-bridge-hub-rpc.pezkuwichain.io'
},
relayName: 'dicle',
text: 'Bridge Hub',
ui: {
color: '#f47738',
logo: 'chainsDicleSVG'
}
},
{
homepage: 'https://pezkuwichain.io',
info: 'collectives-dicle',
paraId: 1001,
providers: {
'Pezkuwi Foundation': 'wss://dicle-collectives-rpc.pezkuwichain.io'
},
relayName: 'dicle',
text: 'Collectives',
ui: {
color: '#f47738',
logo: 'chainsDicleSVG'
}
},
{
homepage: 'https://pezkuwichain.io',
info: 'coretime-dicle',
paraId: 1005,
providers: {
'Pezkuwi Foundation': 'wss://dicle-coretime-rpc.pezkuwichain.io'
},
relayName: 'dicle',
text: 'Coretime',
ui: {
color: '#f47738',
logo: 'chainsDicleSVG'
}
},
{
homepage: 'https://pezkuwichain.io',
info: 'people-dicle',
isPeople: true,
paraId: 1004,
providers: {
'Pezkuwi Foundation': 'wss://dicle-people-rpc.pezkuwichain.io'
},
relayName: 'dicle',
text: 'People',
ui: {
color: '#f47738',
logo: 'chainsDicleSVG'
}
}
];
export const prodRelayDicle: EndpointOption = {
dnslink: 'dicle',
genesisHash: DICLE_GENESIS,
info: 'dicle',
isRelay: true,
isPeopleForIdentity: true,
linked: [
...getTeleports(prodParasDicle)
],
providers: {
'Pezkuwi Foundation': 'wss://dicle-rpc.pezkuwichain.io',
'Local': 'ws://127.0.0.1:9944'
},
teleport: [1000],
text: 'Dicle',
ui: {
color: '#f47738',
identityIcon: 'jdenticon',
logo: 'chainsDicleSVG'
}
};
@@ -0,0 +1,108 @@
// Copyright 2017-2025 @pezkuwi/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { EndpointOption } from './types.js';
import { PEZKUWI_GENESIS } from '../api/constants.js';
import { getTeleports } from './util.js';
// Pezkuwi Network Endpoints
// These are the official PezkuwiChain network endpoints
export const prodParasPezkuwi: Omit<EndpointOption, 'teleport'>[] = [
{
homepage: 'https://pezkuwichain.io',
info: 'asset-hub-pezkuwi',
isPeopleForIdentity: true,
paraId: 1000,
providers: {
'Pezkuwi Foundation': 'wss://zagros-asset-hub-rpc.pezkuwichain.io'
},
relayName: 'pezkuwi',
text: 'Asset Hub',
ui: {
color: '#86e62a',
logo: 'chainsPezkuwiSVG'
}
},
{
homepage: 'https://pezkuwichain.io',
info: 'bridge-hub-pezkuwi',
paraId: 1002,
providers: {
'Pezkuwi Foundation': 'wss://zagros-bridge-hub-rpc.pezkuwichain.io'
},
relayName: 'pezkuwi',
text: 'Bridge Hub',
ui: {
color: '#86e62a',
logo: 'chainsPezkuwiSVG'
}
},
{
homepage: 'https://pezkuwichain.io',
info: 'collectives-pezkuwi',
paraId: 1001,
providers: {
'Pezkuwi Foundation': 'wss://zagros-collectives-rpc.pezkuwichain.io'
},
relayName: 'pezkuwi',
text: 'Collectives',
ui: {
color: '#86e62a',
logo: 'chainsPezkuwiSVG'
}
},
{
homepage: 'https://pezkuwichain.io',
info: 'coretime-pezkuwi',
paraId: 1005,
providers: {
'Pezkuwi Foundation': 'wss://zagros-coretime-rpc.pezkuwichain.io'
},
relayName: 'pezkuwi',
text: 'Coretime',
ui: {
color: '#86e62a',
logo: 'chainsPezkuwiSVG'
}
},
{
homepage: 'https://pezkuwichain.io',
info: 'people-pezkuwi',
isPeople: true,
paraId: 1004,
providers: {
'Pezkuwi Foundation': 'wss://zagros-people-rpc.pezkuwichain.io'
},
relayName: 'pezkuwi',
text: 'People',
ui: {
color: '#86e62a',
logo: 'chainsPezkuwiSVG'
}
}
];
export const prodRelayPezkuwi: EndpointOption = {
dnslink: 'pezkuwi',
genesisHash: PEZKUWI_GENESIS,
info: 'pezkuwi',
isRelay: true,
isPeopleForIdentity: true,
linked: [
...getTeleports(prodParasPezkuwi)
],
providers: {
'Pezkuwi Foundation': 'wss://rpc.pezkuwichain.io',
'Pezkuwi Zagros': 'wss://zagros-rpc.pezkuwichain.io',
'Local': 'ws://127.0.0.1:9944'
},
teleport: [1000],
text: 'Pezkuwi',
ui: {
color: '#e6007a',
identityIcon: 'jdenticon',
logo: 'chainsPezkuwiSVG'
}
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,615 @@
// Copyright 2017-2025 @pezkuwi/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { EndpointOption } from './types.js';
import { chainsAmplitudeSVG, chainsCoretimeDicleSVG, chainsFrequencyPaseoSVG, chainsHydrationPaseoSVG, chainsKreivoSVG, chainsLaosSigmaPNG, chainsMyxcavPNG, chainsNeurowebTestnetPNG, chainsPaseoPNG, chainsPeoplePezkuwiSVG, chainsPopNetworkSVG, chainsQfNetworkPNG, chainsShibuyaSVG, chainsWatrPNG, chainsWeTEESVG } from '@pezkuwi/apps-config/ui/logos/chains';
import { nodesAjunaPNG, nodesAssetHubSVG, nodesAventusSVG, nodesBajunPNG, nodesBifrostSVG, nodesBridgeHubSVG, nodesCollectivesSVG, nodesDarwiniaKoiSVG, nodesFintraSVG, nodesHeimaPaseoPNG, nodesHyperbridgePNG, nodesIdealNetworkSVG, nodesIdncSVG, nodesIntegriteeSVG, nodesKiltIconSVG, nodesMandalaPNG, nodesMusePNG, nodesMyriadPaseoSVG, nodesNodleSVG, nodesOpalLogoPNG, nodesRegionxPNG, nodesRexSVG, nodesXodePNG, nodesZeitgeistPNG } from '@pezkuwi/apps-config/ui/logos/nodes';
import { PASEO_GENESIS } from '../api/constants.js';
// import { testnetTeyrchainSVG } from '../ui/logos/nodes/index.js';
import { getTeleports } from './util.js';
// The available endpoints that will show in the dropdown. For the most part (with the exception of
// Pezkuwi) we try to keep this to live chains only, with RPCs hosted by the community/chain vendor
// info: The chain logo name as defined in ../ui/logos/index.ts in namedLogos (this also needs to align with @pezkuwi/networks)
// text: The text to display on the dropdown
// providers: The actual hosted secure websocket endpoint
//
// IMPORTANT: Alphabetical based on text
export const testParasPaseo: Omit<EndpointOption, 'teleport'>[] = [
// {
// homepage: 'https://testPaseoTeyrchainExample.com',
// info: 'paseoteyrchain',
// paraId: 2345,
// providers: {
// Acurast: 'wss://paseo-teyrchain-testnet-ws.prod.gke.papers.tech'
// },
// text: 'Testnet Teyrchain',
// ui: {
// color: '#000000',
// logo: testnetTeyrchainSVG
// }
// }
{
homepage: 'https://ajuna.io/',
info: 'Ajuna(paseo)',
paraId: 2051,
providers: {
BajunNetwork: 'wss://rpc-paseo.ajuna.network'
},
text: 'Ajuna Network (Paseo)',
ui: {
color: '#161212',
logo: nodesAjunaPNG
}
},
{
info: 'paseoAmplitude',
paraId: 2124,
providers: {
// PendulumChain: 'wss://rpc-foucoco.pendulumchain.tech' // https://github.com/pezkuwi-js/apps/issues/11267
},
text: 'Amplitude testnet (Foucoco)',
ui: {
color: '#5DEFA7',
logo: chainsAmplitudeSVG
}
},
{
homepage: 'https://www.aventus.io/',
info: 'paseoAventus',
paraId: 2056,
providers: {
// Aventus: 'wss://public-rpc.testnet.aventus.io' // https://github.com/pezkuwi-js/apps/issues/11827
},
text: 'Aventus',
ui: {
color: '#E6E6FA',
logo: nodesAventusSVG
}
},
{
homepage: 'https://ajuna.io/',
info: 'Bajun(paseo)',
paraId: 2119,
providers: {
// BajunNetwork: 'wss://rpc-paseo.bajun.network' https://github.com/pezkuwi-js/apps/issues/11026
},
text: 'Bajun Network (Paseo)',
ui: {
color: '#161212',
logo: nodesBajunPNG
}
},
{
homepage: 'https://bifrost.io',
info: 'Bifrost(Paseo)',
paraId: 2030,
providers: {
Liebi: 'wss://bifrost-rpc.paseo.liebi.com/ws',
Liebi2: 'wss://bifrost-rpc.paseo2.liebi.com/ws'
},
text: 'Bifrost',
ui: {
color: '#5a25f0',
logo: nodesBifrostSVG
}
},
{
homepage: 'https://darwinia.network/',
info: 'Darwinia Koi',
paraId: 2105,
providers: {
// Darwinia: 'wss://koi-rpc.darwinia.network' // https://github.com/pezkuwi-js/apps/issues/11279
},
text: 'Darwinia Koi',
ui: {
color: '#FF0083',
logo: nodesDarwiniaKoiSVG
}
},
{
homepage: 'https://fintradex.io/',
info: 'Fintra',
isPeopleForIdentity: true,
paraId: 4910,
providers: {
FINTRA: 'wss://testnet.fintra.network'
},
relayName: 'paseo',
text: 'Fintra',
ui: {
color: '#2596be',
logo: nodesFintraSVG
}
},
{
homepage: 'https://www.frequency.xyz',
info: 'Frequency',
paraId: 4000,
providers: {
'Amplica Labs': 'wss://0.rpc.testnet.amplica.io'
},
text: 'Frequency',
ui: {
color: '#bc86b7',
logo: chainsFrequencyPaseoSVG
}
},
{
homepage: 'https://heima.network/',
info: 'heima-paseo',
paraId: 2106,
providers: {
Heima: 'wss://rpc.paseo-teyrchain.heima.network'
},
text: 'Heima paseo',
ui: {
color: '#ECDA38',
logo: nodesHeimaPaseoPNG
}
},
{
homepage: 'https://hydration.net',
info: 'pezkuwichainHydraDX',
paraId: 2034,
providers: {
'Galactic Council': 'wss://paseo-rpc.play.hydration.cloud'
},
text: 'Hydration (Paseo)',
ui: {
color: '#b3d7fa',
logo: chainsHydrationPaseoSVG
}
},
{
homepage: 'https://hyperbridge.network',
info: 'Hyperbridge',
paraId: 4009,
providers: {
BlockOps: 'wss://hyperbridge-paseo-rpc.blockops.network'
},
text: 'Hyperbridge (Gargantua)',
ui: {
color: '#ED6FF1',
logo: nodesHyperbridgePNG
}
},
{
homepage: 'https://idealabs.network/',
info: 'Ideal Network',
paraId: 4502,
providers: {
'IDN Node': 'wss://idn0-testnet.idealabs.network'
},
text: 'Ideal Network',
ui: {
color: 'rgb(17, 35, 77)',
logo: nodesIdealNetworkSVG
}
},
{
homepage: 'https://idealabs.network/',
info: 'IDN Consumer',
paraId: 4594,
providers: {
'IDN Node': 'wss://idnc0-testnet.idealabs.network'
},
text: 'IDN Consumer',
ui: {
color: 'rgb(241,208,84)',
logo: nodesIdncSVG
}
},
{
homepage: 'https://integritee.network',
info: 'integritee',
paraId: 2039,
providers: {
// Integritee: 'wss://paseo.api.integritee.network' // https://github.com/pezkuwi-js/apps/issues/11992
},
text: 'Integritee Network (Paseo)',
ui: {
color: '#658ea9',
logo: nodesIntegriteeSVG
}
},
{
info: 'kilt',
paraId: 2086,
providers: {
'KILT Foundation': 'wss://peregrine.kilt.io/'
},
text: 'KILT Peregrine',
ui: {
color: 'linear-gradient(45deg, #D73D80 0%, #161B3B 100%)',
logo: nodesKiltIconSVG
}
},
{
homepage: 'https://virto.network/',
info: 'kreivo',
isPeopleForIdentity: true,
paraId: 2281,
providers: {
Kippu: 'wss://testnet.kreivo.kippu.rocks/'
},
relayName: 'paseo',
text: 'Kreivo de Paseo - By Virto',
ui: {
color: '#294940',
identityIcon: 'pezkuwi',
logo: chainsKreivoSVG
}
},
{
homepage: 'https://laosnetwork.io/',
info: 'laos-sigma',
paraId: 4006,
providers: {
'freeverse.io': 'wss://rpc.laossigma.laosfoundation.io'
},
text: 'Laos Sigma',
ui: {
color: '#363435',
logo: chainsLaosSigmaPNG
}
},
{
homepage: 'https://mandalachain.io',
info: 'Mandala',
paraId: 4818,
providers: {
Autobot: 'wss://rpc1.paseo.mandalachain.io',
Bumblebee: 'wss://rpc2.paseo.mandalachain.io'
},
text: 'Mandala',
ui: {
color: '#0036ac',
logo: nodesMandalaPNG
}
},
{
info: 'muse',
paraId: 3369,
providers: {
Parity: 'wss://paseo-muse-rpc.pezkuwi.io'
},
text: 'Muse network',
ui: {
color: '#110ff9',
logo: nodesMusePNG
}
},
{
homepage: 'https://myriad.social',
info: 'Myriad Social',
paraId: 4005,
providers: {
// myriadPaseo: 'wss://ws-rpc.paseo.myriad.social' // https://github.com/pezkuwi-js/apps/issues/11589
},
text: 'Myriad Social Testnet',
ui: {
color: '#d5e3e4',
logo: nodesMyriadPaseoSVG
}
},
{
homepage: 'https://neuroweb.ai',
info: 'NeuroWeb',
paraId: 2043,
providers: {
TraceLabs: 'wss://teyrchain-testnet-rpc.origin-trail.network/'
},
text: 'NeuroWeb Testnet',
ui: {
color: '#646566',
logo: chainsNeurowebTestnetPNG
}
},
{
homepage: 'https://www.nodle.com/',
info: 'NodleParadis',
paraId: 2026,
providers: {
OnFinality: 'wss://node-7273232234617282560.nv.onfinality.io/ws?apikey=b937a7d7-7395-49b9-b745-60a0342fa365'
},
text: 'Nodle',
ui: {
color: '#1ab394',
logo: nodesNodleSVG
}
},
{
info: 'opal',
paraId: 2037,
providers: {
'Geo Load Balancer': 'wss://ws-opal.unique.network'
},
text: 'OPAL by UNIQUE',
ui: {
color: '#3B9C9D',
logo: nodesOpalLogoPNG
}
},
{
info: 'paseoEwx',
paraId: 3345,
providers: {
'Energy Web': 'wss://public-rpc.testnet.energywebx.com/'
},
text: 'PEX',
ui: {
color: '#452E66',
logo: nodesRexSVG
}
},
{
homepage: 'https://popnetwork.xyz/',
info: 'Pop Network',
paraId: 4001,
providers: {
'R0GUE-RPC1': 'wss://rpc1.paseo.popnetwork.xyz'
// 'R0GUE-RPC2': 'wss://rpc2.paseo.popnetwork.xyz', // https://github.com/pezkuwi-js/apps/issues/11629
},
text: 'Pop Network',
ui: {
color: 'linear-gradient(to right, rgb(230, 0, 122), rgb(83, 15, 160))',
logo: chainsPopNetworkSVG
}
},
{
homepage: 'https://qfnetwork.xyz/',
info: 'qf-paseo',
paraId: 4775,
providers: {
// 'QF Network': 'wss://para-test.qfnetwork.xyz' // https://github.com/pezkuwi-js/apps/issues/11745
},
text: 'QF Network (Paseo)',
ui: {
color: '#2E2E5C',
logo: chainsQfNetworkPNG
}
},
{
info: 'regionxCocos',
paraId: 4509,
providers: {
// RegionX: 'wss://regionx-paseo.regionx.tech' // https://github.com/pezkuwi-js/apps/issues/11098
},
text: 'RegionX(Paseo)',
ui: {
color: '#0CC184',
logo: nodesRegionxPNG
}
},
{
homepage: 'https://astar.network',
info: 'PaseoShibuyaChain',
paraId: 2000,
providers: {
// Astar: 'wss://rpc.shibuya.astar.network' // https://github.com/pezkuwi-js/apps/issues/11950
},
relayName: 'paseo',
text: 'Shibuya Testnet (Astar)',
ui: {
color: '#e84366',
logo: chainsShibuyaSVG
}
},
{
info: 'paseoWatr',
paraId: 2058,
providers: {
// Watr: 'wss://rpc.dev.watr.org' // https://github.com/pezkuwi-js/apps/issues/11648
},
text: 'Watr Network',
ui: {
color: '#373b39',
logo: chainsWatrPNG
}
},
{
homepage: 'https://wetee.app/',
info: 'TEE cloud',
paraId: 4545,
providers: {
// WeTEEDAO: 'wss://paseo.asyou.me/ws' // https://github.com/pezkuwi-js/apps/issues/11610
},
text: 'WeTEE (Paseo)',
ui: {
color: '#000',
logo: chainsWeTEESVG
}
},
{
homepage: 'https://xcavate.io/',
info: 'Xcavate',
paraId: 4683,
providers: {
// Xcavate: 'wss://rpc2-paseo.xcavate.io' // https://github.com/pezkuwi-js/apps/issues/12007
},
text: 'Xcavate',
ui: {
color: '#FF0083',
logo: chainsMyxcavPNG
}
},
{
homepage: 'https://xode.net',
info: 'paseoXode',
paraId: 4607,
providers: {
// XodeCommunity: 'wss://paseo-rpcnode.xode.net' // https://github.com/pezkuwi-js/apps/issues/12007
},
text: 'Xode',
ui: {
color: '#ed1f7a',
logo: nodesXodePNG
}
},
{
homepage: 'zeitgeist.pm',
info: 'ZeitgeistBatteryStation',
paraId: 2101,
providers: {
// Zeitgeist: 'wss://bsr.zeitgeist.pm' // https://github.com/pezkuwi-js/apps/issues/11992
},
text: 'Zeitgeist Battery Station',
ui: {
color: 'linear-gradient(180deg, rgba(32,90,172,1) 0%, rgba(26,72,138,1) 50%, rgba(13,36,69,1) 100%)',
logo: nodesZeitgeistPNG
}
}
];
export const testParasPaseoCommon: EndpointOption[] = [
{
info: 'PaseoAssetHub',
isPeopleForIdentity: true,
paraId: 1000,
providers: {
Dwellir: 'wss://asset-hub-paseo-rpc.n.dwellir.com',
IBP1: 'wss://sys.ibp.network/asset-hub-paseo',
IBP2: 'wss://asset-hub-paseo.dotters.network',
StakeWorld: 'wss://pas-rpc.stakeworld.io/assethub',
TurboFlakes: 'wss://sys.turboflakes.io/asset-hub-paseo'
},
relayName: 'paseo',
teleport: [-1, 1002, 1111],
text: 'Asset Hub',
ui: {
color: '#77bb77',
logo: nodesAssetHubSVG
}
},
{
info: 'PaseoBridgeHub',
isPeopleForIdentity: true,
paraId: 1002,
providers: {
IBP1: 'wss://sys.ibp.network/bridgehub-paseo',
IBP2: 'wss://bridge-hub-paseo.dotters.network'
},
relayName: 'paseo',
teleport: [-1, 1000],
text: 'Bridge Hub',
ui: {
color: '#AAADD7',
logo: nodesBridgeHubSVG
}
},
{
info: 'PaseoCollectives',
isPeopleForIdentity: true,
paraId: 1001,
providers: {
IBP1: 'wss://collectives-paseo.rpc.amforc.com',
IBP2: 'wss://collectives-paseo.dotters.network'
},
relayName: 'paseo',
teleport: [-1, 1000],
text: 'Collectives',
ui: {
color: '#e6777a',
logo: nodesCollectivesSVG
}
},
{
info: 'PaseoCoretime',
isPeopleForIdentity: true,
paraId: 1005,
providers: {
IBP1: 'wss://sys.ibp.network/coretime-paseo',
IBP2: 'wss://coretime-paseo.dotters.network'
// ParaNodes: 'wss://paseo-coretime.paranodes.io', // https://github.com/pezkuwi-js/apps/issues/11587
},
relayName: 'paseo',
teleport: [-1],
text: 'Coretime',
ui: {
color: '#113911',
logo: chainsCoretimeDicleSVG
}
},
{
info: 'PAssetHub - Contracts',
isPeopleForIdentity: true,
paraId: 1111,
providers: {
IBP1: 'wss://passet-hub-paseo.ibp.network',
IBP2: 'wss://passet-hub-paseo.dotters.network',
Parity: 'wss://testnet-passet-hub.pezkuwi.io'
},
relayName: 'paseo',
teleport: [-1, 1000],
text: 'PAssetHub - Contracts',
ui: {
color: '#77bb77',
logo: nodesAssetHubSVG
}
},
{
info: 'PaseoPeopleChain',
isPeople: true,
isPeopleForIdentity: false,
paraId: 1004,
providers: {
Amforc: 'wss://people-paseo.rpc.amforc.com',
IBP1: 'wss://sys.ibp.network/people-paseo',
IBP2: 'wss://people-paseo.dotters.network'
},
relayName: 'paseo',
teleport: [-1],
text: 'People',
ui: {
color: '#e84366',
logo: chainsPeoplePezkuwiSVG
}
},
{
info: 'PaseoPeopleLite',
isPeople: true,
isPeopleForIdentity: false,
paraId: 1044,
providers: {
Parity: 'wss://paseo-people-next-rpc.pezkuwi.io'
},
relayName: 'paseo',
teleport: [-1],
text: 'People Lite',
ui: {
color: '#e84366',
logo: chainsPeoplePezkuwiSVG
}
}
];
export const testRelayPaseo: EndpointOption = {
dnslink: 'paseo',
genesisHash: PASEO_GENESIS,
info: 'paseo',
isPeopleForIdentity: true,
isRelay: true,
linked: [
...testParasPaseoCommon,
...testParasPaseo
],
providers: {
Amforc: 'wss://paseo.rpc.amforc.com',
Dwellir: 'wss://paseo-rpc.n.dwellir.com',
IBP1: 'wss://rpc.ibp.network/paseo',
IBP2: 'wss://paseo.dotters.network',
StakeWorld: 'wss://pas-rpc.stakeworld.io'
// Zondax: 'wss://api2.zondax.ch/pas/node/rpc' // https://github.com/pezkuwi-js/apps/issues/11199
// 'light client': 'light://bizinikiwi-connect/paseo'
},
teleport: getTeleports(testParasPaseoCommon),
text: 'Paseo Relay',
ui: {
color: '#38393F',
identityIcon: 'pezkuwi',
logo: chainsPaseoPNG
}
};
@@ -0,0 +1,107 @@
// Copyright 2017-2025 @pezkuwi/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { EndpointOption } from './types.js';
import { ZAGROS_GENESIS } from '../api/constants.js';
import { getTeleports } from './util.js';
// Zagros Test Network Endpoints
// Zagros is the test network for Pezkuwi
export const testParasZagros: Omit<EndpointOption, 'teleport'>[] = [
{
homepage: 'https://pezkuwichain.io',
info: 'asset-hub-zagros',
isPeopleForIdentity: true,
paraId: 1000,
providers: {
'Pezkuwi Foundation': 'wss://zagros-asset-hub-rpc.pezkuwichain.io'
},
relayName: 'zagros',
text: 'Asset Hub',
ui: {
color: '#00b894',
logo: 'chainsZagrosSVG'
}
},
{
homepage: 'https://pezkuwichain.io',
info: 'bridge-hub-zagros',
paraId: 1002,
providers: {
'Pezkuwi Foundation': 'wss://zagros-bridge-hub-rpc.pezkuwichain.io'
},
relayName: 'zagros',
text: 'Bridge Hub',
ui: {
color: '#00b894',
logo: 'chainsZagrosSVG'
}
},
{
homepage: 'https://pezkuwichain.io',
info: 'collectives-zagros',
paraId: 1001,
providers: {
'Pezkuwi Foundation': 'wss://zagros-collectives-rpc.pezkuwichain.io'
},
relayName: 'zagros',
text: 'Collectives',
ui: {
color: '#00b894',
logo: 'chainsZagrosSVG'
}
},
{
homepage: 'https://pezkuwichain.io',
info: 'coretime-zagros',
paraId: 1005,
providers: {
'Pezkuwi Foundation': 'wss://zagros-coretime-rpc.pezkuwichain.io'
},
relayName: 'zagros',
text: 'Coretime',
ui: {
color: '#00b894',
logo: 'chainsZagrosSVG'
}
},
{
homepage: 'https://pezkuwichain.io',
info: 'people-zagros',
isPeople: true,
paraId: 1004,
providers: {
'Pezkuwi Foundation': 'wss://zagros-people-rpc.pezkuwichain.io'
},
relayName: 'zagros',
text: 'People',
ui: {
color: '#00b894',
logo: 'chainsZagrosSVG'
}
}
];
export const testRelayZagros: EndpointOption = {
dnslink: 'zagros',
genesisHash: ZAGROS_GENESIS,
info: 'zagros',
isRelay: true,
isPeopleForIdentity: true,
linked: [
...getTeleports(testParasZagros)
],
providers: {
'Pezkuwi Foundation': 'wss://zagros-rpc.pezkuwichain.io',
'Local': 'ws://127.0.0.1:9944'
},
teleport: [1000],
text: 'Zagros',
ui: {
color: '#00b894',
identityIcon: 'jdenticon',
logo: 'chainsZagrosSVG'
}
};
+100
View File
@@ -0,0 +1,100 @@
// Copyright 2017-2025 @pezkuwi/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type React from 'react';
import type { IconTheme } from '@pezkuwi/react-identicon/types';
import type { HexString } from '@pezkuwi/util/types';
import type { Option } from '../settings/types.js';
interface BaseOption {
dnslink?: string;
/**
* Genesis hash for chain
*/
genesisHash?: HexString;
/**
* Homepage Url
*/
homepage?: string;
/**
* Teyrchain Id of chain
*/
paraId?: number;
/**
* Summary about chain
*/
summary?: string;
teleport?: number[];
ui: {
/**
* Color for chain
*/
color?: string;
/**
* Identicon type i.e. pezkuwi, beachball, ethereum etc
*/
identityIcon?: IconTheme;
/**
* Logo component for chain
*/
logo?: string;
}
}
export interface EndpointOption extends BaseOption {
isChild?: boolean;
isDevelopment?: boolean;
isDisabled?: boolean;
/**
* Declares whether the given endpoint is the People chain used to store identity information.
*/
isPeople?: boolean;
/**
* Checks whether one of the given provider is reachable or not. If set to true, it hides the chain from explorer.
*/
isUnreachable?: boolean;
/**
* Declares list of all linked chains. However, It is applicable for relay chains only.
*/
linked?: EndpointOption[];
info?: string;
/**
* Declares the list of all RPC providers
*/
providers: Record<string, `${'wss://' | 'light://bizinikiwi-connect/'}${string}`>;
/**
* Declares chain name
*/
text: string;
/**
* Declares whether or not the endpoint is a relay chain.
*/
isRelay?: boolean;
/**
* Declares whether the given endpoint uses the People chain to store identity information.
*/
isPeopleForIdentity?: boolean;
/**
* Declares the relays name.
*/
relayName?: string;
}
export interface LinkOption extends BaseOption, Option {
genesisHashRelay?: HexString;
isChild?: boolean;
isDevelopment?: boolean;
isLightClient?: boolean;
isPeople?: boolean;
isRelay?: boolean;
isUnreachable?: boolean;
isSpaced?: boolean;
linked?: LinkOption[];
providers?: `${'wss://' | 'light://bizinikiwi-connect/'}${string}`[];
relayName?: string;
textBy: string;
textRelay?: React.ReactNode;
isPeopleForIdentity?: boolean;
value: string;
valueRelay?: string[];
}
+130
View File
@@ -0,0 +1,130 @@
// Copyright 2017-2025 @pezkuwi/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { TFunction } from '../types.js';
import type { EndpointOption, LinkOption } from './types.js';
interface SortOption {
isUnreachable?: boolean;
}
let dummyId = 0;
function sortNoop (): number {
return 0;
}
function sortLinks (a: SortOption, b: SortOption): number {
return !!a.isUnreachable !== !!b.isUnreachable
? a.isUnreachable
? 1
: -1
: 0;
}
function expandLinked (input: LinkOption[]): LinkOption[] {
const valueRelay = input.map(({ value }) => value);
return input.reduce((result: LinkOption[], entry): LinkOption[] => {
result.push(entry);
return entry.linked
? result.concat(
expandLinked(entry.linked).map((child): LinkOption => {
child.genesisHashRelay = entry.genesisHash;
child.isChild = true;
child.textRelay = input.length
? input[0].text
: undefined;
child.valueRelay = valueRelay;
if (entry.ui?.identityIcon && child.paraId && child.paraId < 2000) {
if (!child.ui) {
child.ui = { identityIcon: entry.ui.identityIcon };
} else if (!child.ui.identityIcon) {
child.ui.identityIcon = entry.ui.identityIcon;
}
}
return child;
})
)
: result;
}, []);
}
function expandEndpoint (t: TFunction, { dnslink, genesisHash, homepage, info, isChild, isDisabled, isPeople, isPeopleForIdentity, isUnreachable, linked, paraId, providers, relayName, teleport, text, ui }: EndpointOption, firstOnly: boolean, withSort: boolean): LinkOption[] {
const hasProviders = Object.keys(providers).length !== 0;
const base = {
genesisHash,
homepage,
info,
isChild,
isDisabled,
isPeople,
isPeopleForIdentity,
isUnreachable: isUnreachable || !hasProviders,
paraId,
providers: Object.keys(providers).map((k) => providers[k]),
relayName,
teleport,
text,
ui
};
const result = Object
.entries(
hasProviders
? providers
: { Placeholder: `wss://${++dummyId}` }
)
.filter((_, index) => !firstOnly || index === 0)
.map(([host, value], index): LinkOption => ({
...base,
dnslink: index === 0 ? dnslink : undefined,
isLightClient: value.startsWith('light://'),
isRelay: false,
textBy: value.startsWith('light://')
? t('lightclient.experimental', 'light client (experimental)', { ns: 'apps-config' })
: t('rpc.hosted.via', 'via {{host}}', { ns: 'apps-config', replace: { host } }),
value
}))
.sort((a, b) =>
a.isLightClient
? 1
: b.isLightClient
? -1
: a.textBy.toLocaleLowerCase().localeCompare(b.textBy.toLocaleLowerCase())
);
if (linked) {
const last = result[result.length - 1];
const options: LinkOption[] = [];
linked
.sort(withSort ? sortLinks : sortNoop)
.filter(({ paraId }) => paraId)
.forEach((o) =>
options.push(...expandEndpoint(t, o, firstOnly, withSort))
);
last.isRelay = true;
last.linked = options;
}
return expandLinked(result);
}
export function expandEndpoints (t: TFunction, input: EndpointOption[], firstOnly: boolean, withSort: boolean): LinkOption[] {
return input
.sort(withSort ? sortLinks : sortNoop)
.reduce((all: LinkOption[], e) =>
all.concat(expandEndpoint(t, e, firstOnly, withSort)), []);
}
export function getTeleports (input: EndpointOption[]): number[] {
return input
.filter(({ teleport }) => !!teleport && teleport[0] === -1)
.map(({ paraId }) => paraId)
.filter((id): id is number => !!id);
}