@graphprotocol/graph-cli 0.37.3 → 0.37.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/package.json +5 -1
  3. package/babel.config.js +0 -3
  4. package/jest.config.js +0 -175
  5. package/src/bin.ts +0 -6
  6. package/src/cli.ts +0 -30
  7. package/src/codegen/schema.test.ts +0 -460
  8. package/src/codegen/schema.ts +0 -299
  9. package/src/codegen/template.ts +0 -45
  10. package/src/codegen/types/conversions.ts +0 -358
  11. package/src/codegen/types/index.test.ts +0 -715
  12. package/src/codegen/types/index.ts +0 -111
  13. package/src/codegen/typescript.ts +0 -224
  14. package/src/codegen/util.test.ts +0 -112
  15. package/src/codegen/util.ts +0 -54
  16. package/src/command-helpers/abi.ts +0 -99
  17. package/src/command-helpers/auth.ts +0 -46
  18. package/src/command-helpers/compiler.ts +0 -60
  19. package/src/command-helpers/data-sources.ts +0 -36
  20. package/src/command-helpers/fs.ts +0 -5
  21. package/src/command-helpers/gluegun.ts +0 -52
  22. package/src/command-helpers/ipfs-http-client.d.ts +0 -1
  23. package/src/command-helpers/ipfs.ts +0 -3
  24. package/src/command-helpers/jsonrpc.ts +0 -22
  25. package/src/command-helpers/network.test.ts +0 -85
  26. package/src/command-helpers/network.ts +0 -133
  27. package/src/command-helpers/node.ts +0 -46
  28. package/src/command-helpers/scaffold.ts +0 -174
  29. package/src/command-helpers/spinner.ts +0 -60
  30. package/src/command-helpers/studio.test.ts +0 -84
  31. package/src/command-helpers/studio.ts +0 -25
  32. package/src/command-helpers/subgraph.ts +0 -21
  33. package/src/command-helpers/version.test.ts +0 -241
  34. package/src/command-helpers/version.ts +0 -53
  35. package/src/commands/add.ts +0 -220
  36. package/src/commands/auth.ts +0 -138
  37. package/src/commands/binary-install-raw.d.ts +0 -1
  38. package/src/commands/build.ts +0 -147
  39. package/src/commands/codegen.ts +0 -123
  40. package/src/commands/create.ts +0 -109
  41. package/src/commands/deploy.ts +0 -388
  42. package/src/commands/init.ts +0 -1060
  43. package/src/commands/local.ts +0 -539
  44. package/src/commands/remove.ts +0 -110
  45. package/src/commands/test.ts +0 -369
  46. package/src/compiler/asc.ts +0 -77
  47. package/src/compiler/index.ts +0 -677
  48. package/src/debug.ts +0 -15
  49. package/src/migrations/mapping_api_version_0_0_1.ts +0 -75
  50. package/src/migrations/mapping_api_version_0_0_2.ts +0 -75
  51. package/src/migrations/mapping_api_version_0_0_3.ts +0 -75
  52. package/src/migrations/mapping_api_version_0_0_4.ts +0 -77
  53. package/src/migrations/mapping_api_version_0_0_5.ts +0 -77
  54. package/src/migrations/spec_version_0_0_2.ts +0 -24
  55. package/src/migrations/spec_version_0_0_3.ts +0 -29
  56. package/src/migrations/util/load-manifest.ts +0 -10
  57. package/src/migrations/util/versions.ts +0 -27
  58. package/src/migrations.ts +0 -33
  59. package/src/protocols/arweave/manifest.graphql +0 -57
  60. package/src/protocols/arweave/scaffold/manifest.ts +0 -14
  61. package/src/protocols/arweave/scaffold/mapping.ts +0 -49
  62. package/src/protocols/arweave/subgraph.ts +0 -22
  63. package/src/protocols/contract.ts +0 -9
  64. package/src/protocols/cosmos/manifest.graphql +0 -76
  65. package/src/protocols/cosmos/scaffold/manifest.ts +0 -11
  66. package/src/protocols/cosmos/scaffold/mapping.ts +0 -35
  67. package/src/protocols/cosmos/subgraph.ts +0 -27
  68. package/src/protocols/ethereum/abi.ts +0 -153
  69. package/src/protocols/ethereum/codegen/abi.test.ts +0 -330
  70. package/src/protocols/ethereum/codegen/abi.ts +0 -719
  71. package/src/protocols/ethereum/codegen/template.ts +0 -41
  72. package/src/protocols/ethereum/contract.ts +0 -24
  73. package/src/protocols/ethereum/manifest.graphql +0 -94
  74. package/src/protocols/ethereum/scaffold/manifest.ts +0 -28
  75. package/src/protocols/ethereum/scaffold/mapping.ts +0 -76
  76. package/src/protocols/ethereum/subgraph.ts +0 -189
  77. package/src/protocols/ethereum/type-generator.ts +0 -191
  78. package/src/protocols/index.ts +0 -287
  79. package/src/protocols/ipfs/codegen/file_template.ts +0 -43
  80. package/src/protocols/near/contract.ts +0 -47
  81. package/src/protocols/near/manifest.graphql +0 -64
  82. package/src/protocols/near/scaffold/manifest.ts +0 -13
  83. package/src/protocols/near/scaffold/mapping.ts +0 -35
  84. package/src/protocols/near/subgraph.ts +0 -22
  85. package/src/protocols/subgraph.ts +0 -12
  86. package/src/protocols/substreams/manifest.graphql +0 -45
  87. package/src/protocols/substreams/scaffold/manifest.ts +0 -8
  88. package/src/protocols/substreams/subgraph.ts +0 -22
  89. package/src/scaffold/cosmos.test.ts +0 -83
  90. package/src/scaffold/ethereum.test.ts +0 -512
  91. package/src/scaffold/index.ts +0 -172
  92. package/src/scaffold/mapping.ts +0 -44
  93. package/src/scaffold/near.test.ts +0 -86
  94. package/src/scaffold/schema.ts +0 -89
  95. package/src/scaffold/tests.ts +0 -217
  96. package/src/schema.ts +0 -26
  97. package/src/subgraph.ts +0 -302
  98. package/src/type-generator.ts +0 -266
  99. package/src/validation/contract.ts +0 -51
  100. package/src/validation/index.ts +0 -5
  101. package/src/validation/manifest.ts +0 -360
  102. package/src/validation/schema.test.ts +0 -38
  103. package/src/validation/schema.ts +0 -957
  104. package/src/watcher.ts +0 -96
  105. package/tests/cli/globalSetup.ts +0 -8
  106. package/tests/cli/globalTeardown.ts +0 -8
  107. package/tests/cli/init/ethereum/abis/Marketplace.json +0 -408
  108. package/tests/cli/init/ethereum/abis/OverloadedElements.json +0 -91
  109. package/tests/cli/init/ethereum/abis/SoloMargin.json +0 -2729
  110. package/tests/cli/init/ethereum/from-contract-with-abi-and-structs.stderr +0 -14
  111. package/tests/cli/init/ethereum/from-contract-with-abi-and-structs.stdout +0 -12
  112. package/tests/cli/init/ethereum/from-contract-with-abi.stderr +0 -14
  113. package/tests/cli/init/ethereum/from-contract-with-abi.stdout +0 -12
  114. package/tests/cli/init/ethereum/from-contract-with-overloaded-elements.stderr +0 -14
  115. package/tests/cli/init/ethereum/from-contract-with-overloaded-elements.stdout +0 -12
  116. package/tests/cli/init/ethereum/from-contract.stderr +0 -16
  117. package/tests/cli/init/ethereum/from-contract.stdout +0 -12
  118. package/tests/cli/init/ethereum/from-example.stderr +0 -12
  119. package/tests/cli/init/ethereum/from-example.stdout +0 -12
  120. package/tests/cli/init/near/from-contract.stderr +0 -14
  121. package/tests/cli/init/near/from-contract.stdout +0 -12
  122. package/tests/cli/init.test.ts +0 -157
  123. package/tests/cli/spawn-command.d.ts +0 -7
  124. package/tests/cli/util.ts +0 -132
  125. package/tests/cli/validation/abi-not-found/Abi.json +0 -7
  126. package/tests/cli/validation/abi-not-found/mapping.ts +0 -0
  127. package/tests/cli/validation/abi-not-found/schema.graphql +0 -3
  128. package/tests/cli/validation/abi-not-found/subgraph.yaml +0 -42
  129. package/tests/cli/validation/abi-not-found copy.stderr +0 -13
  130. package/tests/cli/validation/big-decimal-is-valid/Abi.json +0 -7
  131. package/tests/cli/validation/big-decimal-is-valid/mapping.ts +0 -0
  132. package/tests/cli/validation/big-decimal-is-valid/schema.graphql +0 -4
  133. package/tests/cli/validation/big-decimal-is-valid/subgraph.yaml +0 -23
  134. package/tests/cli/validation/call-function-not-found/Abi.json +0 -57
  135. package/tests/cli/validation/call-function-not-found/mapping.ts +0 -0
  136. package/tests/cli/validation/call-function-not-found/schema.graphql +0 -3
  137. package/tests/cli/validation/call-function-not-found/subgraph.yaml +0 -22
  138. package/tests/cli/validation/call-function-not-found.stderr +0 -10
  139. package/tests/cli/validation/call-handler-with-tuple/Abi.json +0 -24
  140. package/tests/cli/validation/call-handler-with-tuple/generated/schema.ts +0 -44
  141. package/tests/cli/validation/call-handler-with-tuple/mapping.ts +0 -0
  142. package/tests/cli/validation/call-handler-with-tuple/schema.graphql +0 -3
  143. package/tests/cli/validation/call-handler-with-tuple/subgraph.yaml +0 -22
  144. package/tests/cli/validation/call-handler-with-tuple.stderr +0 -24
  145. package/tests/cli/validation/conflicting-network-names/Abi.json +0 -7
  146. package/tests/cli/validation/conflicting-network-names/mapping.ts +0 -0
  147. package/tests/cli/validation/conflicting-network-names/schema.graphql +0 -3
  148. package/tests/cli/validation/conflicting-network-names/subgraph.yaml +0 -41
  149. package/tests/cli/validation/conflicting-network-names.stderr +0 -10
  150. package/tests/cli/validation/conflicting-protocol-names/Abi.json +0 -7
  151. package/tests/cli/validation/conflicting-protocol-names/mapping.ts +0 -0
  152. package/tests/cli/validation/conflicting-protocol-names/schema.graphql +0 -3
  153. package/tests/cli/validation/conflicting-protocol-names/subgraph.yaml +0 -41
  154. package/tests/cli/validation/conflicting-protocol-names.stderr +0 -10
  155. package/tests/cli/validation/derived-from-target-type-missing/Abi.json +0 -6
  156. package/tests/cli/validation/derived-from-target-type-missing/mapping.ts +0 -0
  157. package/tests/cli/validation/derived-from-target-type-missing/schema.graphql +0 -4
  158. package/tests/cli/validation/derived-from-target-type-missing/subgraph.yaml +0 -22
  159. package/tests/cli/validation/derived-from-target-type-missing.stderr +0 -5
  160. package/tests/cli/validation/derived-from-with-interface/Gravity.json +0 -1
  161. package/tests/cli/validation/derived-from-with-interface/mapping.ts +0 -22
  162. package/tests/cli/validation/derived-from-with-interface/schema.graphql +0 -19
  163. package/tests/cli/validation/derived-from-with-interface/subgraph.yaml +0 -25
  164. package/tests/cli/validation/duplicate-data-source-name/Abi.json +0 -7
  165. package/tests/cli/validation/duplicate-data-source-name/mapping.ts +0 -0
  166. package/tests/cli/validation/duplicate-data-source-name/schema.graphql +0 -4
  167. package/tests/cli/validation/duplicate-data-source-name/subgraph.yaml +0 -40
  168. package/tests/cli/validation/duplicate-data-source-name.stderr +0 -5
  169. package/tests/cli/validation/duplicate-template-name/Abi.json +0 -7
  170. package/tests/cli/validation/duplicate-template-name/mapping.ts +0 -0
  171. package/tests/cli/validation/duplicate-template-name/schema.graphql +0 -4
  172. package/tests/cli/validation/duplicate-template-name/subgraph.yaml +0 -59
  173. package/tests/cli/validation/duplicate-template-name.stderr +0 -5
  174. package/tests/cli/validation/entity-field-args/Abi.json +0 -7
  175. package/tests/cli/validation/entity-field-args/mapping.ts +0 -0
  176. package/tests/cli/validation/entity-field-args/schema.graphql +0 -4
  177. package/tests/cli/validation/entity-field-args/subgraph.yaml +0 -22
  178. package/tests/cli/validation/entity-field-args.stderr +0 -5
  179. package/tests/cli/validation/ethereum-contract-without-handlers/Abi.json +0 -7
  180. package/tests/cli/validation/ethereum-contract-without-handlers/mapping.ts +0 -0
  181. package/tests/cli/validation/ethereum-contract-without-handlers/schema.graphql +0 -3
  182. package/tests/cli/validation/ethereum-contract-without-handlers/subgraph.yaml +0 -19
  183. package/tests/cli/validation/ethereum-contract-without-handlers.stderr +0 -6
  184. package/tests/cli/validation/event-not-found/Abi.json +0 -7
  185. package/tests/cli/validation/event-not-found/mapping.ts +0 -0
  186. package/tests/cli/validation/event-not-found/schema.graphql +0 -3
  187. package/tests/cli/validation/event-not-found/subgraph.yaml +0 -40
  188. package/tests/cli/validation/event-not-found.stderr +0 -12
  189. package/tests/cli/validation/example-values-found/Abi.json +0 -7
  190. package/tests/cli/validation/example-values-found/generated/ExampleSubgraph/ExampleContract.ts +0 -35
  191. package/tests/cli/validation/example-values-found/generated/schema.ts +0 -44
  192. package/tests/cli/validation/example-values-found/mapping.ts +0 -0
  193. package/tests/cli/validation/example-values-found/schema.graphql +0 -3
  194. package/tests/cli/validation/example-values-found/subgraph.yaml +0 -24
  195. package/tests/cli/validation/example-values-found.stderr +0 -34
  196. package/tests/cli/validation/invalid-abis/InvalidAbi.json +0 -1
  197. package/tests/cli/validation/invalid-abis/mapping.ts +0 -0
  198. package/tests/cli/validation/invalid-abis/schema.graphql +0 -3
  199. package/tests/cli/validation/invalid-abis/subgraph.yaml +0 -22
  200. package/tests/cli/validation/invalid-abis.stderr +0 -5
  201. package/tests/cli/validation/invalid-contract-addresses/Abi.json +0 -7
  202. package/tests/cli/validation/invalid-contract-addresses/mapping.ts +0 -0
  203. package/tests/cli/validation/invalid-contract-addresses/schema.graphql +0 -3
  204. package/tests/cli/validation/invalid-contract-addresses/subgraph.yaml +0 -58
  205. package/tests/cli/validation/invalid-contract-addresses.stderr +0 -14
  206. package/tests/cli/validation/invalid-data-source-template/mapping.ts +0 -0
  207. package/tests/cli/validation/invalid-data-source-template/schema.graphql +0 -3
  208. package/tests/cli/validation/invalid-data-source-template/subgraph.yaml +0 -32
  209. package/tests/cli/validation/invalid-data-source-template.stderr +0 -30
  210. package/tests/cli/validation/invalid-entity-field-types/Abi.json +0 -7
  211. package/tests/cli/validation/invalid-entity-field-types/mapping.ts +0 -0
  212. package/tests/cli/validation/invalid-entity-field-types/schema.graphql +0 -157
  213. package/tests/cli/validation/invalid-entity-field-types/subgraph.yaml +0 -22
  214. package/tests/cli/validation/invalid-entity-field-types.stderr +0 -148
  215. package/tests/cli/validation/invalid-fulltext-directive/Abi.json +0 -7
  216. package/tests/cli/validation/invalid-fulltext-directive/mapping.ts +0 -0
  217. package/tests/cli/validation/invalid-fulltext-directive/schema.graphql +0 -140
  218. package/tests/cli/validation/invalid-fulltext-directive/subgraph.yaml +0 -22
  219. package/tests/cli/validation/invalid-fulltext-directive.stderr +0 -32
  220. package/tests/cli/validation/invalid-graphql-schema/Abi.json +0 -7
  221. package/tests/cli/validation/invalid-graphql-schema/mapping.ts +0 -0
  222. package/tests/cli/validation/invalid-graphql-schema/schema.graphql +0 -8
  223. package/tests/cli/validation/invalid-graphql-schema/subgraph.yaml +0 -22
  224. package/tests/cli/validation/invalid-graphql-schema.stderr +0 -25
  225. package/tests/cli/validation/invalid-manifest/subgraph.yaml +0 -13
  226. package/tests/cli/validation/invalid-manifest-cannot-infer-protocol/subgraph.yaml +0 -12
  227. package/tests/cli/validation/invalid-manifest-cannot-infer-protocol.stderr +0 -5
  228. package/tests/cli/validation/invalid-manifest.stderr +0 -28
  229. package/tests/cli/validation/missing-entity-id/Abi.json +0 -7
  230. package/tests/cli/validation/missing-entity-id/mapping.ts +0 -0
  231. package/tests/cli/validation/missing-entity-id/schema.graphql +0 -3
  232. package/tests/cli/validation/missing-entity-id/subgraph.yaml +0 -22
  233. package/tests/cli/validation/missing-entity-id/types/ExampleSubgraph/ExampleContract.ts +0 -35
  234. package/tests/cli/validation/missing-entity-id/types/schema.ts +0 -27
  235. package/tests/cli/validation/missing-entity-id.stderr +0 -5
  236. package/tests/cli/validation/missing-or-invalid-derived-from-fields/Abi.json +0 -7
  237. package/tests/cli/validation/missing-or-invalid-derived-from-fields/mapping.ts +0 -0
  238. package/tests/cli/validation/missing-or-invalid-derived-from-fields/schema.graphql +0 -40
  239. package/tests/cli/validation/missing-or-invalid-derived-from-fields/subgraph.yaml +0 -22
  240. package/tests/cli/validation/missing-or-invalid-derived-from-fields.stderr +0 -10
  241. package/tests/cli/validation/missing-or-invalid-derived-from-fields.stdout +0 -0
  242. package/tests/cli/validation/near-is-valid/mapping.ts +0 -0
  243. package/tests/cli/validation/near-is-valid/schema.graphql +0 -8
  244. package/tests/cli/validation/near-is-valid/subgraph.yaml +0 -30
  245. package/tests/cli/validation/nested-template-nice-error/Abi.json +0 -7
  246. package/tests/cli/validation/nested-template-nice-error/mapping.ts +0 -0
  247. package/tests/cli/validation/nested-template-nice-error/schema.graphql +0 -3
  248. package/tests/cli/validation/nested-template-nice-error/subgraph.yaml +0 -35
  249. package/tests/cli/validation/nested-template-nice-error.stderr +0 -5
  250. package/tests/cli/validation/no-network-names/Abi.json +0 -7
  251. package/tests/cli/validation/no-network-names/mapping.ts +0 -0
  252. package/tests/cli/validation/no-network-names/schema.graphql +0 -3
  253. package/tests/cli/validation/no-network-names/subgraph.yaml +0 -40
  254. package/tests/cli/validation/no-network-names.stderr +0 -34
  255. package/tests/cli/validation/source-without-address-is-valid/Abi.json +0 -7
  256. package/tests/cli/validation/source-without-address-is-valid/generated/ExampleSubgraph/ExampleContract.ts +0 -35
  257. package/tests/cli/validation/source-without-address-is-valid/mapping.ts +0 -0
  258. package/tests/cli/validation/source-without-address-is-valid/schema.graphql +0 -3
  259. package/tests/cli/validation/source-without-address-is-valid/subgraph.yaml +0 -23
  260. package/tests/cli/validation/source-without-address-is-valid.stderr +0 -24
  261. package/tests/cli/validation/topic0-is-valid/Abi.json +0 -7
  262. package/tests/cli/validation/topic0-is-valid/mapping.ts +0 -0
  263. package/tests/cli/validation/topic0-is-valid/schema.graphql +0 -4
  264. package/tests/cli/validation/topic0-is-valid/subgraph.yaml +0 -24
  265. package/tests/cli/validation.test.ts +0 -226
  266. package/tsconfig.build.json +0 -4
  267. package/tsconfig.json +0 -19
