@graphprotocol/graph-cli 0.29.2 → 0.30.0

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 (85) hide show
  1. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/chain/arweave.ts +76 -0
  2. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/chain/cosmos.ts +341 -0
  3. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/chain/ethereum.ts +39 -0
  4. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/global/global.ts +286 -142
  5. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/index.ts +4 -2
  6. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/package.json +2 -1
  7. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/test/test.js +4 -2
  8. package/examples/basic-event-handlers/node_modules/keccak/build/config.gypi +300 -125
  9. package/examples/basic-event-handlers/node_modules/websocket/build/config.gypi +292 -15
  10. package/examples/basic-event-handlers/package.json +1 -1
  11. package/examples/basic-event-handlers/yarn.lock +4 -4
  12. package/examples/example-subgraph/package.json +1 -1
  13. package/examples/example-subgraph/yarn.lock +4 -4
  14. package/package.json +1 -1
  15. package/resources/test/docker-compose.yml +4 -2
  16. package/src/codegen/schema.js +5 -1
  17. package/src/codegen/schema.test.js +102 -0
  18. package/src/command-helpers/abi.js +69 -0
  19. package/src/command-helpers/scaffold.js +67 -0
  20. package/src/commands/add.js +198 -0
  21. package/src/commands/deploy.js +0 -5
  22. package/src/commands/init.js +25 -71
  23. package/src/migrations/mapping_api_version_0_0_5.js +1 -1
  24. package/src/migrations/mapping_api_version_0_0_6.js +74 -0
  25. package/src/migrations/spec_version_0_0_2.js +1 -1
  26. package/src/migrations/spec_version_0_0_3.js +29 -0
  27. package/src/migrations/spec_version_0_0_4.js +25 -0
  28. package/src/migrations.js +4 -0
  29. package/src/protocols/arweave/manifest.graphql +57 -0
  30. package/src/protocols/arweave/scaffold/manifest.js +19 -0
  31. package/src/protocols/arweave/scaffold/mapping.js +53 -0
  32. package/src/protocols/arweave/subgraph.js +20 -0
  33. package/src/protocols/{tendermint → cosmos}/manifest.graphql +6 -0
  34. package/src/protocols/cosmos/scaffold/manifest.js +16 -0
  35. package/src/protocols/cosmos/scaffold/mapping.js +39 -0
  36. package/src/protocols/{tendermint → cosmos}/subgraph.js +2 -1
  37. package/src/protocols/ethereum/codegen/abi.js +12 -0
  38. package/src/protocols/ethereum/manifest.graphql +2 -0
  39. package/src/protocols/ethereum/scaffold/manifest.js +2 -1
  40. package/src/protocols/index.js +53 -20
  41. package/src/protocols/near/manifest.graphql +1 -0
  42. package/src/protocols/near/scaffold/manifest.js +4 -2
  43. package/src/scaffold/cosmos.test.js +86 -0
  44. package/src/scaffold/ethereum.test.js +2 -1
  45. package/src/scaffold/index.js +5 -3
  46. package/src/scaffold/near.test.js +2 -1
  47. package/src/validation/manifest.js +64 -12
  48. package/src/validation/schema.js +2 -0
  49. package/tests/cli/validation/conflicting-protocol-names/Abi.json +7 -0
  50. package/tests/cli/validation/conflicting-protocol-names/mapping.ts +0 -0
  51. package/tests/cli/validation/conflicting-protocol-names/schema.graphql +3 -0
  52. package/tests/cli/validation/conflicting-protocol-names/subgraph.yaml +41 -0
  53. package/tests/cli/validation/conflicting-protocol-names.stderr +10 -0
  54. package/tests/cli/validation.test.js +9 -0
  55. package/examples/basic-event-handlers/node_modules/@graphprotocol/graph-ts/chain/tendermint.ts +0 -554
  56. package/examples/basic-event-handlers/node_modules/keccak/build/Makefile +0 -342
  57. package/examples/basic-event-handlers/node_modules/keccak/build/Release/.deps/Release/obj.target/keccak/src/addon.o.d.raw +0 -27
  58. package/examples/basic-event-handlers/node_modules/keccak/build/binding.Makefile +0 -6
  59. package/examples/basic-event-handlers/node_modules/keccak/build/gyp-mac-tool +0 -615
  60. package/examples/basic-event-handlers/node_modules/keccak/build/keccak.target.mk +0 -209
  61. package/examples/basic-event-handlers/node_modules/websocket/build/Makefile +0 -347
  62. package/examples/basic-event-handlers/node_modules/websocket/build/Release/.deps/Release/obj.target/bufferutil/src/bufferutil.o.d.raw +0 -25
  63. package/examples/basic-event-handlers/node_modules/websocket/build/binding.Makefile +0 -6
  64. package/examples/basic-event-handlers/node_modules/websocket/build/bufferutil.target.mk +0 -192
  65. package/examples/basic-event-handlers/node_modules/websocket/build/gyp-mac-tool +0 -615
  66. package/examples/basic-event-handlers/node_modules/websocket/build/validation.target.mk +0 -192
  67. package/src/codegen/types/defaults.js +0 -34
  68. package/tests/cli/init/ethereum/from-example/.gitattributes +0 -1
  69. package/tests/cli/init/ethereum/from-example/LICENSE +0 -21
  70. package/tests/cli/init/ethereum/from-example/README.md +0 -3
  71. package/tests/cli/init/ethereum/from-example/abis/Gravity.json +0 -1
  72. package/tests/cli/init/ethereum/from-example/bin/Counter.bin +0 -1
  73. package/tests/cli/init/ethereum/from-example/contracts/Gravity.sol +0 -63
  74. package/tests/cli/init/ethereum/from-example/contracts/Migrations.sol +0 -23
  75. package/tests/cli/init/ethereum/from-example/docker-compose.yml +0 -39
  76. package/tests/cli/init/ethereum/from-example/migrations/1_initial_migration.js +0 -5
  77. package/tests/cli/init/ethereum/from-example/migrations/2_deploy_contract.js +0 -5
  78. package/tests/cli/init/ethereum/from-example/migrations/3_create_gravatars.js +0 -15
  79. package/tests/cli/init/ethereum/from-example/networks.json +0 -7
  80. package/tests/cli/init/ethereum/from-example/package.json +0 -23
  81. package/tests/cli/init/ethereum/from-example/schema.graphql +0 -6
  82. package/tests/cli/init/ethereum/from-example/src/mapping.ts +0 -22
  83. package/tests/cli/init/ethereum/from-example/subgraph.yaml +0 -27
  84. package/tests/cli/init/ethereum/from-example/truffle.js +0 -27
  85. package/tests/cli/init/ethereum/from-example/yarn.lock +0 -5977
