mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
chainId reconciliation (registry = live chains = genesis LP-018 map, one way): - Pars mainnet 7070 -> 494949 (live api.pars.network eth_chainId=0x78d65, net_version=494949); Pars testnet 7071 -> 494950, devnet 7072 -> 494951 (matches genesis configs/lp182_chain_id_map.go 4949xx scheme). - Lux devnet 96370 -> 96367 (live api.lux-dev.network reports 96367). - chainRegistry.spec.ts now asserts Pars 494949 (was stale-7070 assert). - Also fixed: configmap-mainnet Pars NETWORK_ID, configmap-testnet Pars NETWORK_ID, branded_build.sh, tools/send_test_txs.py, well-known/explore.json (regenerated from the fixed registry). RPC /ext/bc/<alias>/rpc -> /v1/bc/C/rpc (gateway canonical; each sovereign L1 serves its own C-Chain at /v1/bc/C/rpc). Verified returning blocks before switch: Lux/Zoo/Hanzo/Pars mainnet + Lux testnet. Kept on /ext (their /v1 not up yet): Lux devnet, brand testnets, local-node compose/test-tool URLs. P-chain proxy now dials /v1/bc/P. useChainHeights + luxnet/instance no longer strip /ext/bc/C/rpc; they use the env RPC URL / origin directly so C-chain height + luxnet SDK work under /v1. Co-authored-by: Hanzo Dev <[email protected]>
148 lines
4.7 KiB
TypeScript
148 lines
4.7 KiB
TypeScript
import type { Chain } from 'viem';
|
|
|
|
import appConfig from 'configs/app';
|
|
import { CHAINS as REGISTRY_CHAINS, getCurrentChain } from 'configs/app/chainRegistry';
|
|
import essentialDappsChainsConfig from 'configs/essential-dapps-chains';
|
|
import multichainConfig from 'configs/multichain';
|
|
|
|
const getChainInfo = (
|
|
config: Partial<typeof appConfig> = appConfig,
|
|
contracts?: Chain['contracts'],
|
|
logoUrl?: string,
|
|
): Chain | undefined => {
|
|
if (!config.chain || !config.app) {
|
|
return;
|
|
}
|
|
|
|
return {
|
|
id: Number(config.chain.id),
|
|
name: config.chain.name ?? '',
|
|
nativeCurrency: {
|
|
decimals: config.chain.currency.decimals,
|
|
name: config.chain.currency.name ?? '',
|
|
symbol: config.chain.currency.symbol ?? '',
|
|
},
|
|
rpcUrls: {
|
|
'default': {
|
|
http: config.chain.rpcUrls,
|
|
},
|
|
},
|
|
blockExplorers: {
|
|
'default': {
|
|
name: `${ config.chain.name || '' } Explorer`.trim(),
|
|
url: config.app.baseUrl,
|
|
},
|
|
},
|
|
testnet: config.chain.isTestnet,
|
|
contracts,
|
|
custom: {
|
|
logoUrl: logoUrl ?? config.UI?.navigation.icon.default,
|
|
},
|
|
};
|
|
};
|
|
|
|
export const currentChain: Chain | undefined = !appConfig.features.multichain.isEnabled ? getChainInfo() : undefined;
|
|
|
|
export const parentChain: Chain | undefined = (() => {
|
|
const rollupFeature = appConfig.features.rollup;
|
|
|
|
const parentChain = rollupFeature.isEnabled && rollupFeature.parentChain;
|
|
|
|
if (!parentChain) {
|
|
return;
|
|
}
|
|
|
|
if (!parentChain.id || !parentChain.name || !parentChain.rpcUrls || !parentChain.baseUrl || !parentChain.currency) {
|
|
return;
|
|
}
|
|
|
|
return {
|
|
id: parentChain.id,
|
|
name: parentChain.name,
|
|
nativeCurrency: parentChain.currency,
|
|
rpcUrls: {
|
|
'default': {
|
|
http: parentChain.rpcUrls,
|
|
},
|
|
},
|
|
blockExplorers: {
|
|
'default': {
|
|
name: `${ parentChain.name || '' } Explorer`.trim(),
|
|
url: parentChain.baseUrl,
|
|
},
|
|
},
|
|
testnet: parentChain.isTestnet,
|
|
};
|
|
})();
|
|
|
|
export const clusterChains: Array<Chain> | undefined = (() => {
|
|
const config = multichainConfig();
|
|
|
|
if (!config) {
|
|
return;
|
|
}
|
|
|
|
return config.chains.map(({ app_config: config, logo }) => getChainInfo(config, undefined, logo)).filter(Boolean);
|
|
})();
|
|
|
|
export const essentialDappsChains: Array<Chain> | undefined = (() => {
|
|
const config = essentialDappsChainsConfig();
|
|
|
|
if (!config) {
|
|
return;
|
|
}
|
|
|
|
return config.chains.map(({ app_config: config, contracts, logo }) => getChainInfo(config, contracts, logo)).filter(Boolean);
|
|
})();
|
|
|
|
// Sibling networks of the current brand, sourced from the multi-tenant chain
|
|
// registry so the wallet-connect flow presents / can add EVERY registered
|
|
// network for this brand — e.g. Lux mainnet (96369), testnet (96368) and
|
|
// devnet (96367) — instead of only the single env-configured chain. This is
|
|
// the "native all-chains" connect: the list is derived from the registry
|
|
// (the same source of truth as the header chain switcher), never hardcoded to
|
|
// one chain. Each sibling's read RPC is its brand explorer's Blockscout
|
|
// eth-rpc proxy (mirrors the read-only transport wagmiConfig builds for the
|
|
// primary chain); the current chain keeps its own direct RPC from env.
|
|
export const brandFamilyChains: Array<Chain> = (() => {
|
|
if (!currentChain) {
|
|
return [];
|
|
}
|
|
const current = getCurrentChain();
|
|
const titleCase = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
|
|
return REGISTRY_CHAINS
|
|
.filter((c) => c.branding.brandName === current.branding.brandName && c.chainId !== currentChain.id)
|
|
.map((c): Chain => ({
|
|
id: c.chainId,
|
|
name: c.network === 'mainnet' ? current.branding.brandName : `${ current.branding.brandName } ${ titleCase(c.network) }`,
|
|
nativeCurrency: currentChain.nativeCurrency,
|
|
rpcUrls: {
|
|
'default': { http: [ `${ c.apiUrl }/api/eth-rpc` ] },
|
|
},
|
|
blockExplorers: {
|
|
'default': { name: `${ current.branding.brandName } Explorer`, url: c.explorerUrl },
|
|
},
|
|
testnet: c.network !== 'mainnet',
|
|
}));
|
|
})();
|
|
|
|
export const chains = (() => {
|
|
const dedupeById = (list: Array<Chain | undefined>): Array<Chain> =>
|
|
list.filter(Boolean).filter((chain, index, arr) => arr.findIndex((c) => c?.id === chain?.id) === index) as Array<Chain>;
|
|
|
|
if (essentialDappsChains) {
|
|
const hasCurrentChain = essentialDappsChains.some((chain) => chain.id === currentChain?.id);
|
|
const hasParentChain = essentialDappsChains.some((chain) => chain.id === parentChain?.id);
|
|
|
|
return dedupeById([
|
|
...essentialDappsChains,
|
|
hasCurrentChain ? undefined : currentChain,
|
|
hasParentChain ? undefined : parentChain,
|
|
...brandFamilyChains,
|
|
]);
|
|
}
|
|
|
|
return dedupeById([ currentChain, ...brandFamilyChains, parentChain, ...(clusterChains ?? []) ]);
|
|
})();
|