@@ -1,1060 +0,0 @@
1
- import fs from 'fs';
2
- import os from 'os';
3
- import path from 'path';
4
- import chalk from 'chalk';
5
- import { GluegunToolbox } from 'gluegun';
6
- import * as graphCli from '../cli';
7
- import { loadAbiFromBlockScout, loadAbiFromEtherscan } from '../command-helpers/abi';
8
- import * as DataSourcesExtractor from '../command-helpers/data-sources';
9
- import { fixParameters } from '../command-helpers/gluegun';
10
- import { initNetworksConfig } from '../command-helpers/network';
11
- import { chooseNodeUrl } from '../command-helpers/node';
12
- import { generateScaffold, writeScaffold } from '../command-helpers/scaffold';
13
- import { withSpinner } from '../command-helpers/spinner';
14
- import { validateStudioNetwork } from '../command-helpers/studio';
15
- import { getSubgraphBasename, validateSubgraphName } from '../command-helpers/subgraph';
16
- import debug from '../debug';
17
- import Protocol, { ProtocolName } from '../protocols';
18
- import { ContractCtor } from '../protocols/contract';
19
- import EthereumABI from '../protocols/ethereum/abi';
20
- import { abiEvents } from '../scaffold/schema';
21
- import { validateContract } from '../validation';
22
-
23
- const protocolChoices = Array.from(Protocol.availableProtocols().keys());
24
- const availableNetworks = Protocol.availableNetworks();
25
-
26
- const DEFAULT_EXAMPLE_SUBGRAPH = 'ethereum/gravatar';
27
-
28
- const initDebug = debug('graph-cli:init');
29
-
30
- const HELP = `
31
- ${chalk.bold('graph init')} [options] [subgraph-name] [directory]
32
-
33
- ${chalk.dim('Options:')}
34
-
35
- --protocol <${protocolChoices.join('|')}>
36
- --product <subgraph-studio|hosted-service>
37
- Selects the product for which to initialize
38
- --studio Shortcut for --product subgraph-studio
39
- -g, --node <node> Graph node for which to initialize
40
- --allow-simple-name Use a subgraph name without a prefix (default: false)
41
- -h, --help Show usage information
42
-
43
- ${chalk.dim('Choose mode with one of:')}
44
-
45
- --from-contract <contract> Creates a scaffold based on an existing contract
46
- --from-example [example] Creates a scaffold based on an example subgraph
47
-
48
- ${chalk.dim('Options for --from-contract:')}
49
-
50
- --contract-name Name of the contract (default: Contract)
51
- --index-events Index contract events as entities
52
-
53
- ${chalk.dim.underline('Ethereum:')}
54
-
55
- --abi <path> Path to the contract ABI (default: download from Etherscan)
56
- --network <${availableNetworks.get('ethereum')!.join('|')}>
57
- Selects the network the contract is deployed to
58
-
59
- ${chalk.dim.underline('NEAR:')}
60
-
61
- --network <${availableNetworks.get('near')!.join('|')}>
62
- Selects the network the contract is deployed to
63
-
64
- ${chalk.dim.underline('Cosmos:')}
65
-
66
- --network <${availableNetworks.get('cosmos')!.join('|')}>
67
- Selects the network the contract is deployed to
68
- `;
69
-
70
- const processInitForm = async (
71
- toolbox: GluegunToolbox,
72
- {
73
- protocol,
74
- product,
75
- studio,
76
- node,
77
- abi,
78
- allowSimpleName,
79
- directory,
80
- contract,
81
- indexEvents,
82
- fromExample,
83
- network,
84
- subgraphName,
85
- contractName,
86
- }: {
87
- protocol: ProtocolName;
88
- product: string;
89
- studio: string;
90
- node: string;
91
- abi: EthereumABI;
92
- allowSimpleName: boolean;
93
- directory: string;
94
- contract: string;
95
- indexEvents: boolean;
96
- fromExample: string | boolean;
97
- network: string;
98
- subgraphName: string;
99
- contractName: string;
100
- },
101
- ): Promise<
102
- | {
103
- abi: EthereumABI;
104
- protocolInstance: Protocol;
105
- subgraphName: string;
106
- directory: string;
107
- studio: string;
108
- product: string;
109
- network: string;
110
- contract: string;
111
- indexEvents: boolean;
112
- contractName: string;
113
- }
114
- | undefined
115
- > => {
116
- let abiFromEtherscan: EthereumABI | undefined = undefined;
117
- let abiFromFile = undefined;
118
- let protocolInstance!: Protocol;
119
- let ProtocolContract: ContractCtor;
120
- let ABI: typeof EthereumABI;
121
-
122
- const questions = [
123
- {
124
- type: 'select',
125
- name: 'protocol',
126
- message: 'Protocol',
127
- choices: protocolChoices,
128
- skip: protocolChoices.includes(protocol),
129
- result: (value: ProtocolName) => {
130
- protocol ||= value;
131
- protocolInstance = new Protocol(protocol);
132
- return protocol;
133
- },
134
- },
135
- {
136
- type: 'select',
137
- name: 'product',
138
- message: 'Product for which to initialize',
139
- choices: ['subgraph-studio', 'hosted-service'],
140
- skip: () =>
141
- protocol === 'arweave' ||
142
- protocol === 'cosmos' ||
143
- protocol === 'near' ||
144
- product === 'subgraph-studio' ||
145
- product === 'hosted-service' ||
146
- studio !== undefined ||
147
- node !== undefined,
148
- result: (value: string | undefined) => {
149
- // For now we only support NEAR subgraphs in the Hosted Service
150
- if (protocol === 'near') {
151
- // Can be overwritten because the question will be skipped (product === undefined)
152
- product = 'hosted-service';
153
- return product;
154
- }
155
-
156
- if (value == 'subgraph-studio') {
157
- allowSimpleName = true;
158
- }
159
-
160
- product = value as any;
161
- return value;
162
- },
163
- },
164
- {
165
- type: 'input',
166
- name: 'subgraphName',
167
- message: () => (product == 'subgraph-studio' || studio ? 'Subgraph slug' : 'Subgraph name'),
168
- initial: subgraphName,
169
- validate: (name: string) => {
170
- try {
171
- validateSubgraphName(name, { allowSimpleName });
172
- return true;
173
- } catch (e) {
174
- return `${e.message}
175
-
176
- Examples:
177
-
178
- $ graph init ${os.userInfo().username}/${name}
179
- $ graph init ${name} --allow-simple-name`;
180
- }
181
- },
182
- result: (value: string) => {
183
- subgraphName = value;
184
- return value;
185
- },
186
- },
187
- {
188
- type: 'input',
189
- name: 'directory',
190
- message: 'Directory to create the subgraph in',
191
- initial: () => directory || getSubgraphBasename(subgraphName),
192
- validate: (value: string) =>
193
- toolbox.filesystem.exists(value || directory || getSubgraphBasename(subgraphName))
194
- ? 'Directory already exists'
195
- : true,
196
- },
197
- {
198
- type: 'select',
199
- name: 'network',
200
- message: () => `${protocolInstance.displayName()} network`,
201
- choices: () => {
202
- initDebug(
203
- 'Generating list of available networks for protocol "%s" (%M)',
204
- protocol,
205
- availableNetworks.get(protocol as any),
206
- );
207
- return (
208
- // @ts-expect-error TODO: wait what?
209
- availableNetworks
210
- .get(protocol) // Get networks related to the chosen protocol.
211
- // @ts-expect-error TODO: wait what?
212
- .toArray()
213
- ); // Needed because of gluegun. It can't even receive a JS iterable.
214
- },
215
-
216
- skip: fromExample !== undefined,
217
- initial: network || 'mainnet',
218
- result: (value: string) => {
219
- network = value;
220
- return value;
221
- },
222
- },
223
- // TODO:
224
- //
225
- // protocols that don't support contract
226
- // - arweave
227
- // - cosmos
228
- {
229
- type: 'input',
230
- name: 'contract',
231
- message: () => {
232
- ProtocolContract = protocolInstance.getContract()!;
233
- return `Contract ${ProtocolContract.identifierName()}`;
234
- },
235
- skip: () => fromExample !== undefined || !protocolInstance.hasContract(),
236
- initial: contract,
237
- validate: async (value: string) => {
238
- if (fromExample !== undefined || !protocolInstance.hasContract()) {
239
- return true;
240
- }
241
-
242
- // Validate whether the contract is valid
243
- const { valid, error } = validateContract(value, ProtocolContract);
244
-
245
- return valid ? true : error;
246
- },
247
- result: async (value: string) => {
248
- if (fromExample !== undefined) {
249
- return value;
250
- }
251
-
252
- ABI = protocolInstance.getABI();
253
-
254
- // Try loading the ABI from Etherscan, if none was provided
255
- if (protocolInstance.hasABIs() && !abi) {
256
- try {
257
- if (network === 'poa-core') {
258
- // TODO: this variable is never used anywhere, what happens?
259
- // abiFromBlockScout = await loadAbiFromBlockScout(ABI, network, value)
260
- } else {
261
- abiFromEtherscan = await loadAbiFromEtherscan(ABI, network!, value);
262
- }
263
- } catch (e) {
264
- // noop
265
- }
266
- }
267
- return value;
268
- },
269
- },
270
- {
271
- type: 'input',
272
- name: 'abi',
273
- message: 'ABI file (path)',
274
- initial: abi,
275
- skip: () =>
276
- !protocolInstance.hasABIs() || fromExample !== undefined || abiFromEtherscan !== undefined,
277
- validate: async (value: string) => {
278
- if (fromExample || abiFromEtherscan || !protocolInstance.hasABIs()) {
279
- return true;
280
- }
281
-
282
- try {
283
- abiFromFile = loadAbiFromFile(toolbox, ABI, value);
284
- return true;
285
- } catch (e) {
286
- return e.message;
287
- }
288
- },
289
- },
290
- {
291
- type: 'input',
292
- name: 'contractName',
293
- message: 'Contract Name',
294
- initial: contractName || 'Contract',
295
- skip: () => fromExample !== undefined || !protocolInstance.hasContract(),
296
- validate: (value: string) => value && value.length > 0,
297
- result: (value: string) => {
298
- contractName = value;
299
- return value;
300
- },
301
- },
302
- {
303
- type: 'confirm',
304
- name: 'indexEvents',
305
- message: 'Index contract events as entities',
306
- initial: true,
307
- skip: () => !!indexEvents,
308
- result: (value: boolean) => {
309
- indexEvents = value;
310
- return value;
311
- },
312
- },
313
- ];
314
-
315
- try {
316
- const answers = await toolbox.prompt.ask(
317
- // @ts-expect-error questions do somehow fit
318
- questions,
319
- );
320
- return {
321
- ...(answers as any), // necessary answers are here
322
- abi: (abiFromEtherscan || abiFromFile)!,
323
- protocolInstance,
324
- };
325
- } catch (e) {
326
- return undefined;
327
- }
328
- };
329
-
330
- const loadAbiFromFile = (toolbox: GluegunToolbox, ABI: typeof EthereumABI, filename: string) => {
331
- const exists = toolbox.filesystem.exists(filename);
332
-
333
- if (!exists) {
334
- throw Error('File does not exist.');
335
- } else if (exists === 'dir') {
336
- throw Error('Path points to a directory, not a file.');
337
- } else if (exists === 'other') {
338
- throw Error('Not sure what this path points to.');
339
- } else {
340
- return ABI.load('Contract', filename);
341
- }
342
- };
343
-
344
- export default {
345
- description: 'Creates a new subgraph with basic scaffolding',
346
- run: async (toolbox: GluegunToolbox) => {
347
- // Obtain tools
348
- const { print, system } = toolbox;
349
-
350
- // Read CLI parameters
351
- let {
352
- protocol,
353
- product,
354
- studio,
355
- node,
356
- g,
357
- abi,
358
- allowSimpleName,
359
- fromContract,
360
- contractName,
361
- fromExample,
362
- h,
363
- help,
364
- indexEvents,
365
- network,
366
- } = toolbox.parameters.options;
367
-
368
- node ||= g;
369
- ({ node, allowSimpleName } = chooseNodeUrl({
370
- product,
371
- studio,
372
- node,
373
- allowSimpleName,
374
- }));
375
-
376
- if (fromContract && fromExample) {
377
- print.error(`Only one of --from-example and --from-contract can be used at a time.`);
378
- process.exitCode = 1;
379
- return;
380
- }
381
-
382
- let subgraphName, directory;
383
- try {
384
- [subgraphName, directory] = fixParameters(toolbox.parameters, {
385
- allowSimpleName,
386
- help,
387
- h,
388
- indexEvents,
389
- studio,
390
- });
391
- } catch (e) {
392
- print.error(e.message);
393
- process.exitCode = 1;
394
- return;
395
- }
396
-
397
- // Show help text if requested
398
- if (help || h) {
399
- print.info(HELP);
400
- return;
401
- }
402
-
403
- // Detect git
404
- const git = system.which('git');
405
- if (git === null) {
406
- print.error(`Git was not found on your system. Please install 'git' so it is in $PATH.`);
407
- process.exitCode = 1;
408
- return;
409
- }
410
-
411
- // Detect Yarn and/or NPM
412
- const yarn = system.which('yarn');
413
- const npm = system.which('npm');
414
- if (!yarn && !npm) {
415
- print.error(`Neither Yarn nor NPM were found on your system. Please install one of them.`);
416
- process.exitCode = 1;
417
- return;
418
- }
419
-
420
- const commands = {
421
- install: yarn ? 'yarn' : 'npm install',
422
- codegen: yarn ? 'yarn codegen' : 'npm run codegen',
423
- deploy: yarn ? 'yarn deploy' : 'npm run deploy',
424
- };
425
-
426
- // If all parameters are provided from the command-line,
427
- // go straight to creating the subgraph from the example
428
- if (fromExample && subgraphName && directory) {
429
- return await initSubgraphFromExample(
430
- toolbox,
431
- { fromExample, allowSimpleName, directory, subgraphName, studio, product },
432
- { commands },
433
- );
434
- }
435
-
436
- // If all parameters are provided from the command-line,
437
- // go straight to creating the subgraph from an existing contract
438
- if (fromContract && protocol && subgraphName && directory && network && node) {
439
- if (!protocolChoices.includes(protocol)) {
440
- print.error(
441
- `Protocol '${protocol}' is not supported, choose from these options: ${protocolChoices.join(
442
- ', ',
443
- )}`,
444
- );
445
- process.exitCode = 1;
446
- return;
447
- }
448
-
449
- const protocolInstance = new Protocol(protocol);
450
-
451
- if (protocolInstance.hasABIs()) {
452
- const ABI = protocolInstance.getABI();
453
- if (abi) {
454
- try {
455
- abi = loadAbiFromFile(toolbox, ABI, abi);
456
- } catch (e) {
457
- print.error(`Failed to load ABI: ${e.message}`);
458
- process.exitCode = 1;
459
- return;
460
- }
461
- } else {
462
- try {
463
- if (network === 'poa-core') {
464
- abi = await loadAbiFromBlockScout(ABI, network, fromContract);
465
- } else {
466
- abi = await loadAbiFromEtherscan(ABI, network, fromContract);
467
- }
468
- } catch (e) {
469
- process.exitCode = 1;
470
- return;
471
- }
472
- }
473
- }
474
-
475
- return await initSubgraphFromContract(
476
- toolbox,
477
- {
478
- protocolInstance,
479
- abi,
480
- allowSimpleName,
481
- directory,
482
- contract: fromContract,
483
- indexEvents,
484
- network,
485
- subgraphName,
486
- contractName,
487
- node,
488
- studio,
489
- product,
490
- },
491
- { commands, addContract: false },
492
- );
493
- }
494
-
495
- // Otherwise, take the user through the interactive form
496
- const inputs = await processInitForm(toolbox, {
497
- protocol,
498
- product,
499
- studio,
500
- node,
501
- abi,
502
- allowSimpleName,
503
- directory,
504
- contract: fromContract,
505
- indexEvents,
506
- fromExample,
507
- network,
508
- subgraphName,
509
- contractName,
510
- });
511
-
512
- // Exit immediately when the form is cancelled
513
- if (inputs === undefined) {
514
- process.exit(1);
515
- }
516
-
517
- print.info('———');
518
-
519
- if (fromExample) {
520
- await initSubgraphFromExample(
521
- toolbox,
522
- {
523
- fromExample,
524
- subgraphName: inputs.subgraphName,
525
- directory: inputs.directory,
526
- studio: inputs.studio,
527
- product: inputs.product,
528
- },
529
- { commands },
530
- );
531
- } else {
532
- ({ node, allowSimpleName } = chooseNodeUrl({
533
- product: inputs.product,
534
- studio,
535
- node,
536
- allowSimpleName,
537
- }));
538
- await initSubgraphFromContract(
539
- toolbox,
540
- {
541
- protocolInstance: inputs.protocolInstance,
542
- allowSimpleName,
543
- subgraphName: inputs.subgraphName,
544
- directory: inputs.directory,
545
- abi: inputs.abi,
546
- network: inputs.network,
547
- contract: inputs.contract,
548
- indexEvents: inputs.indexEvents,
549
- contractName: inputs.contractName,
550
- node,
551
- studio: inputs.studio,
552
- product: inputs.product,
553
- },
554
- { commands, addContract: true },
555
- );
556
- }
557
- },
558
- };
559
-
560
- const revalidateSubgraphName = async (
561
- toolbox: GluegunToolbox,
562
- subgraphName: string,
563
- { allowSimpleName }: { allowSimpleName: boolean },
564
- ) => {
565
- // Fail if the subgraph name is invalid
566
- try {
567
- validateSubgraphName(subgraphName, { allowSimpleName });
568
- return true;
569
- } catch (e) {
570
- toolbox.print.error(`${e.message}
571
-
572
- Examples:
573
-
574
- $ graph init ${os.userInfo().username}/${subgraphName}
575
- $ graph init ${subgraphName} --allow-simple-name`);
576
- return false;
577
- }
578
- };
579
-
580
- const initRepository = async (toolbox: GluegunToolbox, directory: string) =>
581
- await withSpinner(
582
- `Initialize subgraph repository`,
583
- `Failed to initialize subgraph repository`,
584
- `Warnings while initializing subgraph repository`,
585
- async () => {
586
- // Remove .git dir in --from-example mode; in --from-contract, we're
587
- // starting from an empty directory
588
- const gitDir = path.join(directory, '.git');
589
- if (toolbox.filesystem.exists(gitDir)) {
590
- toolbox.filesystem.remove(gitDir);
591
- }
592
- await toolbox.system.run('git init', { cwd: directory });
593
- await toolbox.system.run('git add --all', { cwd: directory });
594
- await toolbox.system.run('git commit -m "Initial commit"', {
595
- cwd: directory,
596
- });
597
- return true;
598
- },
599
- );
600
-
601
- // Only used for local testing / continuous integration.
602
- //
603
- // This requires that the command `npm link` is called
604
- // on the root directory of this repository, as described here:
605
- // https://docs.npmjs.com/cli/v7/commands/npm-link.
606
- const npmLinkToLocalCli = async (toolbox: GluegunToolbox, directory: string) => {
607
- if (process.env.GRAPH_CLI_TESTS) {
608
- await toolbox.system.run('npm link @graphprotocol/graph-cli', { cwd: directory });
609
- }
610
- };
611
-
612
- const installDependencies = async (
613
- toolbox: GluegunToolbox,
614
- directory: string,
615
- installCommand: string,
616
- ) =>
617
- await withSpinner(
618
- `Install dependencies with ${toolbox.print.colors.muted(installCommand)}`,
619
- `Failed to install dependencies`,
620
- `Warnings while installing dependencies`,
621
- async () => {
622
- // Links to local graph-cli if we're running the automated tests
623
- await npmLinkToLocalCli(toolbox, directory);
624
-
625
- await toolbox.system.run(installCommand, { cwd: directory });
626
- return true;
627
- },
628
- );
629
-
630
- const runCodegen = async (toolbox: GluegunToolbox, directory: string, codegenCommand: string) =>
631
- await withSpinner(
632
- `Generate ABI and schema types with ${toolbox.print.colors.muted(codegenCommand)}`,
633
- `Failed to generate code from ABI and GraphQL schema`,
634
- `Warnings while generating code from ABI and GraphQL schema`,
635
- async () => {
636
- await toolbox.system.run(codegenCommand, { cwd: directory });
637
- return true;
638
- },
639
- );
640
-
641
- const printNextSteps = (
642
- toolbox: GluegunToolbox,
643
- { subgraphName, directory }: { subgraphName: string; directory: string },
644
- {
645
- commands,
646
- }: {
647
- commands: {
648
- install: string;
649
- codegen: string;
650
- deploy: string;
651
- };
652
- },
653
- ) => {
654
- const { print } = toolbox;
655
-
656
- const relativeDir = path.relative(process.cwd(), directory);
657
-
658
- // Print instructions
659
- print.success(
660
- `
661
- Subgraph ${print.colors.blue(subgraphName)} created in ${print.colors.blue(relativeDir)}
662
- `,
663
- );
664
- print.info(`Next steps:
665
-
666
- 1. Run \`${print.colors.muted('graph auth')}\` to authenticate with your deploy key.
667
-
668
- 2. Type \`${print.colors.muted(`cd ${relativeDir}`)}\` to enter the subgraph.
669
-
670
- 3. Run \`${print.colors.muted(commands.deploy)}\` to deploy the subgraph.
671
-
672
- Make sure to visit the documentation on https://thegraph.com/docs/ for further information.`);
673
- };
674
-
675
- const initSubgraphFromExample = async (
676
- toolbox: GluegunToolbox,
677
- {
678
- fromExample,
679
- allowSimpleName,
680
- subgraphName,
681
- directory,
682
- studio,
683
- product,
684
- }: {
685
- fromExample: string | boolean;
686
- allowSimpleName?: boolean;
687
- subgraphName: string;
688
- directory: string;
689
- studio: string;
690
- product: string;
691
- },
692
- {
693
- commands,
694
- }: {
695
- commands: {
696
- install: string;
697
- codegen: string;
698
- deploy: string;
699
- };
700
- },
701
- ) => {
702
- const { filesystem, print, system } = toolbox;
703
-
704
- // Fail if the subgraph name is invalid
705
- if (!revalidateSubgraphName(toolbox, subgraphName, { allowSimpleName: !!allowSimpleName })) {
706
- process.exitCode = 1;
707
- return;
708
- }
709
-
710
- // Fail if the output directory already exists
711
- if (filesystem.exists(directory)) {
712
- print.error(`Directory or file "${directory}" already exists`);
713
- process.exitCode = 1;
714
- return;
715
- }
716
-
717
- // Clone the example subgraph repository
718
- const cloned = await withSpinner(
719
- `Cloning example subgraph`,
720
- `Failed to clone example subgraph`,
721
- `Warnings while cloning example subgraph`,
722
- async () => {
723
- // Create a temporary directory
724
- const prefix = path.join(os.tmpdir(), 'example-subgraph-');
725
- const tmpDir = fs.mkdtempSync(prefix);
726
-
727
- try {
728
- await system.run(`git clone http://github.com/graphprotocol/example-subgraphs ${tmpDir}`);
729
-
730
- // If an example is not specified, use the default one
731
- if (fromExample === undefined || fromExample === true) {
732
- fromExample = DEFAULT_EXAMPLE_SUBGRAPH;
733
- }
734
-
735
- const exampleSubgraphPath = path.join(tmpDir, String(fromExample));
736
-
737
- if (!filesystem.exists(exampleSubgraphPath)) {
738
- return { result: false, error: `Example not found: ${fromExample}` };
739
- }
740
-
741
- filesystem.copy(exampleSubgraphPath, directory);
742
- return true;
743
- } finally {
744
- filesystem.remove(tmpDir);
745
- }
746
- },
747
- );
748
- if (!cloned) {
749
- process.exitCode = 1;
750
- return;
751
- }
752
-
753
- try {
754
- // It doesn't matter if we changed the URL we clone the YAML,
755
- // we'll check it's network anyway. If it's a studio subgraph we're dealing with.
756
- const dataSourcesAndTemplates = await DataSourcesExtractor.fromFilePath(
757
- path.join(directory, 'subgraph.yaml'),
758
- );
759
-
760
- for (const { network } of dataSourcesAndTemplates) {
761
- validateStudioNetwork({ studio, product, network });
762
- }
763
- } catch (e) {
764
- print.error(e.message);
765
- process.exitCode = 1;
766
- return;
767
- }
768
-
769
- const networkConf = await initNetworksConfig(toolbox, directory, 'address');
770
- if (networkConf !== true) {
771
- process.exitCode = 1;
772
- return;
773
- }
774
-
775
- // Update package.json to match the subgraph name
776
- const prepared = await withSpinner(
777
- `Update subgraph name and commands in package.json`,
778
- `Failed to update subgraph name and commands in package.json`,
779
- `Warnings while updating subgraph name and commands in package.json`,
780
- async () => {
781
- try {
782
- // Load package.json
783
- const pkgJsonFilename = filesystem.path(directory, 'package.json');
784
- const pkgJson = await filesystem.read(pkgJsonFilename, 'json');
785
-
786
- pkgJson.name = getSubgraphBasename(subgraphName);
787
- Object.keys(pkgJson.scripts).forEach(name => {
788
- pkgJson.scripts[name] = pkgJson.scripts[name].replace('example', subgraphName);
789
- });
790
- delete pkgJson['license'];
791
- delete pkgJson['repository'];
792
-
793
- // Remove example's cli in favor of the local one (added via `npm link`)
794
- if (process.env.GRAPH_CLI_TESTS) {
795
- delete pkgJson['devDependencies']['@graphprotocol/graph-cli'];
796
- }
797
-
798
- // Write package.json
799
- filesystem.write(pkgJsonFilename, pkgJson, { jsonIndent: 2 });
800
- return true;
801
- } catch (e) {
802
- print.error(`Failed to preconfigure the subgraph: ${e}`);
803
- filesystem.remove(directory);
804
- return false;
805
- }
806
- },
807
- );
808
- if (!prepared) {
809
- process.exitCode = 1;
810
- return;
811
- }
812
-
813
- // Initialize a fresh Git repository
814
- const repo = await initRepository(toolbox, directory);
815
- if (repo !== true) {
816
- process.exitCode = 1;
817
- return;
818
- }
819
-
820
- // Install dependencies
821
- const installed = await installDependencies(toolbox, directory, commands.install);
822
- if (installed !== true) {
823
- process.exitCode = 1;
824
- return;
825
- }
826
-
827
- // Run code-generation
828
- const codegen = await runCodegen(toolbox, directory, commands.codegen);
829
- if (codegen !== true) {
830
- process.exitCode = 1;
831
- return;
832
- }
833
-
834
- printNextSteps(toolbox, { subgraphName, directory }, { commands });
835
- };
836
-
837
- const initSubgraphFromContract = async (
838
- toolbox: GluegunToolbox,
839
- {
840
- protocolInstance,
841
- allowSimpleName,
842
- subgraphName,
843
- directory,
844
- abi,
845
- network,
846
- contract,
847
- indexEvents,
848
- contractName,
849
- node,
850
- studio,
851
- product,
852
- }: {
853
- protocolInstance: Protocol;
854
- allowSimpleName: boolean;
855
- subgraphName: string;
856
- directory: string;
857
- abi: EthereumABI;
858
- network: string;
859
- contract: string;
860
- indexEvents: boolean;
861
- contractName: string;
862
- node: string;
863
- studio: string;
864
- product: string;
865
- },
866
- {
867
- commands,
868
- addContract,
869
- }: {
870
- commands: {
871
- install: string;
872
- codegen: string;
873
- deploy: string;
874
- };
875
- addContract: boolean;
876
- },
877
- ) => {
878
- const { print } = toolbox;
879
-
880
- // Fail if the subgraph name is invalid
881
- if (!revalidateSubgraphName(toolbox, subgraphName, { allowSimpleName })) {
882
- process.exitCode = 1;
883
- return;
884
- }
885
-
886
- // Fail if the output directory already exists
887
- if (toolbox.filesystem.exists(directory)) {
888
- print.error(`Directory or file "${directory}" already exists`);
889
- process.exitCode = 1;
890
- return;
891
- }
892
-
893
- if (
894
- protocolInstance.hasABIs() &&
895
- (abiEvents(abi).size === 0 ||
896
- // @ts-expect-error TODO: the abiEvents result is expected to be a List, how's it an array?
897
- abiEvents(abi).length === 0)
898
- ) {
899
- // Fail if the ABI does not contain any events
900
- print.error(`ABI does not contain any events`);
901
- process.exitCode = 1;
902
- return;
903
- }
904
-
905
- // We can validate this before the scaffold because we receive
906
- // the network from the form or via command line argument.
907
- // We don't need to read the manifest in this case.
908
- try {
909
- validateStudioNetwork({ studio, product, network });
910
- } catch (e) {
911
- print.error(e.message);
912
- process.exitCode = 1;
913
- return;
914
- }
915
-
916
- // Scaffold subgraph
917
- const scaffold = await withSpinner(
918
- `Create subgraph scaffold`,
919
- `Failed to create subgraph scaffold`,
920
- `Warnings while creating subgraph scaffold`,
921
- async spinner => {
922
- const scaffold = await generateScaffold(
923
- {
924
- protocolInstance,
925
- subgraphName,
926
- abi,
927
- network,
928
- contract,
929
- indexEvents,
930
- contractName,
931
- node,
932
- },
933
- spinner,
934
- );
935
- await writeScaffold(scaffold, directory, spinner);
936
- return true;
937
- },
938
- );
939
- if (scaffold !== true) {
940
- process.exitCode = 1;
941
- return;
942
- }
943
-
944
- if (protocolInstance.hasContract()) {
945
- const identifierName = protocolInstance.getContract()!.identifierName();
946
- const networkConf = await initNetworksConfig(toolbox, directory, identifierName);
947
- if (networkConf !== true) {
948
- process.exitCode = 1;
949
- return;
950
- }
951
- }
952
-
953
- // Initialize a fresh Git repository
954
- const repo = await initRepository(toolbox, directory);
955
- if (repo !== true) {
956
- process.exitCode = 1;
957
- return;
958
- }
959
-
960
- // Install dependencies
961
- const installed = await installDependencies(toolbox, directory, commands.install);
962
- if (installed !== true) {
963
- process.exitCode = 1;
964
- return;
965
- }
966
-
967
- // Run code-generation
968
- const codegen = await runCodegen(toolbox, directory, commands.codegen);
969
- if (codegen !== true) {
970
- process.exitCode = 1;
971
- return;
972
- }
973
-
974
- while (addContract) {
975
- addContract = await addAnotherContract(toolbox, { protocolInstance, directory });
976
- }
977
-
978
- printNextSteps(toolbox, { subgraphName, directory }, { commands });
979
- };
980
-
981
- const addAnotherContract = async (
982
- toolbox: GluegunToolbox,
983
- { protocolInstance, directory }: { protocolInstance: Protocol; directory: string },
984
- ) => {
985
- const addContractConfirmation = await toolbox.prompt.confirm('Add another contract?');
986
-
987
- if (addContractConfirmation) {
988
- let abiFromFile = false;
989
- const ProtocolContract = protocolInstance.getContract()!;
990
-
991
- const questions = [
992
- {
993
- type: 'input',
994
- name: 'contract',
995
- message: () => `Contract ${ProtocolContract.identifierName()}`,
996
- validate: async (value: string) => {
997
- // Validate whether the contract is valid
998
- const { valid, error } = validateContract(value, ProtocolContract);
999
- return valid ? true : error;
1000
- },
1001
- },
1002
- {
1003
- type: 'select',
1004
- name: 'localAbi',
1005
- message: 'Provide local ABI path?',
1006
- choices: ['yes', 'no'],
1007
- result: (value: string) => {
1008
- abiFromFile = value === 'yes' ? true : false;
1009
- return abiFromFile;
1010
- },
1011
- },
1012
- {
1013
- type: 'input',
1014
- name: 'abi',
1015
- message: 'ABI file (path)',
1016
- skip: () => abiFromFile === false,
1017
- },
1018
- {
1019
- type: 'input',
1020
- name: 'contractName',
1021
- message: 'Contract Name',
1022
- initial: 'Contract',
1023
- validate: (value: string) => value && value.length > 0,
1024
- },
1025
- ];
1026
-
1027
- // Get the cwd before process.chdir in order to switch back in the end of command execution
1028
- const cwd = process.cwd();
1029
-
1030
- try {
1031
- const { abi, contract, contractName } = await toolbox.prompt.ask(
1032
- // @ts-expect-error questions do somehow fit
1033
- questions,
1034
- );
1035
-
1036
- if (fs.existsSync(directory)) {
1037
- process.chdir(directory);
1038
- }
1039
-
1040
- const commandLine = ['add', contract, '--contract-name', contractName];
1041
-
1042
- if (abiFromFile) {
1043
- if (abi.includes(directory)) {
1044
- commandLine.push('--abi', path.normalize(abi.replace(directory, '')));
1045
- } else {
1046
- commandLine.push('--abi', abi);
1047
- }
1048
- }
1049
-
1050
- await graphCli.run(commandLine);
1051
- } catch (e) {
1052
- toolbox.print.error(e);
1053
- process.exit(1);
1054
- } finally {
1055
- process.chdir(cwd);
1056
- }
1057
- }
1058
-
1059
- return addContractConfirmation;
1060
- };