From baa42a32324b0af823898f543d9e4d1c38f18ed4 Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Sat, 14 Jun 2025 14:19:03 +0100 Subject: [PATCH 01/11] chore(api-reference) Add Contract Manager Support --- apps/api-reference/package.json | 1 + apps/api-reference/src/evm-networks.ts | 941 ++----------------------- pnpm-lock.yaml | 79 +-- 3 files changed, 66 insertions(+), 955 deletions(-) diff --git a/apps/api-reference/package.json b/apps/api-reference/package.json index 5056157a7f..e23df68fc1 100644 --- a/apps/api-reference/package.json +++ b/apps/api-reference/package.json @@ -25,6 +25,7 @@ "@heroicons/react": "catalog:", "@next/third-parties": "catalog:", "@pythnetwork/client": "catalog:", + "@pythnetwork/contract-manager": "workspace:*", "@pythnetwork/pyth-sdk-solidity": "workspace:*", "@solana/web3.js": "catalog:", "@tanstack/react-query": "catalog:", diff --git a/apps/api-reference/src/evm-networks.ts b/apps/api-reference/src/evm-networks.ts index 15ac23ae41..1ee91a58f3 100644 --- a/apps/api-reference/src/evm-networks.ts +++ b/apps/api-reference/src/evm-networks.ts @@ -1,11 +1,47 @@ +import * as EvmChains from "@pythnetwork/contract-manager/data/chains/EvmChains.json"; +import * as EvmPriceFeedContracts from "@pythnetwork/contract-manager/data/contracts/EvmPriceFeedContracts.json"; + +type EvmChains = { + id: string; + mainnet: boolean; + rpcUrl: string; + networkId: number; + type: string; + nativeToken?: string; +}; + +const getPriceFeedContractAddress = (chain: EvmChains) => { + const contractAddress = Object.values(EvmPriceFeedContracts).find( + (contract) => contract.chain === chain.id, + ); + return contractAddress?.address as `0x${string}`; +}; + +const mapEvmChainsToNetworkInfo = (chains: EvmChains[]) => { + const networkInfo: Record = {}; + + for (const chain of chains) { + const id = Number(chain.networkId); + networkInfo[id] = { + name: chain.id, + rpcUrl: chain.rpcUrl, + isMainnet: chain.mainnet, + contractAddress: getPriceFeedContractAddress(chain), + }; + } + + return networkInfo; +}; + +// Convert EvmChains to array format +const evmChainsArray = Object.values(EvmChains) as EvmChains[]; +export const NETWORK_INFO = mapEvmChainsToNetworkInfo(evmChainsArray); + export const getContractAddress = (networkId: number) => isSupportedNetwork(networkId) - ? NETWORK_INFO[networkId].contractAddress + ? NETWORK_INFO[networkId]?.contractAddress : undefined; -export const getRpcUrl = (networkId: number) => - isSupportedNetwork(networkId) ? NETWORK_INFO[networkId].rpcUrl : undefined; - const isSupportedNetwork = ( networkId: number, ): networkId is keyof typeof NETWORK_INFO => networkId in NETWORK_INFO; @@ -17,901 +53,8 @@ type NetworkInfo = { contractAddress: `0x${string}`; }; -// TODO Currently, contract_manager is designed in a way that does not work in -// any js environment except nodejs, including browsers and the Edge runtime. -// So the network info here is just restructured info from contract_manager. -// However, once contract_manager is refactored to work on web, we should -// replace this and should use contract_manager to drive all this info instead. -export const NETWORK_INFO = { - [1]: { - name: "ethereum", - rpcUrl: `https://eth.llamarpc.com `, - isMainnet: true, - contractAddress: "0x4305FB66699C3B2702D4d05CF36551390A4c69C6", - }, - [10]: { - name: "optimism", - rpcUrl: "https://rpc.ankr.com/optimism", - isMainnet: true, - contractAddress: "0xff1a0f4744e8582DF1aE09D5611b887B6a12925C", - }, - [25]: { - name: "cronos", - rpcUrl: "https://cronosrpc-1.xstaking.sg", - isMainnet: true, - contractAddress: "0xE0d0e68297772Dd5a1f1D99897c581E2082dbA5B", - }, - [56]: { - name: "bsc", - rpcUrl: "https://rpc.ankr.com/bsc", - isMainnet: true, - contractAddress: "0x4D7E825f80bDf85e913E0DD2A2D54927e9dE1594", - }, - [71]: { - name: "conflux_espace_testnet", - rpcUrl: "https://evmtestnet.confluxrpc.com", - isMainnet: false, - contractAddress: "0xDd24F84d36BF92C65F92307595335bdFab5Bbd21", - }, - [82]: { - name: "meter", - rpcUrl: "https://meter.blockpi.network/v1/rpc/public", - isMainnet: true, - contractAddress: "0xbFe3f445653f2136b2FD1e6DdDb5676392E3AF16", - }, - [83]: { - name: "meter_testnet", - rpcUrl: "https://rpctest.meter.io", - isMainnet: false, - contractAddress: "0x5a71C07a0588074443545eE0c08fb0375564c3E4", - }, - [88]: { - name: "viction", - rpcUrl: "https://viction.blockpi.network/v1/rpc/public", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [97]: { - name: "bsc_testnet", - rpcUrl: "https://bsc-testnet.drpc.org", - isMainnet: false, - contractAddress: "0x5744Cbf430D99456a0A8771208b674F27f8EF0Fb", - }, - [100]: { - name: "gnosis", - rpcUrl: "https://rpc.gnosischain.com", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [137]: { - name: "polygon", - rpcUrl: "https://polygon-rpc.com", - isMainnet: true, - contractAddress: "0xff1a0f4744e8582DF1aE09D5611b887B6a12925C", - }, - [148]: { - name: "shimmer", - rpcUrl: "https://json-rpc.evm.shimmer.network", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [169]: { - name: "manta", - rpcUrl: "https://pacific-rpc.manta.network/http", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [199]: { - name: "bttc", - rpcUrl: "https://rpc.bt.io", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [204]: { - name: "opbnb", - rpcUrl: "https://opbnb-mainnet-rpc.bnbchain.org", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [250]: { - name: "fantom", - rpcUrl: "https://rpc.ankr.com/fantom", - isMainnet: true, - contractAddress: "0xff1a0f4744e8582DF1aE09D5611b887B6a12925C", - }, - [288]: { - name: "boba", - rpcUrl: "https://replica.boba.network", - isMainnet: true, - contractAddress: "0x4374e5a8b9C22271E9EB878A2AA31DE97DF15DAF", - }, - [295]: { - name: "hedera", - rpcUrl: "https://mainnet.hashio.io/api", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [296]: { - name: "hedera_testnet", - rpcUrl: "https://testnet.hashio.io/api", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [300]: { - name: "zksync_sepolia", - rpcUrl: "https://sepolia.era.zksync.dev/", - isMainnet: false, - contractAddress: "0x056f829183Ec806A78c26C98961678c24faB71af", - }, - [314]: { - name: "filecoin", - rpcUrl: "https://rpc.ankr.com/filecoin", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [321]: { - name: "kcc", - rpcUrl: "https://rpc-mainnet.kcc.network", - isMainnet: true, - contractAddress: "0xE0d0e68297772Dd5a1f1D99897c581E2082dbA5B", - }, - [322]: { - name: "kcc_testnet", - rpcUrl: "https://rpc-testnet.kcc.network", - isMainnet: false, - contractAddress: "0x74f09cb3c7e2A01865f424FD14F6dc9A14E3e94E", - }, - [324]: { - name: "zksync", - rpcUrl: "https://zksync2-mainnet.zksync.io", - isMainnet: true, - contractAddress: "0xf087c864AEccFb6A2Bf1Af6A0382B0d0f6c5D834", - }, - [336]: { - name: "movement_evm_devnet", - rpcUrl: "https://mevm.devnet.m1.movementlabs.xyz/v1", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [338]: { - name: "cronos_testnet", - rpcUrl: "https://evm-t3.cronos.org", - isMainnet: false, - contractAddress: "0x36825bf3Fbdf5a29E2d5148bfe7Dcf7B5639e320", - }, - [646]: { - name: "flow_previewnet", - rpcUrl: "https://previewnet.evm.nodes.onflow.org", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [919]: { - name: "mode_testnet", - rpcUrl: "https://sepolia.mode.network/", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [987]: { - name: "orange_testnet", - rpcUrl: "https://subnets.avax.network/orangetest/testnet/rpc", - isMainnet: false, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [1001]: { - name: "kaia_testnet", - rpcUrl: "https://rpc.ankr.com/klaytn_testnet", - isMainnet: false, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [1024]: { - name: "parallel", - rpcUrl: "https://rpc.parallel.fi/", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [1029]: { - name: "bttc_testnet", - rpcUrl: "https://pre-rpc.bt.io", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [1030]: { - name: "conflux_espace", - rpcUrl: "https://evm.confluxrpc.org", - isMainnet: true, - contractAddress: "0xe9d69CdD6Fe41e7B621B4A688C5D1a68cB5c8ADc", - }, - [1073]: { - name: "shimmer_testnet", - rpcUrl: "https://json-rpc.evm.testnet.shimmer.network", - isMainnet: false, - contractAddress: "0x8D254a21b3C86D32F7179855531CE99164721933", - }, - [1101]: { - name: "polygon_zkevm", - rpcUrl: "https://zkevm-rpc.com", - isMainnet: true, - contractAddress: "0xC5E56d6b40F3e3B5fbfa266bCd35C37426537c65", - }, - [1111]: { - name: "wemix", - rpcUrl: "https://api.wemix.com", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [1112]: { - name: "wemix_testnet", - rpcUrl: "https://api.test.wemix.com", - isMainnet: false, - contractAddress: "0x26DD80569a8B23768A1d80869Ed7339e07595E85", - }, - [1115]: { - name: "coredao_testnet", - rpcUrl: "https://rpc.test.btcs.network", - isMainnet: false, - contractAddress: "0x8D254a21b3C86D32F7179855531CE99164721933", - }, - [1116]: { - name: "coredao", - rpcUrl: "https://rpc.coredao.org", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [1315]: { - name: "story_testnet", - rpcUrl: "https://aeneid.storyrpc.io", - isMainnet: false, - contractAddress: "0x36825bf3Fbdf5a29E2d5148bfe7Dcf7B5639e320", - }, - [1328]: { - name: "sei_evm_testnet", - rpcUrl: "https://evm-rpc-testnet.sei-apis.com", - isMainnet: false, - contractAddress: "0x36825bf3Fbdf5a29E2d5148bfe7Dcf7B5639e320", - }, - [1329]: { - name: "sei_evm_mainnet", - rpcUrl: "https://evm-rpc.sei-apis.com", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [1442]: { - name: "polygon_zkevm_testnet", - rpcUrl: "https://rpc.public.zkevm-test.net", - isMainnet: false, - contractAddress: "0xFf255f800044225f54Af4510332Aa3D67CC77635", - }, - [1514]: { - name: "story", - rpcUrl: "https://homer.storyrpc.io", - isMainnet: true, - contractAddress: "0xD458261E832415CFd3BAE5E416FdF3230ce6F134", - }, - [1625]: { - name: "gravity", - rpcUrl: "https://rpc.gravity.xyz/", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [1890]: { - name: "lightlink_phoenix", - rpcUrl: "https://replicator.phoenix.lightlink.io/rpc/v1", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [1891]: { - name: "lightlink_pegasus_testnet", - rpcUrl: "https://replicator.pegasus.lightlink.io/rpc/v1", - isMainnet: false, - contractAddress: "0x5D289Ad1CE59fCC25b6892e7A303dfFf3a9f7167", - }, - [2020]: { - name: "ronin", - rpcUrl: `https://api.roninchain.com/rpc`, - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [2021]: { - name: "saigon", - rpcUrl: `https://edgeware-evm0.jelliedowl.net`, - isMainnet: false, - contractAddress: "0xEbe57e8045F2F230872523bbff7374986E45C486", - }, - [2221]: { - name: "kava_testnet", - rpcUrl: "https://evm.testnet.kava.io", - isMainnet: false, - contractAddress: "0xfA25E653b44586dBbe27eE9d252192F0e4956683", - }, - [2222]: { - name: "kava", - rpcUrl: "https://kava-evm.publicnode.com", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [2424]: { - name: "injective_inevm_testnet", - rpcUrl: "https://inevm-testnet.rpc.caldera.xyz/http", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [2525]: { - name: "injective_inevm", - rpcUrl: "https://inevm.calderachain.xyz/http", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [2710]: { - name: "morph_testnet", - rpcUrl: "https://rpc-testnet.morphl2.io", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [2810]: { - name: "morph_holesky_testnet", - rpcUrl: "https://rpc-holesky.morphl2.io", - isMainnet: false, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [2888]: { - name: "boba_goerli", - rpcUrl: "https://goerli.boba.network", - isMainnet: false, - contractAddress: "0x8D254a21b3C86D32F7179855531CE99164721933", - }, - [3776]: { - name: "astar_zkevm", - rpcUrl: "https://rpc.startale.com/astar-zkevm", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [4002]: { - name: "fantom_testnet", - rpcUrl: `https://rpc.ankr.com/fantom_testnet`, - isMainnet: false, - contractAddress: "0x5744Cbf430D99456a0A8771208b674F27f8EF0Fb", - }, - [4200]: { - name: "merlin", - rpcUrl: "https://rpc.merlinchain.io", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [5000]: { - name: "mantle", - rpcUrl: "https://rpc.mantle.xyz/", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [5003]: { - name: "mantle_sepolia", - rpcUrl: "https://rpc.sepolia.mantle.xyz", - isMainnet: false, - contractAddress: "0x98046Bd286715D3B0BC227Dd7a956b83D8978603", - }, - [5611]: { - name: "opbnb_testnet", - rpcUrl: "https://opbnb-testnet-rpc.bnbchain.org", - isMainnet: false, - contractAddress: "0x41c9e39574F40Ad34c79f1C99B66A45eFB830d4c", - }, - [7000]: { - name: "zetachain", - rpcUrl: "https://zetachain-evm.blockpi.network/v1/rpc/public", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [7001]: { - name: "zetachain_testnet", - rpcUrl: "https://zetachain-athens-evm.blockpi.network/v1/rpc/public", - isMainnet: false, - contractAddress: "0x0708325268dF9F66270F1401206434524814508b", - }, - [7332]: { - name: "horizen_eon", - rpcUrl: "https://rpc.ankr.com/horizen_eon", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [7700]: { - name: "canto", - rpcUrl: "https://canto.slingshot.finance", - isMainnet: true, - contractAddress: "0x98046Bd286715D3B0BC227Dd7a956b83D8978603", - }, - [7701]: { - name: "canto_testnet", - rpcUrl: "https://canto-testnet.plexnode.wtf", - isMainnet: false, - contractAddress: "0x26DD80569a8B23768A1d80869Ed7339e07595E85", - }, - [8008]: { - name: "polynomial", - rpcUrl: "https://rpc.polynomial.fi/", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [8217]: { - name: "kaia", - rpcUrl: "https://rpc.ankr.com/klaytn", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [8453]: { - name: "base", - rpcUrl: "https://developer-access-mainnet.base.org/", - isMainnet: true, - contractAddress: "0x8250f4aF4B972684F7b336503E2D6dFeDeB1487a", - }, - [9000]: { - name: "evmos_testnet", - rpcUrl: "https://jsonrpc-evmos-testnet.mzonder.com", - isMainnet: false, - contractAddress: "0x74f09cb3c7e2A01865f424FD14F6dc9A14E3e94E", - }, - [9001]: { - name: "evmos", - rpcUrl: "https://evmos-evm.publicnode.com", - isMainnet: true, - contractAddress: "0x354bF866A4B006C9AF9d9e06d9364217A8616E12", - }, - [9393]: { - name: "dela_deperp_testnet", - rpcUrl: "https://sepolia-dela.deperp.com", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [9659]: { - name: "parallel_testnet", - rpcUrl: "https://rpc-accused-coffee-koala-b9fn1dik76.t.conduit.xyz", - isMainnet: false, - contractAddress: "0x23f0e8FAeE7bbb405E7A7C3d60138FCfd43d7509", - }, - [10_200]: { - name: "chiado", - rpcUrl: "https://rpc.chiadochain.net", - isMainnet: false, - contractAddress: "0x98046Bd286715D3B0BC227Dd7a956b83D8978603", - }, - [15_557]: { - name: "eos_testnet", - rpcUrl: "https://api.testnet.evm.eosnetwork.com", - isMainnet: false, - contractAddress: "0x0708325268dF9F66270F1401206434524814508b", - }, - [17_777]: { - name: "eos", - rpcUrl: "https://api.evm.eosnetwork.com", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [33_612]: { - name: "dela_mithreum_deperp_testnet", - rpcUrl: "https://mithreum-rpc-sepolia.deperp.com", - isMainnet: false, - contractAddress: "0xe9d69CdD6Fe41e7B621B4A688C5D1a68cB5c8ADc", - }, - [34_443]: { - name: "mode", - rpcUrl: "https://mainnet.mode.network/", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [42_161]: { - name: "arbitrum", - rpcUrl: "https://arb1.arbitrum.io/rpc", - isMainnet: true, - contractAddress: "0xff1a0f4744e8582DF1aE09D5611b887B6a12925C", - }, - [42_220]: { - name: "celo", - rpcUrl: "https://forno.celo.org", - isMainnet: true, - contractAddress: "0xff1a0f4744e8582DF1aE09D5611b887B6a12925C", - }, - [42_766]: { - name: "zkfair", - rpcUrl: "https://rpc.zkfair.io", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [42_793]: { - name: "etherlink", - rpcUrl: "https://node.mainnet.etherlink.com/", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [43_113]: { - name: "fuji", - rpcUrl: "https://api.avax-test.network/ext/bc/C/rpc", - isMainnet: false, - contractAddress: "0x23f0e8FAeE7bbb405E7A7C3d60138FCfd43d7509", - }, - [43_114]: { - name: "avalanche", - rpcUrl: "https://api.avax.network/ext/bc/C/rpc", - isMainnet: true, - contractAddress: "0x4305FB66699C3B2702D4d05CF36551390A4c69C6", - }, - [43_851]: { - name: "zkfair_testnet", - rpcUrl: "https://testnet-rpc.zkfair.io", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [44_787]: { - name: "celo_alfajores_testnet", - rpcUrl: "https://alfajores-forno.celo-testnet.org", - isMainnet: false, - contractAddress: "0x74f09cb3c7e2A01865f424FD14F6dc9A14E3e94E", - }, - [59_140]: { - name: "linea_goerli", - rpcUrl: `https://rpc.goerli.linea.build`, - isMainnet: false, - contractAddress: "0xdF21D137Aadc95588205586636710ca2890538d5", - }, - [59_141]: { - name: "linea_sepolia", - rpcUrl: "https://rpc.sepolia.linea.build", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [59_144]: { - name: "linea", - rpcUrl: "https://linea.rpc.thirdweb.com", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [64_002]: { - name: "idex_xchain_testnet", - rpcUrl: "https://xchain-testnet-rpc.idex.io", - isMainnet: false, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [80_002]: { - name: "polygon_amoy", - rpcUrl: "https://polygon-amoy-bor-rpc.publicnode.com", - isMainnet: false, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [80_008]: { - name: "polynomial_testnet", - rpcUrl: "https://rpc-polynomial-network-testnet-x0tryg8u1c.t.conduit.xyz", - isMainnet: false, - contractAddress: "0x23f0e8FAeE7bbb405E7A7C3d60138FCfd43d7509", - }, - [80_084]: { - name: "berachain_testnet_v2", - rpcUrl: "https://evm-rpc-bera.rhino-apis.com/", - isMainnet: false, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [80_085]: { - name: "berachain_testnet", - rpcUrl: "https://rpc.ankr.com/berachain_testnet", - isMainnet: false, - contractAddress: "0x8D254a21b3C86D32F7179855531CE99164721933", - }, - [81_457]: { - name: "blast", - rpcUrl: "https://rpc.blast.io", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [84_532]: { - name: "base_sepolia", - rpcUrl: "https://sepolia.base.org", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [88_882]: { - name: "chiliz_spicy", - rpcUrl: "https://spicy-rpc.chiliz.com", - isMainnet: false, - contractAddress: "0x23f0e8FAeE7bbb405E7A7C3d60138FCfd43d7509", - }, - [88_888]: { - name: "chiliz", - rpcUrl: "https://rpc.ankr.com/chiliz", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [128_123]: { - name: "etherlink_testnet", - rpcUrl: "https://node.ghostnet.etherlink.com/", - isMainnet: false, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [167_000]: { - name: "taiko_mainnet", - rpcUrl: "https://rpc.mainnet.taiko.xyz", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [167_009]: { - name: "taiko_hekla", - rpcUrl: "https://rpc.hekla.taiko.xyz/", - isMainnet: false, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [314_159]: { - name: "filecoin_calibration", - rpcUrl: "https://rpc.ankr.com/filecoin_testnet", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [412_346]: { - name: "syndr_nitro_testnet", - rpcUrl: "https://syndr-nitro-testnet.calderachain.xyz/http", - isMainnet: false, - contractAddress: "0xEbe57e8045F2F230872523bbff7374986E45C486", - }, - [421_614]: { - name: "arbitrum_sepolia", - rpcUrl: "https://sepolia-rollup.arbitrum.io/rpc", - isMainnet: false, - contractAddress: "0x4374e5a8b9C22271E9EB878A2AA31DE97DF15DAF", - }, - [534_351]: { - name: "scroll_sepolia", - rpcUrl: "https://sepolia-rpc.scroll.io/", - isMainnet: false, - contractAddress: "0x41c9e39574F40Ad34c79f1C99B66A45eFB830d4c", - }, - [534_352]: { - name: "scroll", - rpcUrl: "https://rpc.scroll.io", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [686_868]: { - name: "merlin_testnet", - rpcUrl: "https://testnet-rpc.merlinchain.io/", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [1_261_120]: { - name: "astar_zkevm_testnet", - rpcUrl: "https://rpc.zkatana.gelato.digital", - isMainnet: false, - contractAddress: "0x8D254a21b3C86D32F7179855531CE99164721933", - }, - [3_441_005]: { - name: "manta_testnet", - rpcUrl: "https://manta-pacific-testnet.drpc.org", - isMainnet: false, - contractAddress: "0x41c9e39574F40Ad34c79f1C99B66A45eFB830d4c", - }, - [3_441_006]: { - name: "manta_sepolia", - rpcUrl: "https://manta-sepolia.rpc.caldera.xyz/http", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [8_101_902]: { - name: "olive_testnet", - rpcUrl: "https://olive-network-testnet.rpc.caldera.xyz/http", - isMainnet: false, - contractAddress: "0x41c9e39574F40Ad34c79f1C99B66A45eFB830d4c", - }, - [11_155_111]: { - name: "sepolia", - rpcUrl: `https://ethereum-sepolia-rpc.publicnode.com`, - isMainnet: false, - contractAddress: "0xDd24F84d36BF92C65F92307595335bdFab5Bbd21", - }, - [11_155_420]: { - name: "optimism_sepolia", - rpcUrl: "https://sepolia.optimism.io", - isMainnet: false, - contractAddress: "0x0708325268dF9F66270F1401206434524814508b", - }, - [94_204_209]: { - name: "polygon_blackberry", - rpcUrl: "https://rpc.polygon-blackberry.gelato.digital", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [123_420_111]: { - name: "optimism_celestia_raspberry", - rpcUrl: "https://rpc.opcelestia-raspberry.gelato.digital", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [168_587_773]: { - name: "blast_s2_testnet", - rpcUrl: "https://sepolia.blast.io", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [245_022_926]: { - name: "neon_devnet", - rpcUrl: "https://devnet.neonevm.org", - isMainnet: false, - contractAddress: "0x0708325268dF9F66270F1401206434524814508b", - }, - [245_022_934]: { - name: "neon", - rpcUrl: "https://neon-evm.drpc.org", - isMainnet: true, - contractAddress: "0x7f2dB085eFC3560AFF33865dD727225d91B4f9A5", - }, - [1_313_161_554]: { - name: "aurora", - rpcUrl: "https://mainnet.aurora.dev", - isMainnet: true, - contractAddress: "0xF89C7b475821EC3fDC2dC8099032c05c6c0c9AB9", - }, - [1_313_161_555]: { - name: "aurora_testnet", - rpcUrl: "https://testnet.aurora.dev", - isMainnet: false, - contractAddress: "0x74f09cb3c7e2A01865f424FD14F6dc9A14E3e94E", - }, - [1_802_203_764]: { - name: "kakarot_sepolia", - rpcUrl: "https://sepolia-rpc-priority.kakarot.org", - isMainnet: false, - contractAddress: "0xD458261E832415CFd3BAE5E416FdF3230ce6F134", - }, - [88_153_591_557]: { - name: "arbitrum_blueberry", - rpcUrl: "https://rpc.arb-blueberry.gelato.digital", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [89]: { - name: "viction_testnet", - rpcUrl: "https://rpc-testnet.viction.xyz", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [1663]: { - name: "horizen_gobi", - rpcUrl: "https://rpc.ankr.com/horizen_gobi_testnet", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [6_038_361]: { - name: "astar_zkyoto_testnet", - rpcUrl: "https://rpc.startale.com/zkyoto", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [8822]: { - name: "iota", - rpcUrl: "https://json-rpc.evm.iotaledger.net", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [9789]: { - name: "tabi_testnet", - rpcUrl: "https://rpc-internal.testnet.tabichain.com/", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [1993]: { - name: "b3_testnet", - rpcUrl: "https://sepolia.b3.fun/http/", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [7887]: { - name: "kinto", - rpcUrl: "https://rpc.kinto-rpc.com", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [282]: { - name: "cronos_zkevm_testnet", - rpcUrl: "https://testnet.zkevm.cronos.org", - isMainnet: false, - contractAddress: "0x67DFF3D12dFDCeC9f85fd86f4cBDb0a111fF721A", - }, - [89_346_162]: { - name: "reya_testnet", - rpcUrl: "https://rpc.reya-cronos.gelato.digital", - isMainnet: false, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [8333]: { - name: "b3_mainnet", - rpcUrl: "https://mainnet-rpc.b3.fun/http", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [388]: { - name: "cronos_zkevm_mainnet", - rpcUrl: "https://mainnet.zkevm.cronos.org", - isMainnet: true, - contractAddress: "0x056f829183Ec806A78c26C98961678c24faB71af", - }, - [30_732]: { - name: "movement_evm_devnet_imola", - rpcUrl: "https://mevm.devnet.imola.movementlabs.xyz", - isMainnet: false, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [545]: { - name: "flow_testnet", - rpcUrl: "https://testnet.evm.nodes.onflow.org", - isMainnet: false, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [94_524]: { - name: "idex_xchain_mainnet", - rpcUrl: "https://xchain-rpc.idex.io/", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [33_111]: { - name: "apechain_testnet", - rpcUrl: "https://curtis.rpc.caldera.xyz/http", - isMainnet: false, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [1946]: { - name: "soneium_minato_testnet", - rpcUrl: "https://rpc.minato.soneium.org/", - isMainnet: false, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [33_139]: { - name: "apechain_mainnet", - rpcUrl: "https://apechain.calderachain.xyz/http", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [747]: { - name: "flow_mainnet", - rpcUrl: "https://mainnet.evm.nodes.onflow.org", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [11_124]: { - name: "abstract_testnet", - rpcUrl: "https://api.testnet.abs.xyz", - isMainnet: false, - contractAddress: "0x47F2A9BDAd52d65b66287253cf5ca0D2b763b486", - }, - [1996]: { - name: "sanko", - rpcUrl: "https://mainnet.sanko.xyz", - isMainnet: true, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [1992]: { - name: "sanko_testnet", - rpcUrl: "https://sanko-arb-sepolia.rpc.caldera.xyz", - isMainnet: false, - contractAddress: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", - }, - [1301]: { - name: "unichain_sepolia", - rpcUrl: "https://sepolia.unichain.org", - isMainnet: false, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [64_165]: { - name: "fantom_sonic_testnet", - rpcUrl: "https://rpc.testnet.soniclabs.com", - isMainnet: false, - contractAddress: "0x96124d1F6E44FfDf1fb5D6d74BB2DE1B7Fbe7376", - }, - [80_094]: { - name: "berachain_mainnet", - rpcUrl: "https://rpc.berachain.com", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, - [146]: { - name: "sonic_mainnet", - rpcUrl: " https://rpc.soniclabs.com", - isMainnet: true, - contractAddress: "0x2880aB155794e7179c9eE2e38200202908C17B43", - }, -} satisfies Record; +export const getRpcUrl = (networkId: number) => + isSupportedNetwork(networkId) ? NETWORK_INFO[networkId]?.rpcUrl : undefined; export const NETWORK_IDS = Object.keys(NETWORK_INFO).map((key) => Number.parseInt(key, 10), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1e5aca631e..91c1146007 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -364,6 +364,9 @@ importers: '@pythnetwork/client': specifier: 'catalog:' version: 2.22.1(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@pythnetwork/contract-manager': + specifier: workspace:* + version: link:../../contract_manager '@pythnetwork/pyth-sdk-solidity': specifier: workspace:* version: link:../../target_chains/ethereum/sdk/solidity @@ -1211,10 +1214,10 @@ importers: version: 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) '@solana/wallet-adapter-react-ui': specifier: 'catalog:' - version: 0.9.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-dom@19.1.0(react@19.1.0))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) + version: 0.9.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-dom@19.1.0(react@19.1.0))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) '@solana/wallet-adapter-wallets': specifier: 'catalog:' - version: 0.19.33(@babel/runtime@7.27.0)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.1.0(react@19.1.0))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.24.2) + version: 0.19.33(@babel/runtime@7.27.0)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.1.0(react@19.1.0))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.24.2) '@solana/web3.js': specifier: 'catalog:' version: 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) @@ -1514,7 +1517,7 @@ importers: version: 3.1.2(typescript@5.8.2) '@solana/wallet-adapter-react': specifier: 'catalog:' - version: 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) + version: 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) '@types/jest': specifier: 'catalog:' version: 29.5.14 @@ -30566,11 +30569,10 @@ snapshots: crypto-js: 4.2.0 uuidv4: 6.2.13 - '@particle-network/solana-wallet@1.3.2(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)': + '@particle-network/solana-wallet@1.3.2(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: '@particle-network/auth': 1.3.1 '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - bs58: 5.0.0 '@paulmillr/qr@0.2.1': {} @@ -34403,18 +34405,18 @@ snapshots: '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-base-ui@0.1.3(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)': + '@solana/wallet-adapter-base-ui@0.1.3(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-native@0.78.2(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)': dependencies: - '@solana/wallet-adapter-react': 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) + '@solana/wallet-adapter-react': 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-native@0.78.2(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) react: 19.1.0 transitivePeerDependencies: - bs58 - react-native - '@solana/wallet-adapter-base-ui@0.1.3(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-native@0.78.2(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)': + '@solana/wallet-adapter-base-ui@0.1.3(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)': dependencies: - '@solana/wallet-adapter-react': 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-native@0.78.2(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) + '@solana/wallet-adapter-react': 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) react: 19.1.0 transitivePeerDependencies: @@ -34530,9 +34532,9 @@ snapshots: '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-particle@0.1.13(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)': + '@solana/wallet-adapter-particle@0.1.13(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: - '@particle-network/solana-wallet': 1.3.2(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0) + '@particle-network/solana-wallet': 1.3.2(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) transitivePeerDependencies: @@ -34543,18 +34545,6 @@ snapshots: '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-react-ui@0.9.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-dom@19.1.0(react@19.1.0))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)': - dependencies: - '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-base-ui': 0.1.3(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) - '@solana/wallet-adapter-react': 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) - '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) - transitivePeerDependencies: - - bs58 - - react-native - '@solana/wallet-adapter-react-ui@0.9.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-dom@19.1.0(react@19.1.0))(react-native@0.78.2(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)': dependencies: '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) @@ -34567,22 +34557,23 @@ snapshots: - bs58 - react-native - '@solana/wallet-adapter-react@0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)': + '@solana/wallet-adapter-react-ui@0.9.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-dom@19.1.0(react@19.1.0))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)': dependencies: - '@solana-mobile/wallet-adapter-mobile': 2.1.5(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/wallet-standard-wallet-adapter-react': 1.1.4(@solana/wallet-adapter-base@0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react@19.1.0) + '@solana/wallet-adapter-base-ui': 0.1.3(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) + '@solana/wallet-adapter-react': 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) transitivePeerDependencies: - bs58 - react-native - '@solana/wallet-adapter-react@0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)': + '@solana/wallet-adapter-react@0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)': dependencies: '@solana-mobile/wallet-adapter-mobile': 2.1.5(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/wallet-standard-wallet-adapter-react': 1.1.4(@solana/wallet-adapter-base@0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)(react@19.1.0) + '@solana/wallet-standard-wallet-adapter-react': 1.1.4(@solana/wallet-adapter-base@0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react@19.1.0) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) react: 19.1.0 transitivePeerDependencies: @@ -34593,7 +34584,7 @@ snapshots: dependencies: '@solana-mobile/wallet-adapter-mobile': 2.1.5(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-native@0.78.2(@babel/core@7.26.10)(@babel/preset-env@7.26.9(@babel/core@7.26.10))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0) '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/wallet-standard-wallet-adapter-react': 1.1.4(@solana/wallet-adapter-base@0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)(react@19.1.0) + '@solana/wallet-standard-wallet-adapter-react': 1.1.4(@solana/wallet-adapter-base@0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react@19.1.0) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) react: 19.1.0 transitivePeerDependencies: @@ -34799,7 +34790,7 @@ snapshots: '@solana/wallet-adapter-nightly': 0.1.17(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-nufi': 0.1.18(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-onto': 0.1.8(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-particle': 0.1.13(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0) + '@solana/wallet-adapter-particle': 0.1.13(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-phantom': 0.9.25(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-safepal': 0.5.19(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-saifu': 0.1.16(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) @@ -34855,7 +34846,7 @@ snapshots: - ws - zod - '@solana/wallet-adapter-wallets@0.19.33(@babel/runtime@7.27.0)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.1.0(react@19.1.0))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.24.2)': + '@solana/wallet-adapter-wallets@0.19.33(@babel/runtime@7.27.0)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.8.2))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.1.0(react@19.1.0))(react-native@0.78.2(@babel/core@7.27.1)(@babel/preset-env@7.26.9(@babel/core@7.27.1))(@types/react@19.1.0)(bufferutil@4.0.9)(react@19.1.0)(utf-8-validate@5.0.10))(react@19.1.0)(tslib@2.8.1)(typescript@5.8.2)(utf-8-validate@5.0.10)(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.24.2)': dependencies: '@solana/wallet-adapter-alpha': 0.1.11(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-avana': 0.1.14(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) @@ -34876,7 +34867,7 @@ snapshots: '@solana/wallet-adapter-nightly': 0.1.17(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-nufi': 0.1.18(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-onto': 0.1.8(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-particle': 0.1.13(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0) + '@solana/wallet-adapter-particle': 0.1.13(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-phantom': 0.9.25(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-safepal': 0.5.19(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-saifu': 0.1.16(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) @@ -34971,19 +34962,6 @@ snapshots: '@wallet-standard/wallet': 1.1.0 bs58: 5.0.0 - '@solana/wallet-standard-wallet-adapter-base@1.1.4(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)': - dependencies: - '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/wallet-standard-chains': 1.1.1 - '@solana/wallet-standard-features': 1.3.0 - '@solana/wallet-standard-util': 1.1.2 - '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@wallet-standard/app': 1.1.0 - '@wallet-standard/base': 1.1.0 - '@wallet-standard/features': 1.1.0 - '@wallet-standard/wallet': 1.1.0 - bs58: 6.0.0 - '@solana/wallet-standard-wallet-adapter-react@1.1.4(@solana/wallet-adapter-base@0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react@19.1.0)': dependencies: '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) @@ -34995,17 +34973,6 @@ snapshots: - '@solana/web3.js' - bs58 - '@solana/wallet-standard-wallet-adapter-react@1.1.4(@solana/wallet-adapter-base@0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)(react@19.1.0)': - dependencies: - '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/wallet-standard-wallet-adapter-base': 1.1.4(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0) - '@wallet-standard/app': 1.1.0 - '@wallet-standard/base': 1.1.0 - react: 19.1.0 - transitivePeerDependencies: - - '@solana/web3.js' - - bs58 - '@solana/wallet-standard-wallet-adapter@1.1.4(@solana/wallet-adapter-base@0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react@19.1.0)': dependencies: '@solana/wallet-standard-wallet-adapter-base': 1.1.4(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0) From d05ca9bb0b8aec684acb1634fd3d18bb70fd712b Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Sun, 15 Jun 2025 15:22:37 +0100 Subject: [PATCH 02/11] chore(api-reference) Add viem RPC as a backup --- apps/api-reference/src/components/EvmProvider/index.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/api-reference/src/components/EvmProvider/index.tsx b/apps/api-reference/src/components/EvmProvider/index.tsx index d204fd78cd..b5aa2f67f5 100644 --- a/apps/api-reference/src/components/EvmProvider/index.tsx +++ b/apps/api-reference/src/components/EvmProvider/index.tsx @@ -19,9 +19,11 @@ const CHAINS = NETWORK_IDS.map((id) => const TRANSPORTS = Object.fromEntries( CHAINS.map((chain) => { - const url = getRpcUrl(chain.id); - if (url) { - return [chain.id, http(url)]; + const rpcUrl = getRpcUrl(chain.id); + if (rpcUrl) { + return [chain.id, http(rpcUrl)]; + } else if (chain.rpcUrls.default.http[0]) { + return [chain.id, http(chain.rpcUrls.default.http[0])]; } else { throw new Error(`No rpc url found for ${chain.name}`); } From 2f803ccdc76b78a39275eb28e85684c73ab1d688 Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Tue, 24 Jun 2025 15:47:01 -0400 Subject: [PATCH 03/11] update --- .../src/components/EvmApi/index.tsx | 6 +- .../src/components/EvmApi/run-button.tsx | 5 +- .../src/components/EvmProvider/index.tsx | 29 +++--- apps/api-reference/src/evm-networks.ts | 61 ------------- contract_manager/package.json | 6 +- contract_manager/src/utils/utils.ts | 91 +++++++++++++++++++ 6 files changed, 119 insertions(+), 79 deletions(-) delete mode 100644 apps/api-reference/src/evm-networks.ts create mode 100644 contract_manager/src/utils/utils.ts diff --git a/apps/api-reference/src/components/EvmApi/index.tsx b/apps/api-reference/src/components/EvmApi/index.tsx index 2aebfaa956..0fbacd593a 100644 --- a/apps/api-reference/src/components/EvmApi/index.tsx +++ b/apps/api-reference/src/components/EvmApi/index.tsx @@ -10,6 +10,7 @@ import { Label, } from "@headlessui/react"; import { ArrowPathIcon } from "@heroicons/react/24/outline"; +import { getEvmContractAddress } from "@pythnetwork/contract-manager/utils/utils"; import PythAbi from "@pythnetwork/pyth-sdk-solidity/abis/IPyth.json"; import PythErrorsAbi from "@pythnetwork/pyth-sdk-solidity/abis/PythErrors.json"; import { ChainIcon } from "connectkit"; @@ -29,7 +30,6 @@ import { ParameterInput } from "./parameter-input"; import type { EvmApiType } from "./run-button"; import { RunButton } from "./run-button"; import { getLogger } from "../../browser-logger"; -import { getContractAddress } from "../../evm-networks"; import { useIsMounted } from "../../use-is-mounted"; import type { SupportedLanguage } from "../Code"; import { Code } from "../Code"; @@ -251,7 +251,7 @@ export const EvmApi = ({ ? { name: currentChain.name, rpcUrl: currentChain.rpcUrls.default.http[0] ?? "", - contractAddress: getContractAddress(chainId) ?? "", + contractAddress: getEvmContractAddress(chainId, "priceFeed"), } : { name: "", rpcUrl: "", contractAddress: "" }, paramValues, @@ -294,7 +294,7 @@ const Example = ({ const updateValues = useCallback(() => { if (typeof example.parameters === "function") { setError(undefined); - const address = getContractAddress(config.state.chainId); + const address = getEvmContractAddress(config.state.chainId, "priceFeed"); if (!address) { throw new Error( `No contract for chain id: ${config.state.chainId.toString()}`, diff --git a/apps/api-reference/src/components/EvmApi/run-button.tsx b/apps/api-reference/src/components/EvmApi/run-button.tsx index c5313f3d22..acaf40698c 100644 --- a/apps/api-reference/src/components/EvmApi/run-button.tsx +++ b/apps/api-reference/src/components/EvmApi/run-button.tsx @@ -1,6 +1,7 @@ "use client"; import { ArrowPathIcon } from "@heroicons/react/24/outline"; +import { getEvmContractAddress } from "@pythnetwork/contract-manager/utils/utils"; import PythAbi from "@pythnetwork/pyth-sdk-solidity/abis/IPyth.json"; import PythErrorsAbi from "@pythnetwork/pyth-sdk-solidity/abis/PythErrors.json"; import { ConnectKitButton, Avatar } from "connectkit"; @@ -9,9 +10,9 @@ import { ContractFunctionExecutionError } from "viem"; import { useAccount, useConfig } from "wagmi"; import { readContract, simulateContract, writeContract } from "wagmi/actions"; + import type { Parameter } from "./parameter"; import { TRANSFORMS } from "./parameter"; -import { getContractAddress } from "../../evm-networks"; import { useIsMounted } from "../../use-is-mounted"; import { Button } from "../Button"; import { Code } from "../Code"; @@ -166,7 +167,7 @@ const useRunButton = ({ if (args === undefined) { setStatus(ErrorStatus(new Error("Invalid parameters!"))); } else { - const address = getContractAddress(config.state.chainId); + const address = getEvmContractAddress(config.state.chainId, "priceFeed"); if (!address) { throw new Error( `No contract for chain id: ${config.state.chainId.toString()}`, diff --git a/apps/api-reference/src/components/EvmProvider/index.tsx b/apps/api-reference/src/components/EvmProvider/index.tsx index b5aa2f67f5..6dba30c3d9 100644 --- a/apps/api-reference/src/components/EvmProvider/index.tsx +++ b/apps/api-reference/src/components/EvmProvider/index.tsx @@ -1,5 +1,6 @@ "use client"; +import { getEvmChainRpcUrl, getAllEvmChainsIds } from "@pythnetwork/contract-manager/utils/utils"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ConnectKitProvider, getDefaultConfig } from "connectkit"; import { useTheme } from "next-themes"; @@ -7,10 +8,10 @@ import type { ReactNode } from "react"; import * as chains from "viem/chains"; import { WagmiProvider, createConfig, http, useChainId } from "wagmi"; -import { NETWORK_IDS, getRpcUrl } from "../../evm-networks"; + import { metadata } from "../../metadata"; -const CHAINS = NETWORK_IDS.map((id) => +const CHAINS = getAllEvmChainsIds().map((id) => Object.values(chains).find((chain) => chain.id === id), ).filter((chain) => chain !== undefined) as unknown as readonly [ chains.Chain, @@ -18,18 +19,22 @@ const CHAINS = NETWORK_IDS.map((id) => ]; const TRANSPORTS = Object.fromEntries( - CHAINS.map((chain) => { - const rpcUrl = getRpcUrl(chain.id); - if (rpcUrl) { - return [chain.id, http(rpcUrl)]; - } else if (chain.rpcUrls.default.http[0]) { - return [chain.id, http(chain.rpcUrls.default.http[0])]; - } else { - throw new Error(`No rpc url found for ${chain.name}`); - } - }), + CHAINS.map((chain) => [chain.id, http(getEvmChainRpcUrl(chain.id))]), ); +// TODO: Remove this once we have a way to get the TRANSPORTS from the contract manager +// const chainEntries = await Promise.all( +// CHAINS.map(async (chain) => { +// const url = await getEvmChainRpcUrl(chain.id); +// return url ? [chain.id, http(url)] : undefined; +// }), +// ); + +// const TRANSPORTS = Object.fromEntries( +// chainEntries.filter((entry): entry is [number, ReturnType] => entry !== undefined) +// ) as Record>; + + type EvmProviderProps = { children: ReactNode; walletConnectProjectId?: string | undefined; diff --git a/apps/api-reference/src/evm-networks.ts b/apps/api-reference/src/evm-networks.ts deleted file mode 100644 index 1ee91a58f3..0000000000 --- a/apps/api-reference/src/evm-networks.ts +++ /dev/null @@ -1,61 +0,0 @@ -import * as EvmChains from "@pythnetwork/contract-manager/data/chains/EvmChains.json"; -import * as EvmPriceFeedContracts from "@pythnetwork/contract-manager/data/contracts/EvmPriceFeedContracts.json"; - -type EvmChains = { - id: string; - mainnet: boolean; - rpcUrl: string; - networkId: number; - type: string; - nativeToken?: string; -}; - -const getPriceFeedContractAddress = (chain: EvmChains) => { - const contractAddress = Object.values(EvmPriceFeedContracts).find( - (contract) => contract.chain === chain.id, - ); - return contractAddress?.address as `0x${string}`; -}; - -const mapEvmChainsToNetworkInfo = (chains: EvmChains[]) => { - const networkInfo: Record = {}; - - for (const chain of chains) { - const id = Number(chain.networkId); - networkInfo[id] = { - name: chain.id, - rpcUrl: chain.rpcUrl, - isMainnet: chain.mainnet, - contractAddress: getPriceFeedContractAddress(chain), - }; - } - - return networkInfo; -}; - -// Convert EvmChains to array format -const evmChainsArray = Object.values(EvmChains) as EvmChains[]; -export const NETWORK_INFO = mapEvmChainsToNetworkInfo(evmChainsArray); - -export const getContractAddress = (networkId: number) => - isSupportedNetwork(networkId) - ? NETWORK_INFO[networkId]?.contractAddress - : undefined; - -const isSupportedNetwork = ( - networkId: number, -): networkId is keyof typeof NETWORK_INFO => networkId in NETWORK_INFO; - -type NetworkInfo = { - name: string; - rpcUrl: string; - isMainnet: boolean; - contractAddress: `0x${string}`; -}; - -export const getRpcUrl = (networkId: number) => - isSupportedNetwork(networkId) ? NETWORK_INFO[networkId]?.rpcUrl : undefined; - -export const NETWORK_IDS = Object.keys(NETWORK_INFO).map((key) => - Number.parseInt(key, 10), -); diff --git a/contract_manager/package.json b/contract_manager/package.json index 66521eebb6..0e1efd1e6c 100644 --- a/contract_manager/package.json +++ b/contract_manager/package.json @@ -1,6 +1,6 @@ { "name": "@pythnetwork/contract-manager", - "version": "1.0.0", + "version": "1.0.1", "description": "Set of tools to manage pyth contracts", "private": true, "exports": { @@ -23,6 +23,10 @@ }, "./data/vaults/*.json": { "default": "./store/vaults/*.json" + }, + "./utils/*": { + "types": "./lib/utils/*.d.ts", + "default": "./lib/utils/*.js" } }, "files": [ diff --git a/contract_manager/src/utils/utils.ts b/contract_manager/src/utils/utils.ts new file mode 100644 index 0000000000..6c27b281aa --- /dev/null +++ b/contract_manager/src/utils/utils.ts @@ -0,0 +1,91 @@ +import Web3 from 'web3'; +import evmChainsData from '../../store/chains/EvmChains.json'; +import evmPriceFeedContractsData from '../../store/contracts/EvmPriceFeedContracts.json'; +import evmWormholeContractsData from '../../store/contracts/EvmWormholeContracts.json'; +import * as chains from "viem/chains"; + +export const getEvmContractAddress = (chainId: number, contractType: string): `0x${string}` => { + const chain = evmChainsData.find((c) => c.networkId === chainId); + if (!chain) { + throw new Error(`Chain with network ID ${chainId} not found`); + } + + if (contractType === 'priceFeed') { + const contract = evmPriceFeedContractsData.find((c) => c.chain === chain.id); + if (!contract) { + throw new Error(`Price feed contract not found for chain ${chainId}`); + } + return contract.address as `0x${string}`; + } + + if (contractType === 'wormhole') { + const contract = evmWormholeContractsData.find((c) => c.chain === chain.id); + if (!contract) { + throw new Error(`Wormhole contract not found for chain ${chainId}`); + } + return contract.address as `0x${string}`; + } + + throw new Error(`Unknown contract type: ${contractType}`); +} + +export const getAllEvmChainsIds = () => evmChainsData.map((c) => c.networkId); + + +// TODO: The below method should be used to get the RPC URL for a chain, but it is not working as expecte +// export const getEvmChainRpcUrl = async (chainId: number) => { +// const chain = evmChainsData.find((c) => c.networkId === chainId); +// if (!chain) { +// throw new Error(`Chain with network ID ${chainId} not found`); +// } + +// // Try JSON RPC URL first +// if (await checkRpcUrl(chain.rpcUrl)) { +// return chain.rpcUrl; +// } + +// // Fallback to viem chains +// const viemChain = Object.values(chains).find((c: any) => c.id === chain.id); +// if (viemChain && viemChain.rpcUrls && viemChain.rpcUrls.default) { +// const viemRpcUrl = viemChain.rpcUrls.default.http[0]; +// if (await checkRpcUrl(viemRpcUrl)) { +// return viemRpcUrl; +// } +// } + +// throw new Error(`No working RPC URL found for chain ${chainId}`); +// } + + +export const getEvmChainRpcUrl = (chainId: number) => { + const chain = evmChainsData.find((c) => c.networkId === chainId); + if (!chain) { + throw new Error(`Chain with network ID ${chainId} not found`); + } + + + // Let's try to use the viem chains without checking if they are working + const viemChain = Object.values(chains).find((c: any) => c.id === chain.id); + if (viemChain && viemChain.rpcUrls && viemChain.rpcUrls.default) { + const viemRpcUrl = viemChain.rpcUrls.default.http[0]; + return viemRpcUrl; + } + + // Now let's try to use the json rpc url + if (chain.rpcUrl) { + return chain.rpcUrl; + } + + throw new Error(`No working RPC URL found for chain ${chainId}`); +} + + +// const checkRpcUrl = (rpcUrl: string) => { +// const web3 = new Web3(rpcUrl); +// return web3.eth.getBlockNumber().then((blockNumber) => { +// return true; +// }).catch((error) => { +// console.error(`Error checking RPC URL ${rpcUrl}: ${error}`); +// return false; +// }); +// } \ No newline at end of file From 4535ac284ce30de17701bd960fac4d3b1b532836 Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Tue, 24 Jun 2025 16:30:03 -0400 Subject: [PATCH 04/11] update --- apps/api-reference/src/components/EvmApi/index.tsx | 5 ----- apps/api-reference/src/components/EvmApi/run-button.tsx | 5 ----- 2 files changed, 10 deletions(-) diff --git a/apps/api-reference/src/components/EvmApi/index.tsx b/apps/api-reference/src/components/EvmApi/index.tsx index 0fbacd593a..346274d928 100644 --- a/apps/api-reference/src/components/EvmApi/index.tsx +++ b/apps/api-reference/src/components/EvmApi/index.tsx @@ -295,11 +295,6 @@ const Example = ({ if (typeof example.parameters === "function") { setError(undefined); const address = getEvmContractAddress(config.state.chainId, "priceFeed"); - if (!address) { - throw new Error( - `No contract for chain id: ${config.state.chainId.toString()}`, - ); - } const params = example.parameters({ readContract: (functionName, args) => readContract(config, { abi, address, functionName, args }), diff --git a/apps/api-reference/src/components/EvmApi/run-button.tsx b/apps/api-reference/src/components/EvmApi/run-button.tsx index acaf40698c..bbf821a194 100644 --- a/apps/api-reference/src/components/EvmApi/run-button.tsx +++ b/apps/api-reference/src/components/EvmApi/run-button.tsx @@ -168,11 +168,6 @@ const useRunButton = ({ setStatus(ErrorStatus(new Error("Invalid parameters!"))); } else { const address = getEvmContractAddress(config.state.chainId, "priceFeed"); - if (!address) { - throw new Error( - `No contract for chain id: ${config.state.chainId.toString()}`, - ); - } switch (props.type) { case EvmApiType.Read: { readContract(config, { abi, address, functionName, args }) From 76f013e38169bc4802f0f90a4ebc82fd9d497984 Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Wed, 25 Jun 2025 14:58:03 -0400 Subject: [PATCH 05/11] udpate --- contract_manager/src/utils/utils.ts | 84 ++++++++--------------------- 1 file changed, 22 insertions(+), 62 deletions(-) diff --git a/contract_manager/src/utils/utils.ts b/contract_manager/src/utils/utils.ts index 6c27b281aa..49e672a764 100644 --- a/contract_manager/src/utils/utils.ts +++ b/contract_manager/src/utils/utils.ts @@ -1,74 +1,45 @@ -import Web3 from 'web3'; import evmChainsData from '../../store/chains/EvmChains.json'; import evmPriceFeedContractsData from '../../store/contracts/EvmPriceFeedContracts.json'; import evmWormholeContractsData from '../../store/contracts/EvmWormholeContracts.json'; import * as chains from "viem/chains"; -export const getEvmContractAddress = (chainId: number, contractType: string): `0x${string}` => { +export const getEvmPriceFeedContractAddress = (chainId: number): `0x${string}` | undefined => { const chain = evmChainsData.find((c) => c.networkId === chainId); if (!chain) { - throw new Error(`Chain with network ID ${chainId} not found`); + return undefined; } - - if (contractType === 'priceFeed') { - const contract = evmPriceFeedContractsData.find((c) => c.chain === chain.id); - if (!contract) { - throw new Error(`Price feed contract not found for chain ${chainId}`); - } - return contract.address as `0x${string}`; - } - - if (contractType === 'wormhole') { - const contract = evmWormholeContractsData.find((c) => c.chain === chain.id); - if (!contract) { - throw new Error(`Wormhole contract not found for chain ${chainId}`); - } - return contract.address as `0x${string}`; + const contract = evmPriceFeedContractsData.find((c) => c.chain === chain.id); + if (!contract?.address || !contract.address.startsWith('0x')) { + return undefined; } - - throw new Error(`Unknown contract type: ${contractType}`); + return contract.address as `0x${string}`; } -export const getAllEvmChainsIds = () => evmChainsData.map((c) => c.networkId); - - -// TODO: The below method should be used to get the RPC URL for a chain, but it is not working as expecte -// export const getEvmChainRpcUrl = async (chainId: number) => { -// const chain = evmChainsData.find((c) => c.networkId === chainId); -// if (!chain) { -// throw new Error(`Chain with network ID ${chainId} not found`); -// } - -// // Try JSON RPC URL first -// if (await checkRpcUrl(chain.rpcUrl)) { -// return chain.rpcUrl; -// } - -// // Fallback to viem chains -// const viemChain = Object.values(chains).find((c: any) => c.id === chain.id); -// if (viemChain && viemChain.rpcUrls && viemChain.rpcUrls.default) { -// const viemRpcUrl = viemChain.rpcUrls.default.http[0]; -// if (await checkRpcUrl(viemRpcUrl)) { -// return viemRpcUrl; -// } -// } - -// throw new Error(`No working RPC URL found for chain ${chainId}`); -// } +export const getEvmWormholeContractAddress = (chainId: number): `0x${string}` | undefined => { + const chain = evmChainsData.find((c) => c.networkId === chainId); + if (!chain) { + return undefined; + } + const contract = evmWormholeContractsData.find((c) => c.chain === chain.id); + if (!contract?.address || !contract.address.startsWith('0x')) { + return undefined; + } + return contract.address as `0x${string}`; +} +export const getAllEvmChainsIds: number[] = evmChainsData.map((c) => c.networkId); -export const getEvmChainRpcUrl = (chainId: number) => { +export const getEvmChainRpcUrl = (chainId: number): string | undefined => { const chain = evmChainsData.find((c) => c.networkId === chainId); if (!chain) { - throw new Error(`Chain with network ID ${chainId} not found`); + return undefined; } // Let's try to use the viem chains without checking if they are working const viemChain = Object.values(chains).find((c: any) => c.id === chain.id); if (viemChain && viemChain.rpcUrls && viemChain.rpcUrls.default) { - const viemRpcUrl = viemChain.rpcUrls.default.http[0]; - return viemRpcUrl; + return viemChain.rpcUrls.default.http[0]; } // Now let's try to use the json rpc url @@ -76,16 +47,5 @@ export const getEvmChainRpcUrl = (chainId: number) => { return chain.rpcUrl; } - throw new Error(`No working RPC URL found for chain ${chainId}`); + return undefined; } - - -// const checkRpcUrl = (rpcUrl: string) => { -// const web3 = new Web3(rpcUrl); -// return web3.eth.getBlockNumber().then((blockNumber) => { -// return true; -// }).catch((error) => { -// console.error(`Error checking RPC URL ${rpcUrl}: ${error}`); -// return false; -// }); -// } \ No newline at end of file From 76d907b0acc9723be5aecadcb102a0b05d716df3 Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Wed, 25 Jun 2025 15:07:41 -0400 Subject: [PATCH 06/11] update --- apps/api-reference/src/components/EvmApi/index.tsx | 10 +++++++--- .../api-reference/src/components/EvmProvider/index.tsx | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/api-reference/src/components/EvmApi/index.tsx b/apps/api-reference/src/components/EvmApi/index.tsx index 346274d928..77466ceb66 100644 --- a/apps/api-reference/src/components/EvmApi/index.tsx +++ b/apps/api-reference/src/components/EvmApi/index.tsx @@ -10,7 +10,7 @@ import { Label, } from "@headlessui/react"; import { ArrowPathIcon } from "@heroicons/react/24/outline"; -import { getEvmContractAddress } from "@pythnetwork/contract-manager/utils/utils"; +import { getEvmPriceFeedContractAddress } from "@pythnetwork/contract-manager/utils/utils"; import PythAbi from "@pythnetwork/pyth-sdk-solidity/abis/IPyth.json"; import PythErrorsAbi from "@pythnetwork/pyth-sdk-solidity/abis/PythErrors.json"; import { ChainIcon } from "connectkit"; @@ -251,7 +251,7 @@ export const EvmApi = ({ ? { name: currentChain.name, rpcUrl: currentChain.rpcUrls.default.http[0] ?? "", - contractAddress: getEvmContractAddress(chainId, "priceFeed"), + contractAddress: getEvmPriceFeedContractAddress(chainId) ?? "", } : { name: "", rpcUrl: "", contractAddress: "" }, paramValues, @@ -294,7 +294,11 @@ const Example = ({ const updateValues = useCallback(() => { if (typeof example.parameters === "function") { setError(undefined); - const address = getEvmContractAddress(config.state.chainId, "priceFeed"); + const address = getEvmPriceFeedContractAddress(config.state.chainId); + if (!address) { + setError("No contract address found for this chain"); + return; + } const params = example.parameters({ readContract: (functionName, args) => readContract(config, { abi, address, functionName, args }), diff --git a/apps/api-reference/src/components/EvmProvider/index.tsx b/apps/api-reference/src/components/EvmProvider/index.tsx index 6dba30c3d9..19bc006aba 100644 --- a/apps/api-reference/src/components/EvmProvider/index.tsx +++ b/apps/api-reference/src/components/EvmProvider/index.tsx @@ -11,7 +11,7 @@ import { WagmiProvider, createConfig, http, useChainId } from "wagmi"; import { metadata } from "../../metadata"; -const CHAINS = getAllEvmChainsIds().map((id) => +const CHAINS = getAllEvmChainsIds.map((id) => Object.values(chains).find((chain) => chain.id === id), ).filter((chain) => chain !== undefined) as unknown as readonly [ chains.Chain, From 5314c26e243a00b13d743d3c90ecd15ab233f06a Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Wed, 25 Jun 2025 16:50:27 -0400 Subject: [PATCH 07/11] update --- apps/api-reference/src/components/EvmApi/run-button.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/api-reference/src/components/EvmApi/run-button.tsx b/apps/api-reference/src/components/EvmApi/run-button.tsx index bbf821a194..524f1c79cf 100644 --- a/apps/api-reference/src/components/EvmApi/run-button.tsx +++ b/apps/api-reference/src/components/EvmApi/run-button.tsx @@ -1,7 +1,7 @@ "use client"; import { ArrowPathIcon } from "@heroicons/react/24/outline"; -import { getEvmContractAddress } from "@pythnetwork/contract-manager/utils/utils"; +import { getEvmPriceFeedContractAddress } from "@pythnetwork/contract-manager/utils/utils"; import PythAbi from "@pythnetwork/pyth-sdk-solidity/abis/IPyth.json"; import PythErrorsAbi from "@pythnetwork/pyth-sdk-solidity/abis/PythErrors.json"; import { ConnectKitButton, Avatar } from "connectkit"; @@ -167,7 +167,7 @@ const useRunButton = ({ if (args === undefined) { setStatus(ErrorStatus(new Error("Invalid parameters!"))); } else { - const address = getEvmContractAddress(config.state.chainId, "priceFeed"); + const address = getEvmPriceFeedContractAddress(config.state.chainId); switch (props.type) { case EvmApiType.Read: { readContract(config, { abi, address, functionName, args }) From 6cec3c9f1a7bf0fd4c150c11bdab534a5d88986d Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Wed, 25 Jun 2025 16:56:07 -0400 Subject: [PATCH 08/11] update --- .../src/components/EvmApi/index.tsx | 3 +- .../src/components/EvmApi/run-button.tsx | 1 - .../src/components/EvmProvider/index.tsx | 13 ++++--- contract_manager/src/utils/utils.ts | 39 +++++++++++-------- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/apps/api-reference/src/components/EvmApi/index.tsx b/apps/api-reference/src/components/EvmApi/index.tsx index 77466ceb66..f27692ad62 100644 --- a/apps/api-reference/src/components/EvmApi/index.tsx +++ b/apps/api-reference/src/components/EvmApi/index.tsx @@ -251,7 +251,8 @@ export const EvmApi = ({ ? { name: currentChain.name, rpcUrl: currentChain.rpcUrls.default.http[0] ?? "", - contractAddress: getEvmPriceFeedContractAddress(chainId) ?? "", + contractAddress: + getEvmPriceFeedContractAddress(chainId) ?? "", } : { name: "", rpcUrl: "", contractAddress: "" }, paramValues, diff --git a/apps/api-reference/src/components/EvmApi/run-button.tsx b/apps/api-reference/src/components/EvmApi/run-button.tsx index 524f1c79cf..52a4cb5d92 100644 --- a/apps/api-reference/src/components/EvmApi/run-button.tsx +++ b/apps/api-reference/src/components/EvmApi/run-button.tsx @@ -10,7 +10,6 @@ import { ContractFunctionExecutionError } from "viem"; import { useAccount, useConfig } from "wagmi"; import { readContract, simulateContract, writeContract } from "wagmi/actions"; - import type { Parameter } from "./parameter"; import { TRANSFORMS } from "./parameter"; import { useIsMounted } from "../../use-is-mounted"; diff --git a/apps/api-reference/src/components/EvmProvider/index.tsx b/apps/api-reference/src/components/EvmProvider/index.tsx index 19bc006aba..e211042fab 100644 --- a/apps/api-reference/src/components/EvmProvider/index.tsx +++ b/apps/api-reference/src/components/EvmProvider/index.tsx @@ -1,6 +1,9 @@ "use client"; -import { getEvmChainRpcUrl, getAllEvmChainsIds } from "@pythnetwork/contract-manager/utils/utils"; +import { + getEvmChainRpcUrl, + getAllEvmChainsIds, +} from "@pythnetwork/contract-manager/utils/utils"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ConnectKitProvider, getDefaultConfig } from "connectkit"; import { useTheme } from "next-themes"; @@ -8,12 +11,11 @@ import type { ReactNode } from "react"; import * as chains from "viem/chains"; import { WagmiProvider, createConfig, http, useChainId } from "wagmi"; - import { metadata } from "../../metadata"; -const CHAINS = getAllEvmChainsIds.map((id) => - Object.values(chains).find((chain) => chain.id === id), -).filter((chain) => chain !== undefined) as unknown as readonly [ +const CHAINS = getAllEvmChainsIds + .map((id) => Object.values(chains).find((chain) => chain.id === id)) + .filter((chain) => chain !== undefined) as unknown as readonly [ chains.Chain, ...chains.Chain[], ]; @@ -34,7 +36,6 @@ const TRANSPORTS = Object.fromEntries( // chainEntries.filter((entry): entry is [number, ReturnType] => entry !== undefined) // ) as Record>; - type EvmProviderProps = { children: ReactNode; walletConnectProjectId?: string | undefined; diff --git a/contract_manager/src/utils/utils.ts b/contract_manager/src/utils/utils.ts index 49e672a764..ecd8fe79e3 100644 --- a/contract_manager/src/utils/utils.ts +++ b/contract_manager/src/utils/utils.ts @@ -1,51 +1,58 @@ -import evmChainsData from '../../store/chains/EvmChains.json'; -import evmPriceFeedContractsData from '../../store/contracts/EvmPriceFeedContracts.json'; -import evmWormholeContractsData from '../../store/contracts/EvmWormholeContracts.json'; +import evmChainsData from "../../store/chains/EvmChains.json"; +import evmPriceFeedContractsData from "../../store/contracts/EvmPriceFeedContracts.json"; +import evmWormholeContractsData from "../../store/contracts/EvmWormholeContracts.json"; import * as chains from "viem/chains"; -export const getEvmPriceFeedContractAddress = (chainId: number): `0x${string}` | undefined => { +export const getEvmPriceFeedContractAddress = ( + chainId: number, +): `0x${string}` | undefined => { const chain = evmChainsData.find((c) => c.networkId === chainId); if (!chain) { return undefined; } const contract = evmPriceFeedContractsData.find((c) => c.chain === chain.id); - if (!contract?.address || !contract.address.startsWith('0x')) { + if (!contract?.address || !contract.address.startsWith("0x")) { return undefined; } return contract.address as `0x${string}`; -} +}; -export const getEvmWormholeContractAddress = (chainId: number): `0x${string}` | undefined => { +export const getEvmWormholeContractAddress = ( + chainId: number, +): `0x${string}` | undefined => { const chain = evmChainsData.find((c) => c.networkId === chainId); if (!chain) { return undefined; } const contract = evmWormholeContractsData.find((c) => c.chain === chain.id); - if (!contract?.address || !contract.address.startsWith('0x')) { + if (!contract?.address || !contract.address.startsWith("0x")) { return undefined; } return contract.address as `0x${string}`; -} +}; -export const getAllEvmChainsIds: number[] = evmChainsData.map((c) => c.networkId); +export const getAllEvmChainsIds: number[] = evmChainsData.map( + (c) => c.networkId, +); export const getEvmChainRpcUrl = (chainId: number): string | undefined => { const chain = evmChainsData.find((c) => c.networkId === chainId); if (!chain) { return undefined; } - - + // Let's try to use the viem chains without checking if they are working - const viemChain = Object.values(chains).find((c: any) => c.id === chain.id); + const viemChain = Object.values(chains).find( + (c) => c.id === Number(chain.id), + ); if (viemChain && viemChain.rpcUrls && viemChain.rpcUrls.default) { return viemChain.rpcUrls.default.http[0]; - } + } // Now let's try to use the json rpc url if (chain.rpcUrl) { return chain.rpcUrl; } - + return undefined; -} +}; From 8d325b6ede1071b854c7bf1ed19517d009f0026d Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Wed, 25 Jun 2025 17:02:02 -0400 Subject: [PATCH 09/11] removed comments --- .../src/components/EvmProvider/index.tsx | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/apps/api-reference/src/components/EvmProvider/index.tsx b/apps/api-reference/src/components/EvmProvider/index.tsx index e211042fab..f0a96ac9e5 100644 --- a/apps/api-reference/src/components/EvmProvider/index.tsx +++ b/apps/api-reference/src/components/EvmProvider/index.tsx @@ -24,18 +24,6 @@ const TRANSPORTS = Object.fromEntries( CHAINS.map((chain) => [chain.id, http(getEvmChainRpcUrl(chain.id))]), ); -// TODO: Remove this once we have a way to get the TRANSPORTS from the contract manager -// const chainEntries = await Promise.all( -// CHAINS.map(async (chain) => { -// const url = await getEvmChainRpcUrl(chain.id); -// return url ? [chain.id, http(url)] : undefined; -// }), -// ); - -// const TRANSPORTS = Object.fromEntries( -// chainEntries.filter((entry): entry is [number, ReturnType] => entry !== undefined) -// ) as Record>; - type EvmProviderProps = { children: ReactNode; walletConnectProjectId?: string | undefined; From d9793c48fd2f10c1a758f2a958364498a958dcb3 Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Thu, 26 Jun 2025 11:14:34 -0400 Subject: [PATCH 10/11] update --- apps/api-reference/src/components/EvmApi/run-button.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/api-reference/src/components/EvmApi/run-button.tsx b/apps/api-reference/src/components/EvmApi/run-button.tsx index 52a4cb5d92..ad697d19ae 100644 --- a/apps/api-reference/src/components/EvmApi/run-button.tsx +++ b/apps/api-reference/src/components/EvmApi/run-button.tsx @@ -167,6 +167,10 @@ const useRunButton = ({ setStatus(ErrorStatus(new Error("Invalid parameters!"))); } else { const address = getEvmPriceFeedContractAddress(config.state.chainId); + if (!address) { + setStatus(ErrorStatus(new Error("No address found!"))); + return; + } switch (props.type) { case EvmApiType.Read: { readContract(config, { abi, address, functionName, args }) From 325a91651bcfb9a6e750532574b25904a9a88a88 Mon Sep 17 00:00:00 2001 From: Aditya Arora Date: Thu, 26 Jun 2025 13:22:27 -0400 Subject: [PATCH 11/11] update --- .../src/components/EvmProvider/index.tsx | 4 +- contract_manager/src/utils/utils.ts | 64 +++++++++---------- 2 files changed, 32 insertions(+), 36 deletions(-) diff --git a/apps/api-reference/src/components/EvmProvider/index.tsx b/apps/api-reference/src/components/EvmProvider/index.tsx index f0a96ac9e5..4eee10fea2 100644 --- a/apps/api-reference/src/components/EvmProvider/index.tsx +++ b/apps/api-reference/src/components/EvmProvider/index.tsx @@ -2,7 +2,7 @@ import { getEvmChainRpcUrl, - getAllEvmChainsIds, + allEvmChainIds, } from "@pythnetwork/contract-manager/utils/utils"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ConnectKitProvider, getDefaultConfig } from "connectkit"; @@ -13,7 +13,7 @@ import { WagmiProvider, createConfig, http, useChainId } from "wagmi"; import { metadata } from "../../metadata"; -const CHAINS = getAllEvmChainsIds +const CHAINS = allEvmChainIds .map((id) => Object.values(chains).find((chain) => chain.id === id)) .filter((chain) => chain !== undefined) as unknown as readonly [ chains.Chain, diff --git a/contract_manager/src/utils/utils.ts b/contract_manager/src/utils/utils.ts index ecd8fe79e3..97f0844674 100644 --- a/contract_manager/src/utils/utils.ts +++ b/contract_manager/src/utils/utils.ts @@ -3,56 +3,52 @@ import evmPriceFeedContractsData from "../../store/contracts/EvmPriceFeedContrac import evmWormholeContractsData from "../../store/contracts/EvmWormholeContracts.json"; import * as chains from "viem/chains"; +export const allEvmChainIds: number[] = evmChainsData.map((c) => c.networkId); + export const getEvmPriceFeedContractAddress = ( chainId: number, ): `0x${string}` | undefined => { - const chain = evmChainsData.find((c) => c.networkId === chainId); - if (!chain) { - return undefined; - } - const contract = evmPriceFeedContractsData.find((c) => c.chain === chain.id); - if (!contract?.address || !contract.address.startsWith("0x")) { - return undefined; - } - return contract.address as `0x${string}`; + return getContractAddress(chainId, evmPriceFeedContractsData); }; export const getEvmWormholeContractAddress = ( chainId: number, +): `0x${string}` | undefined => { + return getContractAddress(chainId, evmWormholeContractsData); +}; + +const getContractAddress = ( + chainId: number, + contractsData: { chain: string; address: string }[], ): `0x${string}` | undefined => { const chain = evmChainsData.find((c) => c.networkId === chainId); - if (!chain) { - return undefined; - } - const contract = evmWormholeContractsData.find((c) => c.chain === chain.id); - if (!contract?.address || !contract.address.startsWith("0x")) { + if (chain === undefined) { return undefined; + } else { + const contract = contractsData.find((c) => c.chain === chain.id); + if (contract?.address === undefined) { + return undefined; + } else if (isZeroXString(contract.address)) { + return contract.address as `0x${string}`; + } else { + throw new Error( + `Invariant failed: invalid contract address ${contract.address} for chain ${contract.chain}`, + ); + } } - return contract.address as `0x${string}`; }; -export const getAllEvmChainsIds: number[] = evmChainsData.map( - (c) => c.networkId, -); +const isZeroXString = (str: string): str is `0x${string}` => + str.startsWith("0x") && str.length === 42; export const getEvmChainRpcUrl = (chainId: number): string | undefined => { const chain = evmChainsData.find((c) => c.networkId === chainId); - if (!chain) { + if (chain === undefined) { return undefined; + } else { + const viemChain = Object.values(chains).find( + (c) => c.id === Number.parseInt(chain.id, 10), + ); + return viemChain?.rpcUrls.default.http[0] ?? chain.rpcUrl; } - - // Let's try to use the viem chains without checking if they are working - const viemChain = Object.values(chains).find( - (c) => c.id === Number(chain.id), - ); - if (viemChain && viemChain.rpcUrls && viemChain.rpcUrls.default) { - return viemChain.rpcUrls.default.http[0]; - } - - // Now let's try to use the json rpc url - if (chain.rpcUrl) { - return chain.rpcUrl; - } - - return undefined; };