diff --git a/apps/web/configs/chains.tsx b/apps/web/configs/chains.tsx index 44ab6c53..477f7163 100644 --- a/apps/web/configs/chains.tsx +++ b/apps/web/configs/chains.tsx @@ -48,6 +48,7 @@ type ChainData = { confirmations: number; rpcUrl: string; subgraphUrl: string; + publishedSubgraphUrl?: string; globalTribunal?: Address; arbitrator: Address; passportScorer: Address; @@ -59,6 +60,21 @@ type ChainData = { const SUBGRAPH_TESTNET_VERSION = Subgraph.VERSION_TESTNET; const SUBGRAPH_PRODNET_VERSION = Subgraph.VERSION_PROD; +const getSubgraphUrls = ( + publishedId: string, + subgraphSlug: string, + subgraphVersion: string, +) => { + const versionedEndpoint = `https://api.studio.thegraph.com/query/70985/${subgraphSlug}`; + return { + publishedSubgraphUrl: + process.env.NEXT_PUBLIC_SUBGRAPH_KEY ? + `https://gateway.thegraph.com/api/${process.env.NEXT_PUBLIC_SUBGRAPH_KEY}/subgraphs/id/${publishedId}` + : undefined, + subgraphUrl: `${versionedEndpoint}/${subgraphVersion}`, + }; +}; + export const chainConfigMap: { [key: number | string]: ChainData; } = { @@ -84,27 +100,31 @@ export const chainConfigMap: { blockTime: 14, confirmations: 7, rpcUrl: process.env.RPC_URL_ARB_TESTNET!, - subgraphUrl: `${process.env.NEXT_PUBLIC_SUBGRAPH_URL_ARB_SEP?.replace("/version/latest", "")}/${SUBGRAPH_TESTNET_VERSION}`, + ...getSubgraphUrls( + "BfZYwhZ1rTb22Nah1u6YyXtUtAdgGNtZhW1EBb4mFzAU", + "gardens-v2---arbitrum-sepolia", + SUBGRAPH_TESTNET_VERSION, + ), globalTribunal: "0xb05A948B5c1b057B88D381bDe3A375EfEA87EbAD", allo: "0x1133eA7Af70876e64665ecD07C0A0476d09465a1", arbitrator: "0xe32566076534973ff78b512ec6a321a58c2b735c", passportScorer: "0xfF53a163e43EccC00d8FdE7acA24aa9FA4da7356", isTestnet: true, }, - 11155111: { - name: sepolia.name, - icon: Ethereum, - explorer: "https://eth-sepolia.blockscout.com", - blockTime: 12, - confirmations: 1, // 3 - rpcUrl: process.env.RPC_URL_ETH_TESTNET!, - subgraphUrl: `${process.env.NEXT_PUBLIC_SUBGRAPH_URL_ETH_SEP?.replace("/version/latest", "")}/${SUBGRAPH_TESTNET_VERSION}`, - globalTribunal: "0xc6Eaf449f79B081300F5317122B2Dff3f039ad0b", - allo: "0x1133eA7Af70876e64665ecD07C0A0476d09465a1", - arbitrator: "0x", - passportScorer: "0xc137c30ac0f21ce75bb484e88fb8701024f82d25", - isTestnet: true, - }, + // 11155111: { + // name: sepolia.name, + // icon: Ethereum, + // explorer: "https://eth-sepolia.blockscout.com", + // blockTime: 12, + // confirmations: 1, // 3 + // rpcUrl: process.env.RPC_URL_ETH_TESTNET!, + // subgraphUrl: `${process.env.NEXT_PUBLIC_SUBGRAPH_URL_ETH_SEP?.replace("/version/latest", "")}/${SUBGRAPH_TESTNET_VERSION}`, + // globalTribunal: "0xc6Eaf449f79B081300F5317122B2Dff3f039ad0b", + // allo: "0x1133eA7Af70876e64665ecD07C0A0476d09465a1", + // arbitrator: "0x", + // passportScorer: "0xc137c30ac0f21ce75bb484e88fb8701024f82d25", + // isTestnet: true, + // }, // 11155420: { // name: optimismSepolia.name, // icon: Optimism, @@ -122,7 +142,11 @@ export const chainConfigMap: { blockTime: 14, confirmations: 7, // 7 rpcUrl: process.env.RPC_URL_ARBITRUM!, - subgraphUrl: `${process.env.NEXT_PUBLIC_SUBGRAPH_URL_ARBITRUM?.replace("/version/latest", "")}/${SUBGRAPH_PRODNET_VERSION}`, + ...getSubgraphUrls( + "4vsznmRkUGm9DZFBwvC6PDvGPVfVLQcUUr5ExdTNZiUc", + "gardens-v2---arbitrum", + SUBGRAPH_PRODNET_VERSION, + ), globalTribunal: "0x1b8c7f06f537711a7caf6770051a43b4f3e69a7e", allo: "0x1133eA7Af70876e64665ecD07C0A0476d09465a1", arbitrator: "0xd58ff588177f02cc535a0e235a4c002a17e27202", @@ -137,7 +161,11 @@ export const chainConfigMap: { blockTime: 14, confirmations: 2, // 2 rpcUrl: process.env.RPC_URL_OPTIMISM!, - subgraphUrl: `${process.env.NEXT_PUBLIC_SUBGRAPH_URL_OPTIMISM?.replace("/version/latest", "")}/${SUBGRAPH_PRODNET_VERSION}`, + ...getSubgraphUrls( + "4vsznmRkUGm9DZFBwvC6PDvGPVfVLQcUUr5ExdTNZiUc", + "gardens-v2---optimism", + SUBGRAPH_PRODNET_VERSION, + ), globalTribunal: "0x1B8C7f06F537711A7CAf6770051A43B4F3E69A7e", allo: "0x1133eA7Af70876e64665ecD07C0A0476d09465a1", arbitrator: "0xb39dfa15f96055664179e8ecaa890f3fa26c21e9", @@ -152,7 +180,11 @@ export const chainConfigMap: { blockTime: 2.1, confirmations: 4, // 4 rpcUrl: process.env.RPC_URL_MATIC!, - subgraphUrl: `${process.env.NEXT_PUBLIC_SUBGRAPH_URL_MATIC?.replace("/version/latest", "")}/${SUBGRAPH_PRODNET_VERSION}`, + ...getSubgraphUrls( + "4vsznmRkUGm9DZFBwvC6PDvGPVfVLQcUUr5ExdTNZiUc", + "gardens-v2---polygon", + SUBGRAPH_PRODNET_VERSION, + ), globalTribunal: "0x1B8C7f06F537711A7CAf6770051A43B4F3E69A7e", allo: "0x1133eA7Af70876e64665ecD07C0A0476d09465a1", arbitrator: "0x7842e2d0dda2e64727c251382e9b1ee70fa33b94", @@ -167,7 +199,11 @@ export const chainConfigMap: { blockTime: 5.2, confirmations: 4, // 4 rpcUrl: process.env.RPC_URL_GNOSIS!, - subgraphUrl: `${process.env.NEXT_PUBLIC_SUBGRAPH_URL_GNOSIS?.replace("/version/latest", "")}/${SUBGRAPH_PRODNET_VERSION}`, + ...getSubgraphUrls( + "ELGHrYhvJJQrYkVsYWS5iDuFpQ1p834Q2k2kBmUAVZAi", + "gardens-v2---gnosis", + SUBGRAPH_PRODNET_VERSION, + ), globalTribunal: "0x1B8C7f06F537711A7CAf6770051A43B4F3E69A7e", allo: "0x1133eA7Af70876e64665ecD07C0A0476d09465a1", arbitrator: "0x450967c1497ab95df8530a9a8eaae5e951171dee", @@ -191,30 +227,6 @@ export const chainConfigMap: { // }, }; -// export const chainConfigMap: { [key: number | string]: ChainData } = {}; - -// Fill deployed contract addresses -// Promise.all( -// chains.map(async (chain) => { -// const latestContracts = getRunLatestAddrs(chain.id); -// if (!latestContracts) { -// throw new Error(`No contract addresses found for chain ${chain.id}`); -// } -// const network = networks.find((x) => x.chainId === +chain.id); -// if (!network) { -// console.error(`No network found for chain ${chain.id}`); -// } else { -// chainConfigMap[chain.id] = { -// ...chainDataMapWithoutContracts[chain.id], -// allo: network.ENVS.ALLO_PROXY as Address, -// passportScorer: latestContracts.proxyPassportScorer as Address, -// arbitrator: latestContracts.proxySafeArbitrator as Address, -// isTestnet: network.testnet, -// }; -// } -// }), -// ).then(() => console.debug("Contracts addresses loaded")); - export function getConfigByChain(chainId: ChainId): ChainData | undefined { if (chainId in chainConfigMap) { return chainConfigMap[chainId]; diff --git a/apps/web/hooks/useSubgraphQuery.ts b/apps/web/hooks/useSubgraphQuery.ts index 3f712a3b..9a12f075 100644 --- a/apps/web/hooks/useSubgraphQuery.ts +++ b/apps/web/hooks/useSubgraphQuery.ts @@ -121,12 +121,29 @@ export function useSubgraphQuery< value?.toLowerCase() : value; }); - const res = await urqlClient.query(query, variables, { - ...context, - url: config?.subgraphUrl, - requestPolicy: "network-only", - }); - return modifier && res.data ? { ...res, data: modifier(res.data) } : res; + + const urqlQuery = (skipPublished: boolean) => + urqlClient.query(query, variables, { + ...context, + url: + skipPublished || !config?.publishedSubgraphUrl ? + config?.subgraphUrl + : config?.publishedSubgraphUrl, + requestPolicy: "network-only", + }); + + let res; + try { + res = await urqlQuery(false); + } catch (err1) { + console.error( + "⚡ Error fetching through published subgraph, retrying with hosted:", + err1, + ); + res = await urqlQuery(true); + } + + return modifier && res?.data ? { ...res, data: modifier(res.data) } : res; }; const refetchFromOutside = async () => { diff --git a/apps/web/hooks/useSubgraphQueryMultiChain.ts b/apps/web/hooks/useSubgraphQueryMultiChain.ts index a63b2e20..7e11030e 100644 --- a/apps/web/hooks/useSubgraphQueryMultiChain.ts +++ b/apps/web/hooks/useSubgraphQueryMultiChain.ts @@ -105,11 +105,11 @@ export function useSubgraphQueryMultiChain< const chainSubgraphs = (chainsOverride ?? chainIds ?? allChains).map( (chain) => ({ chainId: +chain, - url: getConfigByChain(chain)?.subgraphUrl, + chainConfig: getConfigByChain(chain), }), ); await Promise.all( - chainSubgraphs.map(async ({ chainId, url }, i) => { + chainSubgraphs.map(async ({ chainId, chainConfig }, i) => { const fetchSubgraphChain = async (retryCount?: number) => { if (!retryCount && retryOnNoChange) { retryCount = 0; @@ -124,19 +124,31 @@ export function useSubgraphQueryMultiChain< }); } try { - const fetchQuery = async () => { + const fetchQuery = async (skipPublished: boolean) => { const { urqlClient } = initUrqlClient({ chainId: (chainsOverride ?? allChains)[i], }); return urqlClient.query(query, variables, { ...queryContext, - url, + url: + skipPublished || !chainConfig?.publishedSubgraphUrl ? + chainConfig?.subgraphUrl + : chainConfig?.publishedSubgraphUrl, chainId, requestPolicy: "network-only", } as OperationContext & { _instance: any }); }; - const res = await fetchQuery(); + let res; + try { + res = await fetchQuery(false); + } catch (err1) { + console.error( + "⚡ Error fetching through published subgraph, retrying with hosted:", + err1, + ); + res = await fetchQuery(true); + } if (res.error) { errorsMap.current.set(chainId, res.error); diff --git a/apps/web/providers/urql.tsx b/apps/web/providers/urql.tsx index 740bc443..80f89b52 100644 --- a/apps/web/providers/urql.tsx +++ b/apps/web/providers/urql.tsx @@ -18,7 +18,7 @@ let urqlRecord: Record< const isServer = typeof window === "undefined"; //Subgraph URL -const subgraphArbSepURL = process.env.NEXT_PUBLIC_SUBGRAPH_URL_ARB_SEP ?? ""; +const subgraphArbSepURL = getConfigByChain(421614)!.subgraphUrl; /** * Function to initialize urql client. can be used both on client and server