@@ -1,8 +1,28 @@
1
1
  const fs = require('fs-extra')
2
2
  const path = require('path')
3
+ const prettier = require('prettier')
4
+ const yaml = require('yaml')
3
5
 
4
6
  const { step } = require('./spinner')
5
7
  const Scaffold = require('../scaffold')
8
+ const { generateEventIndexingHandlers } = require('../scaffold/mapping')
9
+ const { generateEventType, abiEvents } = require('../scaffold/schema')
10
+ const { strings } = require('gluegun')
11
+ const { Map } = require('immutable')
12
+
13
+ const generateDataSource = async (protocol, contractName, network, contractAddress, abi) => {
14
+ const protocolManifest = protocol.getManifestScaffold()
15
+
16
+ return Map.of(
17
+ 'kind', protocol.name,
18
+ 'name', contractName,
19
+ 'network', network,
20
+ 'source', yaml.parse(prettier.format(protocolManifest.source({contract: contractAddress, contractName}),
21
+ {parser: 'yaml'})),
22
+ 'mapping', yaml.parse(prettier.format(protocolManifest.mapping({abi, contractName}),
23
+ {parser: 'yaml'}))
24
+ ).asMutable()
25
+ }
6
26
 
7
27
  const generateScaffold = async (
8
28
  {
@@ -13,6 +33,7 @@ const generateScaffold = async (
13
33
  subgraphName,
14
34
  indexEvents,
15
35
  contractName = 'Contract',
36
+ dataSourceName,
16
37
  node,
17
38
  },
18
39
  spinner,
@@ -27,6 +48,7 @@ const generateScaffold = async (
27
48
  network,
28
49
  contractName,
29
50
  subgraphName,
51
+ dataSourceName,
30
52
  node,
31
53
  })
32
54
 
@@ -59,8 +81,53 @@ const writeScaffold = async (scaffold, directory, spinner) => {
59
81
  await writeScaffoldDirectory(scaffold, directory, spinner)
60
82
  }
61
83
 
84
+ const writeABI = async (abi, contractName, abiPath = `./abis/${contractName}.json`) => {
85
+ let data = prettier.format(JSON.stringify(abi.data), {
86
+ parser: 'json',
87
+ })
88
+
89
+ await fs.writeFile(abiPath, data, { encoding: 'utf-8' })
90
+ }
91
+
92
+ const writeSchema = async (abi, protocol, schemaPath, entities) => {
93
+ const events = protocol.hasEvents()
94
+ ? abiEvents(abi).filter(event => entities.indexOf(event.get('name')) === -1).toJS()
95
+ : []
96
+
97
+ let data = prettier.format(
98
+ events.map(
99
+ event => generateEventType(event, protocol.name)
100
+ ).join('\n\n'),
101
+ {
102
+ parser: 'graphql',
103
+ },
104
+ )
105
+
106
+ await fs.appendFile(schemaPath, data, { encoding: 'utf-8' })
107
+ }
108
+
109
+ const writeMapping = async (abi, protocol, contractName, entities) => {
110
+ const events = protocol.hasEvents()
111
+ ? abiEvents(abi).filter(event => entities.indexOf(event.get('name')) === -1).toJS()
112
+ : []
113
+
114
+ let mapping = prettier.format(
115
+ generateEventIndexingHandlers(
116
+ events,
117
+ contractName,
118
+ ),
119
+ { parser: 'typescript', semi: false },
120
+ )
121
+
122
+ await fs.writeFile(`./src/${strings.kebabCase(contractName)}.ts`, mapping, { encoding: 'utf-8' })
123
+ }
124
+
62
125
  module.exports = {
63
126
  ...module.exports,
64
127
  generateScaffold,
65
128
  writeScaffold,
129
+ generateDataSource,
130
+ writeABI,
131
+ writeSchema,
132
+ writeMapping,
66
133
  }
@@ -0,0 +1,198 @@
1
+ const chalk = require('chalk')
2
+ const toolbox = require('gluegun/toolbox')
3
+ const immutable = require('immutable')
4
+ const { withSpinner } = require('../command-helpers/spinner')
5
+ const Subgraph = require('../subgraph')
6
+ const Protocol = require('../protocols')
7
+ const DataSourcesExtractor = require('../command-helpers/data-sources')
8
+ const { generateDataSource, writeABI, writeSchema, writeMapping } = require('../command-helpers/scaffold')
9
+ const { loadAbiFromEtherscan, loadAbiFromBlockScout } = require('../command-helpers/abi')
10
+ const EthereumABI = require('../protocols/ethereum/abi')
11
+ const { fixParameters } = require('../command-helpers/gluegun')
12
+
13
+ const HELP = `
14
+ ${chalk.bold('graph add')} <address> [<subgraph-manifest default: "./subgraph.yaml">]
15
+
16
+ ${chalk.dim('Options:')}
17
+
18
+ --abi <path> Path to the contract ABI (default: download from Etherscan)
19
+ --contract-name Name of the contract (default: Contract)
20
+ --merge-entities Whether to merge entities with the same name (default: false)
21
+ -h, --help Show usage information
22
+ `
23
+
24
+ module.exports = {
25
+ description: 'Creates a new subgraph with basic scaffolding',
26
+ run: async toolbox => {
27
+ // Obtain tools
28
+ let { print, system } = toolbox
29
+
30
+ // Read CLI parameters
31
+ let {
32
+ abi,
33
+ contractName,
34
+ h,
35
+ help,
36
+ mergeEntities
37
+ } = toolbox.parameters.options
38
+
39
+ let address = toolbox.parameters.first
40
+ let manifestPath = toolbox.parameters.second || './subgraph.yaml'
41
+ contractName = contractName || 'Contract'
42
+
43
+ // Validate the address
44
+ if (!address) {
45
+ print.error('No contract address provided')
46
+ process.exitCode = 1
47
+ return
48
+ }
49
+
50
+ try {
51
+ fixParameters(toolbox.parameters, {
52
+ h,
53
+ help,
54
+ mergeEntities,
55
+ })
56
+ } catch (e) {
57
+ print.error(e.message)
58
+ process.exitCode = 1
59
+ return
60
+ }
61
+
62
+ // Show help text if requested
63
+ if (help || h) {
64
+ print.info(HELP)
65
+ return
66
+ }
67
+
68
+ const dataSourcesAndTemplates = await DataSourcesExtractor.fromFilePath(manifestPath)
69
+ let protocol = Protocol.fromDataSources(dataSourcesAndTemplates)
70
+ let manifest = await Subgraph.load(manifestPath, { protocol })
71
+ let network = manifest.result.get('dataSources').get(0).get('network')
72
+ let result = manifest.result.asMutable()
73
+
74
+ let entities = getEntities(manifest)
75
+ let contractNames = getContractNames(manifest)
76
+ if (contractNames.indexOf(contractName) !== -1) {
77
+ print.error(
78
+ `Datasource or template with name ${contractName} already exists, please choose a different name`,
79
+ )
80
+ process.exitCode = 1
81
+ return
82
+ }
83
+
84
+ let ethabi = null
85
+ if (abi) {
86
+ ethabi = EthereumABI.load(contractName, abi)
87
+ } else {
88
+ if (network === 'poa-core') {
89
+ ethabi = await loadAbiFromBlockScout(EthereumABI, network, address)
90
+ } else {
91
+ ethabi = await loadAbiFromEtherscan(EthereumABI, network, address)
92
+ }
93
+ }
94
+
95
+ let { collisionEntities, onlyCollisions, abiData } = updateEventNamesOnCollision(ethabi, entities, contractName, mergeEntities)
96
+ ethabi.data = abiData
97
+
98
+ await writeABI(ethabi, contractName, abi)
99
+ await writeSchema(ethabi, protocol, result.getIn(['schema', 'file']), collisionEntities)
100
+ await writeMapping(ethabi, protocol, contractName, collisionEntities)
101
+
102
+ let dataSources = result.get('dataSources')
103
+ let dataSource = await generateDataSource(protocol,
104
+ contractName, network, address, ethabi)
105
+
106
+ // Handle the collisions edge case by copying another data source yaml data
107
+ if (mergeEntities && onlyCollisions) {
108
+ let firstDataSource = dataSources.get(0)
109
+ let source = dataSource.get('source')
110
+ let mapping = firstDataSource.get('mapping').asMutable()
111
+
112
+ // Save the address of the new data source
113
+ source.abi = firstDataSource.get('source').get('abi')
114
+
115
+ dataSource.set('mapping', mapping)
116
+ dataSource.set('source', source)
117
+ }
118
+
119
+ result.set('dataSources', dataSources.push(dataSource))
120
+
121
+ await Subgraph.write(result, manifestPath)
122
+
123
+ // Detect Yarn and/or NPM
124
+ let yarn = await system.which('yarn')
125
+ let npm = await system.which('npm')
126
+ if (!yarn && !npm) {
127
+ print.error(
128
+ `Neither Yarn nor NPM were found on your system. Please install one of them.`,
129
+ )
130
+ process.exitCode = 1
131
+ return
132
+ }
133
+
134
+ await withSpinner(
135
+ 'Running codegen',
136
+ 'Failed to run codegen',
137
+ 'Warning during codegen',
138
+ async spinner => {
139
+ await system.run(yarn ? 'yarn codegen' : 'npm run codegen')
140
+ }
141
+ )
142
+ }
143
+ }
144
+
145
+ const getEntities = (manifest) => {
146
+ let dataSources = manifest.result.get('dataSources', immutable.List())
147
+ let templates = manifest.result.get('templates', immutable.List())
148
+
149
+ return dataSources
150
+ .concat(templates)
151
+ .map(dataSource => dataSource.getIn(['mapping', 'entities']))
152
+ .flatten()
153
+ }
154
+
155
+ const getContractNames = (manifest) => {
156
+ let dataSources = manifest.result.get('dataSources', immutable.List())
157
+ let templates = manifest.result.get('templates', immutable.List())
158
+
159
+ return dataSources
160
+ .concat(templates)
161
+ .map(dataSource => dataSource.get('name'))
162
+ }
163
+
164
+ const updateEventNamesOnCollision = (ethabi, entities, contractName, mergeEntities) => {
165
+ let abiData = ethabi.data
166
+ let { print } = toolbox
167
+ let collisionEntities = []
168
+ let onlyCollisions = true
169
+
170
+ for (let i = 0; i < abiData.size; i++) {
171
+ let dataRow = abiData.get(i).asMutable()
172
+
173
+ if (dataRow.get('type') === 'event'){
174
+ if (entities.indexOf(dataRow.get('name')) !== -1) {
175
+ if (entities.indexOf(`${contractName}${dataRow.get('name')}`) !== -1) {
176
+ print.error(`Contract name ('${contractName}')
177
+ + event name ('${dataRow.get('name')}') entity already exists.`)
178
+ process.exitCode = 1
179
+ return
180
+ }
181
+
182
+ if (mergeEntities) {
183
+ collisionEntities.push(dataRow.get('name'))
184
+ abiData = abiData.asImmutable().delete(i) // needs to be immutable when deleting, yes you read that right - https://github.com/immutable-js/immutable-js/issues/1901
185
+ i-- // deletion also shifts values to the left
186
+ continue
187
+ } else {
188
+ dataRow.set('name', `${contractName}${dataRow.get('name')}`)
189
+ }
190
+ } else {
191
+ onlyCollisions = false
192
+ }
193
+ }
194
+ abiData = abiData.asMutable().set(i, dataRow)
195
+ }
196
+
197
+ return { abiData, collisionEntities, onlyCollisions }
198
+ }
@@ -294,7 +294,6 @@ $ graph create --node ${node} ${subgraphName}`)
294
294
  const base = requestUrl.protocol + '//' + requestUrl.hostname
295
295
  let playground = res.playground
296
296
  let queries = res.queries
297
- let subscriptions = res.subscriptions
298
297
 
299
298
  // Add a base URL if graph-node did not return the full URL
300
299
  if (playground.charAt(0) === ':') {
@@ -303,9 +302,6 @@ $ graph create --node ${node} ${subgraphName}`)
303
302
  if (queries.charAt(0) === ':') {
304
303
  queries = base + queries
305
304
  }
