Files
explore/lib/api/pchain/useChainHeights.ts
T
zeekayandHanzo Dev e1cf5a1c4c fix(explore): reconcile chainIds to live/canonical + migrate chain RPC to /v1 (v1.1.7)
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 <dev@hanzo.ai>
2026-07-14 10:06:17 -07:00

66 lines
2.1 KiB
TypeScript

// React Query hook for fetching live block heights for P-chain and C-chain.
import { useQuery } from '@tanstack/react-query';
import { getEnvValue } from 'configs/app/utils';
const HEIGHTS_STALE_TIME_MS = 15_000;
const HEIGHTS_QUERY_KEY = 'pchain:chainHeights' as const;
async function fetchChainHeights(): Promise<{ pChain: number; cChain: number }> {
// NEXT_PUBLIC_NETWORK_RPC_URL IS the C-chain EVM RPC endpoint (canonical
// `/v1/bc/C/rpc` on the gateway). Dial it directly — no path rewriting — so
// the C-chain height works regardless of the gateway path scheme.
const cChainRpcUrl = getEnvValue('NEXT_PUBLIC_NETWORK_RPC_URL') ?? '';
const [ pRes, cRes ] = await Promise.allSettled([
// P-chain: use server-side proxy to bypass CORS
fetch('/api/pchain', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ jsonrpc: '2.0', method: 'platform.getHeight', params: {}, id: 1 }),
}),
fetch(cChainRpcUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ jsonrpc: '2.0', method: 'eth_blockNumber', params: [], id: 2 }),
}),
]);
let pChain = 0;
let cChain = 0;
if (pRes.status === 'fulfilled' && pRes.value.ok) {
const data = await pRes.value.json() as { result?: { height?: string } };
pChain = data.result?.height ? parseInt(data.result.height, 10) : 0;
}
if (cRes.status === 'fulfilled' && cRes.value.ok) {
const data = await cRes.value.json() as { result?: string };
cChain = data.result ? parseInt(data.result, 16) : 0;
}
return { pChain, cChain };
}
export interface UseChainHeightsResult {
readonly pChainHeight: number;
readonly cChainHeight: number;
readonly isLoading: boolean;
}
export function useChainHeights(): UseChainHeightsResult {
const query = useQuery({
queryKey: [ HEIGHTS_QUERY_KEY ],
queryFn: fetchChainHeights,
staleTime: HEIGHTS_STALE_TIME_MS,
refetchInterval: HEIGHTS_STALE_TIME_MS,
});
return {
pChainHeight: query.data?.pChain ?? 0,
cChainHeight: query.data?.cChain ?? 0,
isLoading: query.isLoading,
};
}