From 7a1e0871a5835e002554a2ea839e91723e409d50 Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Thu, 17 Apr 2025 10:45:27 +0200 Subject: [PATCH 1/5] feat(payment-detection): option to use TheGraph Network with API key --- .../payment-detection/src/thegraph/client.ts | 59 ++++++++++++++++--- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/packages/payment-detection/src/thegraph/client.ts b/packages/payment-detection/src/thegraph/client.ts index 7b9d9b196..3353007b6 100644 --- a/packages/payment-detection/src/thegraph/client.ts +++ b/packages/payment-detection/src/thegraph/client.ts @@ -2,13 +2,15 @@ import { CurrencyTypes } from '@requestnetwork/types'; import { NearChains } from '@requestnetwork/currency'; import { GraphQLClient } from 'graphql-request'; -import { Block_Height, Maybe, getSdk } from './generated/graphql'; +import { Block_Height, getSdk, Maybe } from './generated/graphql'; import { getSdk as getNearSdk } from './generated/graphql-near'; import { RequestConfig } from 'graphql-request/src/types'; const THE_GRAPH_STUDIO_URL = 'https://api.studio.thegraph.com/query/67444/request-payments-$NETWORK/version/latest'; +const THE_GRAPH_EXPLORER_URL = 'https://gateway.thegraph.com/api/$API_KEY/subgraphs/id/$NETWORK'; + const THE_GRAPH_ALCHEMY_URL = 'https://subgraph.satsuma-prod.com/e2e4905ab7c8/request-network--434873/request-payments-$NETWORK/api'; @@ -21,6 +23,26 @@ const THE_GRAPH_URL_MANTLE = const THE_GRAPH_URL_CORE = 'https://thegraph.coredao.org/subgraphs/name/requestnetwork/request-payments-core'; +const THE_GRAPH_EXPLORER_SUBGRAPH_ID = { + mainnet: '5mXPGZRC2Caynh4NyVrTK72DAGB9dfcKmLsnxYWHQ9nd', + sepolia: '6e8Dcwt3cvsgNU3JYBtRQQ9Sj4P9VVVnXaPjJ3jUpYpY', + ['arbitrum-one']: '3MtDdHbzvBVNBpzUTYXGuDDLgTd1b8bPYwoH1Hdssgp9', + avalanche: 'A27V4PeZdKHeyuBkehdBJN8cxNtzVpXvYoqkjHUHRCFp', + base: 'CcTtKy6BustyyVZ5XvFD4nLnbkgMBT1vcAEJ3sAx6bRe', + bsc: '4PScFUi3CFDbop9XzT6gCDtD4RR8kRzyrzSjrHoXHZBt', + celo: '5ts3PHjMcH2skCgKtvLLNE64WLjbhE5ipruvEcgqyZqC', + fantom: '6AwmiYo5eY36W526ZDQeAkNBjXjXKYcMLYyYHeM67xAb', + fuse: 'EHSpUBa7PAewX7WsaU2jbCKowF5it56yStr6Zgf8aDtx', + matic: 'DPpU1WMxk2Z4H2TAqgwGbVBGpabjbC1972Mynak5jSuR', + moonbeam: '4Jo3DwA25zyVLeDhyi7cks52dNrkVCWWhQJzm1hKnCfj', + near: '9yEg3h46CZiv4VuSqo1erMMBx5sHxRuW5Ai2V8goSpQL', + ['near-testnet']: 'AusVyfndonsMVFrVzckuENLqx8t6kcXuxn6C6VbSGd7M', + optimism: '525fra79nG3Z1w8aPZh3nHsH5zCVetrVmceB1hKcTrTX', + xdai: '2UAW7B94eeeqaL5qUM5FDzTWJcmgA6ta1RcWMo3XuLmU', + zksyncera: 'HJNZW9vRSGXrcCVyQMdNKxxuLKeZcV6yMjTCyY6T2oon', + sonic: 'CQbtmuANYsChysuXTk9jWP3BD4ArncARVVw1b8JpHiTk', +} as const satisfies Partial>; + // NB: the GraphQL client is automatically generated based on files present in ./queries, // using graphql-codegen. // To generate types, run `yarn codegen`, then open the generated files so that the code editor picks up the changes. @@ -44,6 +66,8 @@ export type TheGraphQueryOptions = { export type TheGraphClientOptions = RequestConfig & { /** constraint to select indexers that have at least parsed this block */ minIndexedBlock?: number | undefined; + /** API key for accessing subgraphs hosted on TheGraph Explorer */ + theGraphExplorerApiKey?: string; }; /** Splits the input options into "client options" to pass to the SDK, and "query options" to use in queries */ @@ -55,7 +79,13 @@ const extractClientOptions = ( // build query options const queryOptions: TheGraphQueryOptions = {}; - const { minIndexedBlock, ...clientOptions } = optionsObject; + const { + minIndexedBlock, + // ignore theGraphExplorerApiKey, it should not be part of clientOptions + // eslint-disable-next-line @typescript-eslint/no-unused-vars + theGraphExplorerApiKey: _theGraphExplorerApiKey, + ...clientOptions + } = optionsObject; if (minIndexedBlock) { queryOptions.blockFilter = { number_gte: minIndexedBlock }; } else if (url.match(/^https:\/\/gateway-\w+\.network\.thegraph\.com\//)) { @@ -94,19 +124,32 @@ export const defaultGetTheGraphClient = ( network: CurrencyTypes.ChainName, options?: TheGraphClientOptions, ) => { + const filteredNetwork = network.replace('aurora', 'near'); + const theGraphStudioUrl = THE_GRAPH_STUDIO_URL.replace('$NETWORK', filteredNetwork); + const theGraphExplorerUrl = THE_GRAPH_EXPLORER_URL.replace( + '$API_KEY', + options?.theGraphExplorerApiKey || '', + ).replace('$NETWORK', filteredNetwork); + const theGraphAlchemyUrl = THE_GRAPH_ALCHEMY_URL.replace('$NETWORK', filteredNetwork); + + const shouldUseTheGraphExplorer = + !!options?.theGraphExplorerApiKey && + Object.keys(THE_GRAPH_EXPLORER_SUBGRAPH_ID).includes(network); + return network === 'private' ? undefined : NearChains.isChainSupported(network) - ? getTheGraphNearClient( - `${THE_GRAPH_STUDIO_URL.replace('$NETWORK', network.replace('aurora', 'near'))}`, - options, - ) + ? shouldUseTheGraphExplorer + ? getTheGraphEvmClient(theGraphExplorerUrl, options) + : getTheGraphNearClient(theGraphStudioUrl, options) : network === 'mantle' ? getTheGraphEvmClient(THE_GRAPH_URL_MANTLE, options) : network === 'mantle-testnet' ? getTheGraphEvmClient(THE_GRAPH_URL_MANTLE_TESTNET, options) : network === 'core' ? getTheGraphEvmClient(THE_GRAPH_URL_CORE, options) + : shouldUseTheGraphExplorer + ? getTheGraphEvmClient(theGraphExplorerUrl, options) : network === 'mainnet' || network === 'sepolia' || network === 'matic' || @@ -117,6 +160,6 @@ export const defaultGetTheGraphClient = ( network === 'zksyncera' || network === 'avalanche' || network === 'fantom' - ? getTheGraphEvmClient(`${THE_GRAPH_ALCHEMY_URL.replace('$NETWORK', network)}`, options) - : getTheGraphEvmClient(`${THE_GRAPH_STUDIO_URL.replace('$NETWORK', network)}`, options); + ? getTheGraphEvmClient(theGraphAlchemyUrl, options) + : getTheGraphEvmClient(theGraphStudioUrl, options); }; From 6c1f34463707f617a4ab7425c0115596135c9a25 Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Thu, 17 Apr 2025 11:14:25 +0200 Subject: [PATCH 2/5] add tests --- package.json | 3 +- .../payment-detection/src/thegraph/client.ts | 82 +++++++++++-------- .../test/thegraph/client.test.ts | 46 +++++++++++ 3 files changed, 96 insertions(+), 35 deletions(-) create mode 100644 packages/payment-detection/test/thegraph/client.test.ts diff --git a/package.json b/package.json index 9f1cc06fa..b10de3333 100644 --- a/package.json +++ b/package.json @@ -69,5 +69,6 @@ "semver": "https://github.com/RequestNetwork/requestNetwork/security/dependabot/197", "json-schema": "https://github.com/RequestNetwork/requestNetwork/security/dependabot/51", "json5": "https://github.com/RequestNetwork/requestNetwork/security/dependabot/165" - } + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/packages/payment-detection/src/thegraph/client.ts b/packages/payment-detection/src/thegraph/client.ts index 3353007b6..22f2ab0e8 100644 --- a/packages/payment-detection/src/thegraph/client.ts +++ b/packages/payment-detection/src/thegraph/client.ts @@ -9,7 +9,8 @@ import { RequestConfig } from 'graphql-request/src/types'; const THE_GRAPH_STUDIO_URL = 'https://api.studio.thegraph.com/query/67444/request-payments-$NETWORK/version/latest'; -const THE_GRAPH_EXPLORER_URL = 'https://gateway.thegraph.com/api/$API_KEY/subgraphs/id/$NETWORK'; +const THE_GRAPH_EXPLORER_URL = + 'https://gateway.thegraph.com/api/$API_KEY/subgraphs/id/$SUBGRAPH_ID'; const THE_GRAPH_ALCHEMY_URL = 'https://subgraph.satsuma-prod.com/e2e4905ab7c8/request-network--434873/request-payments-$NETWORK/api'; @@ -23,9 +24,20 @@ const THE_GRAPH_URL_MANTLE = const THE_GRAPH_URL_CORE = 'https://thegraph.coredao.org/subgraphs/name/requestnetwork/request-payments-core'; -const THE_GRAPH_EXPLORER_SUBGRAPH_ID = { - mainnet: '5mXPGZRC2Caynh4NyVrTK72DAGB9dfcKmLsnxYWHQ9nd', - sepolia: '6e8Dcwt3cvsgNU3JYBtRQQ9Sj4P9VVVnXaPjJ3jUpYpY', +const THE_GRAPH_ALCHEMY_CHAINS: CurrencyTypes.ChainName[] = [ + 'arbitrum-one', + 'avalanche', + 'base', + 'bsc', + 'fantom', + 'mainnet', + 'matic', + 'sepolia', + 'optimism', + 'zksyncera', +]; + +const THE_GRAPH_EXPLORER_SUBGRAPH_ID: Partial> = { ['arbitrum-one']: '3MtDdHbzvBVNBpzUTYXGuDDLgTd1b8bPYwoH1Hdssgp9', avalanche: 'A27V4PeZdKHeyuBkehdBJN8cxNtzVpXvYoqkjHUHRCFp', base: 'CcTtKy6BustyyVZ5XvFD4nLnbkgMBT1vcAEJ3sAx6bRe', @@ -33,15 +45,17 @@ const THE_GRAPH_EXPLORER_SUBGRAPH_ID = { celo: '5ts3PHjMcH2skCgKtvLLNE64WLjbhE5ipruvEcgqyZqC', fantom: '6AwmiYo5eY36W526ZDQeAkNBjXjXKYcMLYyYHeM67xAb', fuse: 'EHSpUBa7PAewX7WsaU2jbCKowF5it56yStr6Zgf8aDtx', + mainnet: '5mXPGZRC2Caynh4NyVrTK72DAGB9dfcKmLsnxYWHQ9nd', matic: 'DPpU1WMxk2Z4H2TAqgwGbVBGpabjbC1972Mynak5jSuR', moonbeam: '4Jo3DwA25zyVLeDhyi7cks52dNrkVCWWhQJzm1hKnCfj', + sepolia: '6e8Dcwt3cvsgNU3JYBtRQQ9Sj4P9VVVnXaPjJ3jUpYpY', + sonic: 'CQbtmuANYsChysuXTk9jWP3BD4ArncARVVw1b8JpHiTk', near: '9yEg3h46CZiv4VuSqo1erMMBx5sHxRuW5Ai2V8goSpQL', ['near-testnet']: 'AusVyfndonsMVFrVzckuENLqx8t6kcXuxn6C6VbSGd7M', optimism: '525fra79nG3Z1w8aPZh3nHsH5zCVetrVmceB1hKcTrTX', xdai: '2UAW7B94eeeqaL5qUM5FDzTWJcmgA6ta1RcWMo3XuLmU', zksyncera: 'HJNZW9vRSGXrcCVyQMdNKxxuLKeZcV6yMjTCyY6T2oon', - sonic: 'CQbtmuANYsChysuXTk9jWP3BD4ArncARVVw1b8JpHiTk', -} as const satisfies Partial>; +}; // NB: the GraphQL client is automatically generated based on files present in ./queries, // using graphql-codegen. @@ -120,7 +134,7 @@ export const getTheGraphNearClient = (url: string, options?: TheGraphClientOptio return sdk; }; -export const defaultGetTheGraphClient = ( +export const defaultGetTheGraphClientUrl = ( network: CurrencyTypes.ChainName, options?: TheGraphClientOptions, ) => { @@ -129,37 +143,37 @@ export const defaultGetTheGraphClient = ( const theGraphExplorerUrl = THE_GRAPH_EXPLORER_URL.replace( '$API_KEY', options?.theGraphExplorerApiKey || '', - ).replace('$NETWORK', filteredNetwork); + ).replace('$SUBGRAPH_ID', THE_GRAPH_EXPLORER_SUBGRAPH_ID[network] || ''); const theGraphAlchemyUrl = THE_GRAPH_ALCHEMY_URL.replace('$NETWORK', filteredNetwork); const shouldUseTheGraphExplorer = !!options?.theGraphExplorerApiKey && Object.keys(THE_GRAPH_EXPLORER_SUBGRAPH_ID).includes(network); - return network === 'private' - ? undefined - : NearChains.isChainSupported(network) - ? shouldUseTheGraphExplorer - ? getTheGraphEvmClient(theGraphExplorerUrl, options) - : getTheGraphNearClient(theGraphStudioUrl, options) - : network === 'mantle' - ? getTheGraphEvmClient(THE_GRAPH_URL_MANTLE, options) - : network === 'mantle-testnet' - ? getTheGraphEvmClient(THE_GRAPH_URL_MANTLE_TESTNET, options) - : network === 'core' - ? getTheGraphEvmClient(THE_GRAPH_URL_CORE, options) - : shouldUseTheGraphExplorer - ? getTheGraphEvmClient(theGraphExplorerUrl, options) - : network === 'mainnet' || - network === 'sepolia' || - network === 'matic' || - network === 'bsc' || - network === 'optimism' || - network === 'arbitrum-one' || - network === 'base' || - network === 'zksyncera' || - network === 'avalanche' || - network === 'fantom' - ? getTheGraphEvmClient(theGraphAlchemyUrl, options) - : getTheGraphEvmClient(theGraphStudioUrl, options); + switch (true) { + case network === 'private': + return; + case network === 'mantle': + return THE_GRAPH_URL_MANTLE; + case network === 'mantle-testnet': + return THE_GRAPH_URL_MANTLE_TESTNET; + case network === 'core': + return THE_GRAPH_URL_CORE; + default: + return shouldUseTheGraphExplorer + ? theGraphExplorerUrl + : THE_GRAPH_ALCHEMY_CHAINS.includes(network) + ? theGraphAlchemyUrl + : theGraphStudioUrl; + } +}; + +export const defaultGetTheGraphClient = ( + network: CurrencyTypes.ChainName, + options?: TheGraphClientOptions, +) => { + const url = defaultGetTheGraphClientUrl(network, options); + if (!url) return; + if (NearChains.isChainSupported(network)) return getTheGraphNearClient(url, options); + return getTheGraphEvmClient(url, options); }; diff --git a/packages/payment-detection/test/thegraph/client.test.ts b/packages/payment-detection/test/thegraph/client.test.ts new file mode 100644 index 000000000..d0042ecde --- /dev/null +++ b/packages/payment-detection/test/thegraph/client.test.ts @@ -0,0 +1,46 @@ +import { defaultGetTheGraphClientUrl } from '../../src/thegraph'; + +describe('defaultGetTheGraphClientUrl', () => { + it('should build the correct URL for network supported by Alchemy', () => { + const url = defaultGetTheGraphClientUrl('base'); + expect(url).toBe( + 'https://subgraph.satsuma-prod.com/e2e4905ab7c8/request-network--434873/request-payments-base/api', + ); + }); + it('should build the correct URL when using TheGraph Explorer API key', () => { + const url = defaultGetTheGraphClientUrl('base', { theGraphExplorerApiKey: 'test' }); + expect(url).toBe( + 'https://gateway.thegraph.com/api/test/subgraphs/id/CcTtKy6BustyyVZ5XvFD4nLnbkgMBT1vcAEJ3sAx6bRe', + ); + }); + it('should build the correct URL for Mantle', () => { + const url = defaultGetTheGraphClientUrl('mantle'); + expect(url).toBe( + 'https://subgraph-api.mantle.xyz/api/public/555176e7-c1f4-49f9-9180-f2f03538b039/subgraphs/requestnetwork/request-payments-mantle/v0.1.0/gn', + ); + }); + it('should build the correct URL for Near', () => { + const urlNear = defaultGetTheGraphClientUrl('near'); + expect(urlNear).toBe( + 'https://api.studio.thegraph.com/query/67444/request-payments-near/version/latest', + ); + const urlNearTestnet = defaultGetTheGraphClientUrl('near-testnet'); + expect(urlNearTestnet).toBe( + 'https://api.studio.thegraph.com/query/67444/request-payments-near-testnet/version/latest', + ); + const urlAurora = defaultGetTheGraphClientUrl('aurora'); + expect(urlAurora).toBe( + 'https://api.studio.thegraph.com/query/67444/request-payments-near/version/latest', + ); + const urlAuroraTestnet = defaultGetTheGraphClientUrl('aurora-testnet'); + expect(urlAuroraTestnet).toBe( + 'https://api.studio.thegraph.com/query/67444/request-payments-near-testnet/version/latest', + ); + }); + it('should build the correct URL for Near with TheGraph Explorer API key', () => { + const url = defaultGetTheGraphClientUrl('near', { theGraphExplorerApiKey: 'test' }); + expect(url).toBe( + 'https://gateway.thegraph.com/api/test/subgraphs/id/9yEg3h46CZiv4VuSqo1erMMBx5sHxRuW5Ai2V8goSpQL', + ); + }); +}); From f413833cbf55c159812bf1ce4c637245cc27191b Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Thu, 17 Apr 2025 11:15:14 +0200 Subject: [PATCH 3/5] remove corepack field --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index b10de3333..9f1cc06fa 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,5 @@ "semver": "https://github.com/RequestNetwork/requestNetwork/security/dependabot/197", "json-schema": "https://github.com/RequestNetwork/requestNetwork/security/dependabot/51", "json5": "https://github.com/RequestNetwork/requestNetwork/security/dependabot/165" - }, - "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" + } } From f09c643134de0d831ba7ba6cf3478398fde0931b Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Thu, 17 Apr 2025 11:26:07 +0200 Subject: [PATCH 4/5] readability --- packages/payment-detection/src/thegraph/client.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/payment-detection/src/thegraph/client.ts b/packages/payment-detection/src/thegraph/client.ts index 22f2ab0e8..fe751a058 100644 --- a/packages/payment-detection/src/thegraph/client.ts +++ b/packages/payment-detection/src/thegraph/client.ts @@ -139,16 +139,19 @@ export const defaultGetTheGraphClientUrl = ( options?: TheGraphClientOptions, ) => { const filteredNetwork = network.replace('aurora', 'near'); + const theGraphExplorerSubgraphId = THE_GRAPH_EXPLORER_SUBGRAPH_ID[network]; + const { theGraphExplorerApiKey } = options || {}; + + // build URLs const theGraphStudioUrl = THE_GRAPH_STUDIO_URL.replace('$NETWORK', filteredNetwork); const theGraphExplorerUrl = THE_GRAPH_EXPLORER_URL.replace( '$API_KEY', - options?.theGraphExplorerApiKey || '', - ).replace('$SUBGRAPH_ID', THE_GRAPH_EXPLORER_SUBGRAPH_ID[network] || ''); + theGraphExplorerApiKey || '', + ).replace('$SUBGRAPH_ID', theGraphExplorerSubgraphId || ''); const theGraphAlchemyUrl = THE_GRAPH_ALCHEMY_URL.replace('$NETWORK', filteredNetwork); - const shouldUseTheGraphExplorer = - !!options?.theGraphExplorerApiKey && - Object.keys(THE_GRAPH_EXPLORER_SUBGRAPH_ID).includes(network); + const shouldUseTheGraphExplorer = !!theGraphExplorerApiKey && !!theGraphExplorerSubgraphId; + const shouldUseAlchemy = THE_GRAPH_ALCHEMY_CHAINS.includes(network); switch (true) { case network === 'private': @@ -162,7 +165,7 @@ export const defaultGetTheGraphClientUrl = ( default: return shouldUseTheGraphExplorer ? theGraphExplorerUrl - : THE_GRAPH_ALCHEMY_CHAINS.includes(network) + : shouldUseAlchemy ? theGraphAlchemyUrl : theGraphStudioUrl; } From da33c4aed04511e06a918a2f959fc8d60f5acfd9 Mon Sep 17 00:00:00 2001 From: Alexandre ABRIOUX Date: Thu, 17 Apr 2025 16:22:41 +0200 Subject: [PATCH 5/5] fix usage of chains --- .../payment-detection/src/thegraph/client.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/payment-detection/src/thegraph/client.ts b/packages/payment-detection/src/thegraph/client.ts index fe751a058..916c03cdc 100644 --- a/packages/payment-detection/src/thegraph/client.ts +++ b/packages/payment-detection/src/thegraph/client.ts @@ -138,29 +138,29 @@ export const defaultGetTheGraphClientUrl = ( network: CurrencyTypes.ChainName, options?: TheGraphClientOptions, ) => { - const filteredNetwork = network.replace('aurora', 'near'); - const theGraphExplorerSubgraphId = THE_GRAPH_EXPLORER_SUBGRAPH_ID[network]; + const chain = network.replace('aurora', 'near') as CurrencyTypes.ChainName; + const theGraphExplorerSubgraphId = THE_GRAPH_EXPLORER_SUBGRAPH_ID[chain]; const { theGraphExplorerApiKey } = options || {}; // build URLs - const theGraphStudioUrl = THE_GRAPH_STUDIO_URL.replace('$NETWORK', filteredNetwork); + const theGraphStudioUrl = THE_GRAPH_STUDIO_URL.replace('$NETWORK', chain); const theGraphExplorerUrl = THE_GRAPH_EXPLORER_URL.replace( '$API_KEY', theGraphExplorerApiKey || '', ).replace('$SUBGRAPH_ID', theGraphExplorerSubgraphId || ''); - const theGraphAlchemyUrl = THE_GRAPH_ALCHEMY_URL.replace('$NETWORK', filteredNetwork); + const theGraphAlchemyUrl = THE_GRAPH_ALCHEMY_URL.replace('$NETWORK', chain); const shouldUseTheGraphExplorer = !!theGraphExplorerApiKey && !!theGraphExplorerSubgraphId; - const shouldUseAlchemy = THE_GRAPH_ALCHEMY_CHAINS.includes(network); + const shouldUseAlchemy = THE_GRAPH_ALCHEMY_CHAINS.includes(chain); switch (true) { - case network === 'private': + case chain === 'private': return; - case network === 'mantle': + case chain === 'mantle': return THE_GRAPH_URL_MANTLE; - case network === 'mantle-testnet': + case chain === 'mantle-testnet': return THE_GRAPH_URL_MANTLE_TESTNET; - case network === 'core': + case chain === 'core': return THE_GRAPH_URL_CORE; default: return shouldUseTheGraphExplorer