From e84f233ee156863136b120a79a91ec692a6f5677 Mon Sep 17 00:00:00 2001 From: Saihajpreet Singh Date: Thu, 11 Jan 2024 11:10:00 -0600 Subject: [PATCH] feat: use studio deploy router to get supported networks (#1557) * feat: use studio deploy router to get supported networks * improve * changeset * Add more debug logs: * better error --- .changeset/hip-pears-perform.md | 5 ++ packages/cli/src/command-helpers/node.ts | 2 +- packages/cli/src/commands/init.ts | 73 ++++++++++++++++++++---- 3 files changed, 67 insertions(+), 13 deletions(-) create mode 100644 .changeset/hip-pears-perform.md diff --git a/.changeset/hip-pears-perform.md b/.changeset/hip-pears-perform.md new file mode 100644 index 000000000..f4b3e0d0a --- /dev/null +++ b/.changeset/hip-pears-perform.md @@ -0,0 +1,5 @@ +--- +'@graphprotocol/graph-cli': minor +--- + +fetch supported networks from API diff --git a/packages/cli/src/command-helpers/node.ts b/packages/cli/src/command-helpers/node.ts index d6129a8b7..292db1f2d 100644 --- a/packages/cli/src/command-helpers/node.ts +++ b/packages/cli/src/command-helpers/node.ts @@ -2,7 +2,7 @@ import { URL } from 'url'; import { print } from 'gluegun'; import { GRAPH_CLI_SHARED_HEADERS } from '../constants'; -const SUBGRAPH_STUDIO_URL = 'https://api.studio.thegraph.com/deploy/'; +export const SUBGRAPH_STUDIO_URL = 'https://api.studio.thegraph.com/deploy/'; const HOSTED_SERVICE_URL = 'https://api.thegraph.com/deploy/'; const HOSTED_SERVICE_INDEX_NODE_URL = 'https://api.thegraph.com/index-node/graphql'; diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts index 35da3cf51..bf4ca7b55 100644 --- a/packages/cli/src/commands/init.ts +++ b/packages/cli/src/commands/init.ts @@ -10,10 +10,11 @@ import { loadStartBlockForContract, } from '../command-helpers/abi'; import { initNetworksConfig } from '../command-helpers/network'; -import { chooseNodeUrl } from '../command-helpers/node'; +import { chooseNodeUrl, SUBGRAPH_STUDIO_URL } from '../command-helpers/node'; import { generateScaffold, writeScaffold } from '../command-helpers/scaffold'; import { withSpinner } from '../command-helpers/spinner'; import { getSubgraphBasename, validateSubgraphName } from '../command-helpers/subgraph'; +import { GRAPH_CLI_SHARED_HEADERS } from '../constants'; import debugFactory from '../debug'; import Protocol, { ProtocolName } from '../protocols'; import EthereumABI from '../protocols/ethereum/abi'; @@ -22,12 +23,54 @@ import { validateContract } from '../validation'; import AddCommand from './add'; const protocolChoices = Array.from(Protocol.availableProtocols().keys()); -const availableNetworks = Protocol.availableNetworks(); - -const DEFAULT_EXAMPLE_SUBGRAPH = 'ethereum-gravatar'; const initDebugger = debugFactory('graph-cli:commands:init'); +/** + * a dynamic list of available networks supported by the studio + */ +const AVAILABLE_NETWORKS = async () => { + const logger = initDebugger.extend('AVAILABLE_NETWORKS'); + try { + logger('fetching chain_list from studio'); + const res = await fetch(SUBGRAPH_STUDIO_URL, { + method: 'POST', + headers: { + ...GRAPH_CLI_SHARED_HEADERS, + 'content-type': 'application/json', + }, + body: JSON.stringify({ + jsonrpc: '2.0', + id: 1, + method: 'chain_list', + params: [], + }), + }); + + if (!res.ok) { + logger( + "Something went wrong while fetching 'chain_list' from studio HTTP code: %o", + res.status, + ); + return null; + } + + const result = await res.json(); + if (result?.result) { + logger('chain_list result: %o', result.result); + return result.result as { studio: Array; hostedService: Array }; + } + + logger("Unable to get result for 'chain_list' from studio: %O", result); + return null; + } catch (e) { + logger('error: %O', e); + return null; + } +}; + +const DEFAULT_EXAMPLE_SUBGRAPH = 'ethereum-gravatar'; + export default class InitCommand extends Command { static description = 'Creates a new subgraph with basic scaffolding.'; @@ -125,12 +168,9 @@ export default class InitCommand extends Command { }), network: Flags.string({ summary: 'Network the contract is deployed to.', + description: + 'Check https://thegraph.com/docs/en/developing/supported-networks/ for supported networks', dependsOn: ['from-contract'], - options: [ - ...availableNetworks.get('ethereum')!, - ...availableNetworks.get('near')!, - ...availableNetworks.get('cosmos')!, - ], }), }; @@ -590,14 +630,23 @@ async function processInitForm( }, ]); + const choices = (await AVAILABLE_NETWORKS())?.[ + product === 'subgraph-studio' ? 'studio' : 'hostedService' + ]; + + if (!choices) { + this.error( + 'Unable to fetch available networks from API. Please report this issue. As a workaround you can pass `--network` flag from the available networks: https://thegraph.com/docs/en/developing/supported-networks', + { exit: 1 }, + ); + } + const { network } = await prompt.ask<{ network: string }>([ { type: 'select', name: 'network', message: () => `${protocolInstance.displayName()} network`, - choices: availableNetworks - .get(protocol as ProtocolName) // Get networks related to the chosen protocol. - ?.toArray() || ['mainnet'], + choices, skip: initNetwork !== undefined, result: value => { if (initNetwork) {