306
- if (subscriptions.charAt(0) === ':') {
307
- subscriptions = base + subscriptions
308
- }
309
305
 
310
306
  if (isHostedService) {
311
307
  print.success(
@@ -318,7 +314,6 @@ $ graph create --node ${node} ${subgraphName}`)
318
314
  }
319
315
  print.info('\nSubgraph endpoints:')
320
316
  print.info(`Queries (HTTP): ${queries}`)
321
- print.info(`Subscriptions (WS): ${subscriptions}`)
322
317
  print.info(``)
323
318
  }
324
319
  },
@@ -16,6 +16,7 @@ const { initNetworksConfig } = require('../command-helpers/network')
16
16
  const { withSpinner, step } = require('../command-helpers/spinner')
17
17
  const { fixParameters } = require('../command-helpers/gluegun')
18
18
  const { chooseNodeUrl } = require('../command-helpers/node')
19
+ const { loadAbiFromEtherscan, loadAbiFromBlockScout } = require('../command-helpers/abi')
19
20
  const { generateScaffold, writeScaffold } = require('../command-helpers/scaffold')
20
21
  const { abiEvents } = require('../scaffold/schema')
21
22
  const { validateContract } = require('../validation')
@@ -57,6 +58,11 @@ ${chalk.dim.underline('NEAR:')}
57
58
 
58
59
  --network <${availableNetworks.get('near').join('|')}>
59
60
  Selects the network the contract is deployed to
61
+
62
+ ${chalk.dim.underline('Cosmos:')}
63
+
64
+ --network <${availableNetworks.get('cosmos').join('|')}>
65
+ Selects the network the contract is deployed to
60
66
  `
61
67
 
62
68
  const processInitForm = async (
@@ -169,6 +175,11 @@ const processInitForm = async (
169
175
  return value
170
176
  },
171
177
  },
178
+ // TODO:
179
+ //
180
+ // protocols that don't support contract
181
+ // - arweave
182
+ // - tendermint
172
183
  {
173
184
  type: 'input',
174
185
  name: 'contract',
@@ -176,10 +187,10 @@ const processInitForm = async (
176
187
  ProtocolContract = protocolInstance.getContract()
177
188
  return `Contract ${ProtocolContract.identifierName()}`
178
189
  },
179
- skip: fromExample !== undefined,
190
+ skip: () => fromExample !== undefined || !protocolInstance.hasContract(),
180
191
  initial: contract,
181
192
  validate: async value => {
182
- if (fromExample !== undefined) {
193
+ if (fromExample !== undefined || !protocolInstance.hasContract()) {
183
194
  return true
184
195
  }
185
196
 
@@ -237,11 +248,11 @@ const processInitForm = async (
237
248
  name: 'contractName',
238
249
  message: 'Contract Name',
239
250
  initial: contractName || 'Contract',
240
- skip: () => fromExample !== undefined,
251
+ skip: () => fromExample !== undefined || !protocolInstance.hasContract(),
241
252
  validate: value => value && value.length > 0,
242
253
  result: value => {
243
- contractName = value;
244
- return value;
254
+ contractName = value
255
+ return value
245
256
  }
246
257
  },
247
258
  ]
@@ -254,67 +265,6 @@ const processInitForm = async (
254
265
  }
255
266
  }
256
267
 
257
- const loadAbiFromBlockScout = async (ABI, network, address) =>
258
- await withSpinner(
259
- `Fetching ABI from BlockScout`,
260
- `Failed to fetch ABI from BlockScout`,
261
- `Warnings while fetching ABI from BlockScout`,
262
- async spinner => {
263
- let result = await fetch(
264
- `https://blockscout.com/${
265
- network.replace('-', '/')
266
- }/api?module=contract&action=getabi&address=${address}`,
267
- )
268
- let json = await result.json()
269
-
270
- // BlockScout returns a JSON object that has a `status`, a `message` and
271
- // a `result` field. The `status` is '0' in case of errors and '1' in
272
- // case of success
273
- if (json.status === '1') {
274
- return new ABI('Contract', undefined, immutable.fromJS(JSON.parse(json.result)))
275
- } else {
276
- throw new Error('ABI not found, try loading it from a local file')
277
- }
278
- },
279
- )
280
-
281
- const getEtherscanLikeAPIUrl = (network) => {
282
- switch(network){
283
- case "mainnet": return `https://api.etherscan.io/api`;
284
- case "arbitrum-one": return `https://api.arbiscan.io/api`;
285
- case "bsc": return `https://api.bscscan.com/api`;
286
- case "matic": return `https://api.polygonscan.com/api`;
287
- case "mumbai": return `https://api-testnet.polygonscan.com/api`;
288
- case "aurora": return `https://api.aurorascan.dev/api`;
289
- case "aurora-testnet": return `https://api-testnet.aurorascan.dev/api`;
290
- case "optimism-kovan": return `https://api-kovan-optimistic.etherscan.io/api`;
291
- default: return `https://api-${network}.etherscan.io/api`;
292
- }
293
- }
294
-
295
- const loadAbiFromEtherscan = async (ABI, network, address) =>
296
- await withSpinner(
297
- `Fetching ABI from Etherscan`,
298
- `Failed to fetch ABI from Etherscan`,
299
- `Warnings while fetching ABI from Etherscan`,
300
- async spinner => {
301
- const scanApiUrl = getEtherscanLikeAPIUrl(network);
302
- let result = await fetch(
303
- `${scanApiUrl}?module=contract&action=getabi&address=${address}`,
304
- )
305
- let json = await result.json()
306
-
307
- // Etherscan returns a JSON object that has a `status`, a `message` and
308
- // a `result` field. The `status` is '0' in case of errors and '1' in
309
- // case of success
310
- if (json.status === '1') {
311
- return new ABI('Contract', undefined, immutable.fromJS(JSON.parse(json.result)))
312
- } else {
313
- throw new Error('ABI not found, try loading it from a local file')
314
- }
315
- },
316
- )
317
-
318
268
  const loadAbiFromFile = async (ABI, filename) => {
319
269
  let exists = await toolbox.filesystem.exists(filename)
320
270
 
@@ -768,6 +718,7 @@ const initSubgraphFromContract = async (
768
718
  contract,
769
719
  indexEvents,
770
720
  contractName,
721
+ dataSourceName,
771
722
  node,
772
723
  studio,
773
724
  product,
@@ -822,6 +773,7 @@ const initSubgraphFromContract = async (
822
773
  contract,
823
774
  indexEvents,
824
775
  contractName,
776
+ dataSourceName,
825
777
  node,
826
778
  },
827
779
  spinner,
@@ -835,11 +787,13 @@ const initSubgraphFromContract = async (
835
787
  return
836
788
  }
837
789
 
838
- let identifierName = protocolInstance.getContract().identifierName()
839
- let networkConf = await initNetworksConfig(toolbox, directory, identifierName)
840
- if (networkConf !== true) {
841
- process.exitCode = 1
842
- return
790
+ if (protocolInstance.hasContract()) {
791
+ let identifierName = protocolInstance.getContract().identifierName()
792
+ let networkConf = await initNetworksConfig(toolbox, directory, identifierName)
793
+ if (networkConf !== true) {
794
+ process.exitCode = 1
795
+ return
796
+ }
843
797
  }
844
798
 
845
799
  // Initialize a fresh Git repository
@@ -21,7 +21,7 @@ module.exports = {
21
21
 
22
22
  let manifest = loadManifest(manifestFile)
23
23
  return (
24
- // Only migrate if the graph-ts version is >= 0.23.0...
24
+ // Only migrate if the graph-ts version is >= 0.24.0...
25
25
  // Coerce needed because we may be dealing with an alpha version
26
26
  // and in the `semver` library this would not return true on equality.
27
27
  semver.gte(semver.coerce(graphTsVersion), '0.24.0') &&
@@ -0,0 +1,74 @@
1
+ const fs = require('fs-extra')
2
+ const semver = require('semver')
3
+ const toolbox = require('gluegun/toolbox')
4
+ const yaml = require('js-yaml')
5
+ const { loadManifest } = require('./util/load-manifest')
6
+ const { getGraphTsVersion } = require('./util/versions')
7
+
8
+ // If any of the manifest apiVersions are 0.0.6, replace them with 0.0.7
9
+ module.exports = {
10
+ name: 'Bump mapping apiVersion from 0.0.6 to 0.0.7',
11
+ predicate: async ({ sourceDir, manifestFile }) => {
12
+ // Obtain the graph-ts version, if possible
13
+ let graphTsVersion
14
+ try {
15
+ graphTsVersion = await getGraphTsVersion(sourceDir)
16
+ } catch (_) {
17
+ // If we cannot obtain the version, return a hint that the graph-ts
18
+ // hasn't been installed yet
19
+ return 'graph-ts dependency not installed yet'
20
+ }
21
+
22
+ let manifest = loadManifest(manifestFile)
23
+ return (
24
+ // Only migrate if the graph-ts version is >= 0.27.0...
25
+ // Coerce needed because we may be dealing with an alpha version
26
+ // and in the `semver` library this would not return true on equality.
27
+ semver.gte(semver.coerce(graphTsVersion), '0.27.0') &&
28
+ // ...and we have a manifest with mapping > apiVersion = 0.0.6
29
+ manifest &&
30
+ typeof manifest === 'object' &&
31
+ Array.isArray(manifest.dataSources) &&
32
+ (manifest.dataSources.reduce(
33
+ (hasOldMappings, dataSource) =>
34
+ hasOldMappings ||
35
+ (typeof dataSource === 'object' &&
36
+ dataSource.mapping &&
37
+ typeof dataSource.mapping === 'object' &&
38
+ dataSource.mapping.apiVersion === '0.0.6'),
39
+ false,
40
+ ) ||
41
+ (Array.isArray(manifest.templates) &&
42
+ manifest.templates.reduce(
43
+ (hasOldMappings, template) =>
44
+ hasOldMappings ||
45
+ (typeof template === 'object' &&
46
+ template.mapping &&
47
+ typeof template.mapping === 'object' &&
48
+ template.mapping.apiVersion === '0.0.6'),
49
+ false,
50
+ )))
51
+ )
52
+ },
53
+ apply: async ({ manifestFile }) => {
54
+ // Make sure we catch all variants; we could load the manifest
55
+ // and replace the values in the data structures here; unfortunately
56
+ // writing that back to the file messes with the formatting more than
57
+ // we'd like; that's why for now, we use a simple patching approach
58
+ await toolbox.patching.replace(
59
+ manifestFile,
60
+ new RegExp('apiVersion: 0.0.6', 'g'),
61
+ 'apiVersion: 0.0.7',
62
+ )
63
+ await toolbox.patching.replace(
64
+ manifestFile,
65
+ new RegExp("apiVersion: '0.0.6'", 'g'),
66
+ "apiVersion: '0.0.7'",
67
+ )
68
+ await toolbox.patching.replace(
69
+ manifestFile,
70
+ new RegExp('apiVersion: "0.0.6"', 'g'),
71
+ 'apiVersion: "0.0.7"',
72
+ )
73
+ },
74
+ }
@@ -6,7 +6,7 @@ const { loadManifest } = require('./util/load-manifest')
6
6
  // Spec version to 0.0.2 uses top level templates. graph-cli no longer supports
7
7
  // 0.0.1 which used nested templates.
8
8
  module.exports = {
9
- name: 'Bump mapping specVersion from 0.0.1 to 0.0.2',
9
+ name: 'Bump manifest specVersion from 0.0.1 to 0.0.2',
10
10
  predicate: async ({ sourceDir, manifestFile }) => {
11
11
  let manifest = await loadManifest(manifestFile)
12
12
  return (
@@ -0,0 +1,29 @@
1
+ const fs = require('fs-extra')
2
+ const toolbox = require('gluegun/toolbox')
3
+ const yaml = require('js-yaml')
4
+ const { loadManifest } = require('./util/load-manifest')
5
+
6
+ // Spec version 0.0.4 uses feature management, but features are
7
+ // detected and validated by the graph-node instance during subgraph
8
+ // deployment.
9
+ //
10
+ // Also, we skip spec version 0.0.3, which is considered invalid and
11
+ // non-canonical.
12
+ module.exports = {
13
+ name: 'Bump manifest specVersion from 0.0.2 to 0.0.4',
14
+ predicate: async ({ sourceDir, manifestFile }) => {
15
+ let manifest = await loadManifest(manifestFile)
16
+ return (
17
+ manifest &&
18
+ typeof manifest === 'object' &&
19
+ manifest.specVersion &&
20
+ (manifest.specVersion === '0.0.2' || manifest.specVersion === '0.0.3')
21
+ )
22
+ },
23
+ apply: async ({ manifestFile }) => {
24
+ await toolbox.patching.patch(manifestFile, {
25
+ insert: 'specVersion: 0.0.4',
26
+ replace: new RegExp(`specVersion: ['"]?0.0.[23]['"]?`),
27
+ })
28
+ },
29
+ }
@@ -0,0 +1,25 @@
1
+ const fs = require('fs-extra')
2
+ const toolbox = require('gluegun/toolbox')
3
+ const yaml = require('js-yaml')
4
+ const { loadManifest } = require('./util/load-manifest')
5
+
6
+ // Spec version 0.0.5 let event handlers require transaction receipt
7
+ // data to be accessed in the runtime.
8
+ module.exports = {
9
+ name: 'Bump manifest specVersion from 0.0.4 to 0.0.5',
10
+ predicate: async ({ sourceDir, manifestFile }) => {
11
+ let manifest = await loadManifest(manifestFile)
12
+ return (
13
+ manifest &&
14
+ typeof manifest === 'object' &&
15
+ manifest.specVersion &&
16
+ manifest.specVersion === '0.0.4'
17
+ )
18
+ },
19
+ apply: async ({ manifestFile }) => {
20
+ await toolbox.patching.patch(manifestFile, {
21
+ insert: 'specVersion: 0.0.5',
22
+ replace: new RegExp(`specVersion: ['"]?0.0.4['"]?`),
23
+ })
24
+ },
25
+ }
package/src/migrations.js CHANGED
@@ -5,7 +5,11 @@ const MIGRATIONS = [
5
5
  require('./migrations/mapping_api_version_0_0_2'),
6
6
  require('./migrations/mapping_api_version_0_0_3'),
7
7
  require('./migrations/mapping_api_version_0_0_4'),
8
+ require('./migrations/mapping_api_version_0_0_5'),
9
+ require('./migrations/mapping_api_version_0_0_6'),
8
10
  require('./migrations/spec_version_0_0_2'),
11
+ require('./migrations/spec_version_0_0_3'),
12
+ require('./migrations/spec_version_0_0_4'),
9
13
  ]
10
14
 
11
15
  const applyMigrations = async options =>