@graphprotocol/graph-cli 0.27.1 → 0.28.2

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 (35) hide show
  1. package/README.md +6 -6
  2. package/examples/basic-event-handlers/package.json +1 -1
  3. package/examples/basic-event-handlers/yarn.lock +4 -4
  4. package/examples/example-subgraph/package.json +1 -1
  5. package/examples/example-subgraph/yarn.lock +4 -4
  6. package/package.json +1 -1
  7. package/src/codegen/schema.js +105 -26
  8. package/src/codegen/schema.test.js +2 -6
  9. package/src/commands/codegen.js +1 -1
  10. package/src/commands/deploy.js +1 -1
  11. package/src/commands/init.js +1 -0
  12. package/src/protocols/index.js +34 -0
  13. package/src/protocols/tendermint/manifest.graphql +64 -0
  14. package/src/protocols/tendermint/subgraph.js +20 -0
  15. package/src/scaffold/index.js +1 -1
  16. package/src/subgraph.js +4 -0
  17. package/src/validation/manifest.js +17 -0
  18. package/src/validation/schema.js +120 -119
  19. package/tests/cli/init/ethereum/from-example/.gitattributes +1 -0
  20. package/tests/cli/init/ethereum/from-example/LICENSE +21 -0
  21. package/tests/cli/init/ethereum/from-example/README.md +3 -0
  22. package/tests/cli/init/ethereum/from-example/abis/Gravity.json +1 -0
  23. package/tests/cli/init/ethereum/from-example/bin/Counter.bin +1 -0
  24. package/tests/cli/init/ethereum/from-example/contracts/Gravity.sol +63 -0
  25. package/tests/cli/init/ethereum/from-example/contracts/Migrations.sol +23 -0
  26. package/tests/cli/init/ethereum/from-example/docker-compose.yml +39 -0
  27. package/tests/cli/init/ethereum/from-example/migrations/1_initial_migration.js +5 -0
  28. package/tests/cli/init/ethereum/from-example/migrations/2_deploy_contract.js +5 -0
  29. package/tests/cli/init/ethereum/from-example/migrations/3_create_gravatars.js +15 -0
  30. package/tests/cli/init/ethereum/from-example/package.json +23 -0
  31. package/tests/cli/init/ethereum/from-example/schema.graphql +6 -0
  32. package/tests/cli/init/ethereum/from-example/src/mapping.ts +22 -0
  33. package/tests/cli/init/ethereum/from-example/subgraph.yaml +27 -0
  34. package/tests/cli/init/ethereum/from-example/truffle.js +27 -0
  35. package/tests/cli/init/ethereum/from-example/yarn.lock +5977 -0
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # The Graph CLI (graph-cli)
2
2
 
3
3
  [![npm (scoped)](https://img.shields.io/npm/v/@graphprotocol/graph-cli.svg)](https://www.npmjs.com/package/@graphprotocol/graph-cli)
4
- [![Build Status](https://travis-ci.org/graphprotocol/graph-cli.svg?branch=master)](https://travis-ci.org/graphprotocol/graph-cli)
4
+ [![Build Status](https://travis-ci.org/graphprotocol/graph-cli.svg?branch=main)](https://travis-ci.org/graphprotocol/graph-cli)
5
5
 
6
6
  ## The Graph Command Line Interface
7
7
 
@@ -57,9 +57,9 @@ If you are ready to dive into the details of building a subgraph from scratch, t
57
57
 
58
58
  The steps to create a new version of the `graph-cli` are:
59
59
 
60
- 1. Decide which version number you'll be rolling out. You can check the differences between the current `master` branch and the latest release.
60
+ 1. Decide which version number you'll be rolling out. You can check the differences between the current `main` branch and the latest release.
61
61
  2. Create a PR with the commit generated by `npm version <VERSION> [<PREID>]`.
62
- 3. Once that's approved and merged to `master`, you can publish it to `npm` and push the git tags as well.
62
+ 3. Once that's approved and merged to `main`, you can publish it to `npm` and push the git tags as well.
63
63
  4. Last but not least, create a Github Release refering to the pushed git tag, linking to the PRs involved.
64
64
 
65
65
  Helpful links:
@@ -84,7 +84,7 @@ npm version minor
84
84
  git push --set-upstream <REMOTE> <BRANCH>
85
85
  ```
86
86
 
87
- Once that's approved and merged, you can update your local `master` and:
87
+ Once that's approved and merged, you can update your local `main` and:
88
88
 
89
89
  ```
90
90
  npm publish
@@ -106,7 +106,7 @@ npm version preminor --preid alpha
106
106
  git push --set-upstream <REMOTE> <BRANCH>
107
107
  ```
108
108
 
109
- Once that's approved and merged, you can update your local `master` and:
109
+ Once that's approved and merged, you can update your local `main` and:
110
110
 
111
111
  ```
112
112
  npm publish --tag alpha
@@ -128,7 +128,7 @@ npm version prerelease --preid alpha
128
128
  git push --set-upstream <REMOTE> <BRANCH>
129
129
  ```
130
130
 
131
- Once that's approved and merged, you can update your local `master` and:
131
+ Once that's approved and merged, you can update your local `main` and:
132
132
 
133
133
  ```
134
134
  npm publish --tag alpha
@@ -9,7 +9,7 @@
9
9
  "deploy-test": "../../bin/graph deploy test/basic-event-handlers --version-label v0.0.1 --ipfs http://localhost:15001 --node http://127.0.0.1:18020"
10
10
  },
11
11
  "devDependencies": {
12
- "@graphprotocol/graph-ts": "0.24.1",
12
+ "@graphprotocol/graph-ts": "0.26.0",
13
13
  "apollo-fetch": "^0.7.0"
14
14
  },
15
15
  "dependencies": {
@@ -2,10 +2,10 @@
2
2
  # yarn lockfile v1
3
3
 
4
4
 
5
- "@graphprotocol/graph-ts@0.24.1":
6
- version "0.24.1"
7
- resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.24.1.tgz#50961b52b5383f9c5cf5e6e23fa039f24e729ddf"
8
- integrity sha512-2vU4m5ZPQIqMlMce/z5vmOtGHRlRmcRhMfemS3NIwxCSxSBGVnX2zb7QBTzzdQKGwsAZdbz6V0okkOtvohELfQ==
5
+ "@graphprotocol/graph-ts@0.26.0":
6
+ version "0.26.0"
7
+ resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.26.0.tgz#576f995531eebaca4374901aeaff499219e382e8"
8
+ integrity sha512-GW/emOJl+35MXgmIxTnUK7dJtPCaB9u5aAwoLVqJ8swogC794O92UrXMVrAJsherUriu+yI9bLMGmNPOIi60jw==
9
9
  dependencies:
10
10
  assemblyscript "0.19.10"
11
11
 
@@ -7,7 +7,7 @@
7
7
  "build-wast": "../../bin/graph build -t wast subgraph.yaml"
8
8
  },
9
9
  "devDependencies": {
10
- "@graphprotocol/graph-ts": "0.24.1"
10
+ "@graphprotocol/graph-ts": "0.26.0"
11
11
  },
12
12
  "resolutions": {
13
13
  "assemblyscript": "0.19.10"
@@ -2,10 +2,10 @@
2
2
  # yarn lockfile v1
3
3
 
4
4
 
5
- "@graphprotocol/graph-ts@0.24.1":
6
- version "0.24.1"
7
- resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.24.1.tgz#50961b52b5383f9c5cf5e6e23fa039f24e729ddf"
8
- integrity sha512-2vU4m5ZPQIqMlMce/z5vmOtGHRlRmcRhMfemS3NIwxCSxSBGVnX2zb7QBTzzdQKGwsAZdbz6V0okkOtvohELfQ==
5
+ "@graphprotocol/graph-ts@0.26.0":
6
+ version "0.26.0"
7
+ resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.26.0.tgz#576f995531eebaca4374901aeaff499219e382e8"
8
+ integrity sha512-GW/emOJl+35MXgmIxTnUK7dJtPCaB9u5aAwoLVqJ8swogC794O92UrXMVrAJsherUriu+yI9bLMGmNPOIi60jw==
9
9
  dependencies:
10
10
  assemblyscript "0.19.10"
11
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphprotocol/graph-cli",
3
- "version": "0.27.1",
3
+ "version": "0.28.2",
4
4
  "license": "(Apache-2.0 OR MIT)",
5
5
  "description": "CLI for building for and deploying to The Graph",
6
6
  "dependencies": {
@@ -5,6 +5,53 @@ const typesCodegen = require('./types')
5
5
 
6
6
  const List = immutable.List
7
7
 
8
+ class IdField {
9
+ static BYTES = Symbol("Bytes")
10
+ static STRING = Symbol("String")
11
+
12
+ constructor(idField) {
13
+ const typeName = idField.getIn(['type', 'type', 'name', 'value'])
14
+ this.kind = typeName === "Bytes" ? IdField.BYTES : IdField.STRING
15
+ }
16
+
17
+ typeName() {
18
+ return this.kind === IdField.BYTES ? "Bytes" : "string"
19
+ }
20
+
21
+ gqlTypeName() {
22
+ return this.kind === IdField.BYTES ? "Bytes" : "String"
23
+ }
24
+
25
+ tsNamedType() {
26
+ return tsCodegen.namedType(this.typeName())
27
+ }
28
+
29
+ tsValueFrom() {
30
+ return this.kind === IdField.BYTES ? "Value.fromBytes(id)" : "Value.fromString(id)"
31
+ }
32
+
33
+ tsValueKind() {
34
+ return this.kind === IdField.BYTES ? "ValueKind.BYTES" : "ValueKind.STRING"
35
+ }
36
+
37
+ tsValueToString() {
38
+ return this.kind == IdField.BYTES ? "id.toBytes().toHexString()" : "id.toString()"
39
+ }
40
+
41
+ tsToString() {
42
+ return this.kind == IdField.BYTES ? "id.toHexString()" : "id"
43
+ }
44
+
45
+ static fromFields(fields) {
46
+ const idField = fields.find(field => field.getIn(['name', 'value']) === 'id')
47
+ return new IdField(idField)
48
+ }
49
+
50
+ static fromTypeDef(def) {
51
+ return IdField.fromFields(def.get("fields"))
52
+ }
53
+ }
54
+
8
55
  module.exports = class SchemaCodeGenerator {
9
56
  constructor(schema) {
10
57
  this.schema = schema
@@ -52,12 +99,14 @@ module.exports = class SchemaCodeGenerator {
52
99
  _generateEntityType(def) {
53
100
  let name = def.getIn(['name', 'value'])
54
101
  let klass = tsCodegen.klass(name, { export: true, extends: 'Entity' })
102
+ const fields = def.get('fields')
103
+ const idField = IdField.fromFields(fields)
55
104
 
56
105
  // Generate and add a constructor
57
- klass.addMethod(this._generateConstructor(name))
106
+ klass.addMethod(this._generateConstructor(name, fields))
58
107
 
59
108
  // Generate and add save() and getById() methods
60
- this._generateStoreMethods(name).forEach(method => klass.addMethod(method))
109
+ this._generateStoreMethods(name, idField).forEach(method => klass.addMethod(method))
61
110
 
62
111
  // Generate and add entity field getters and setters
63
112
  def
@@ -71,19 +120,20 @@ module.exports = class SchemaCodeGenerator {
71
120
  return klass
72
121
  }
73
122
 
74
- _generateConstructor(entityName) {
123
+ _generateConstructor(entityName, fields) {
124
+ const idField = IdField.fromFields(fields)
75
125
  return tsCodegen.method(
76
126
  'constructor',
77
- [tsCodegen.param('id', tsCodegen.namedType('string'))],
127
+ [tsCodegen.param('id', idField.tsNamedType())],
78
128
  undefined,
79
129
  `
80
130
  super()
81
- this.set('id', Value.fromString(id))
131
+ this.set('id', ${idField.tsValueFrom()})
82
132
  `,
83
133
  )
84
134
  }
85
135
 
86
- _generateStoreMethods(entityName) {
136
+ _generateStoreMethods(entityName, idField) {
87
137
  return List.of(
88
138
  tsCodegen.method(
89
139
  'save',
@@ -91,23 +141,21 @@ module.exports = class SchemaCodeGenerator {
91
141
  tsCodegen.namedType('void'),
92
142
  `
93
143
  let id = this.get('id')
94
- assert(id != null, 'Cannot save ${entityName} entity without an ID')
144
+ assert(id != null,
145
+ 'Cannot save ${entityName} entity without an ID')
95
146
  if (id) {
96
- assert(
97
- id.kind == ValueKind.STRING,
98
- 'Cannot save ${entityName} entity with non-string ID. ' +
99
- 'Considering using .toHex() to convert the "id" to a string.'
100
- )
101
- store.set('${entityName}', id.toString(), this)
147
+ assert(id.kind == ${idField.tsValueKind()},
148
+ \`Entities of type ${entityName} must have an ID of type ${idField.gqlTypeName()} but the id '\${id.displayData()}' is of type \${id.displayKind()}\`)
149
+ store.set('${entityName}', ${idField.tsValueToString()}, this)
102
150
  }`,
103
151
  ),
104
152
 
105
153
  tsCodegen.staticMethod(
106
154
  'load',
107
- [tsCodegen.param('id', tsCodegen.namedType('string'))],
155
+ [tsCodegen.param('id', tsCodegen.namedType(idField.typeName()))],
108
156
  tsCodegen.nullableType(tsCodegen.namedType(entityName)),
109
157
  `
110
- return changetype<${entityName} | null>(store.get('${entityName}', id))
158
+ return changetype<${entityName} | null>(store.get('${entityName}', ${idField.tsToString()}))
111
159
  `,
112
160
  ),
113
161
  )
@@ -158,13 +206,12 @@ module.exports = class SchemaCodeGenerator {
158
206
  isArray &&
159
207
  paramType.inner instanceof tsCodegen.NullableType
160
208
  ) {
161
- let arrayTypeWithoutClosingBracked = fieldValueType.slice(0, -1)
162
- let suggestedType = `${arrayTypeWithoutClosingBracked}!]`
209
+ let baseType = this._baseType(gqlType)
163
210
 
164
211
  throw new Error(`
165
212
  GraphQL schema can't have List's with Nullable members.
166
- Error in '${name}' field of type '${fieldValueType}'.
167
- Suggestion: add an '!' to the member type of the List, change from '${fieldValueType}' to '${suggestedType}'`
213
+ Error in '${name}' field of type '[${baseType}]'.
214
+ Suggestion: add an '!' to the member type of the List, change from '[${baseType}]' to '[${baseType}!]'`
168
215
  )
169
216
  }
170
217
 
@@ -176,7 +223,7 @@ Suggestion: add an '!' to the member type of the List, change from '${fieldValue
176
223
  this.unset('${name}')
177
224
  } else {
178
225
  this.set('${name}', ${typesCodegen.valueFromAsc(
179
- `<${paramTypeString}>value`,
226
+ `<${paramTypeString}>value`,
180
227
  fieldValueType,
181
228
  )})
182
229
  }
@@ -190,12 +237,44 @@ Suggestion: add an '!' to the member type of the List, change from '${fieldValue
190
237
  )
191
238
  }
192
239
 
240
+ _resolveFieldType(gqlType) {
241
+ let typeName = gqlType.getIn(['name', 'value'])
242
+
243
+ // If this is a reference to another type, the field has the type of
244
+ // the referred type's id field
245
+ const typeDef = this.schema.ast.get("definitions").
246
+ find(def => this._isEntityTypeDefinition(def) && def.getIn(["name", "value"]) === typeName)
247
+ if (typeDef) {
248
+ return IdField.fromTypeDef(typeDef).typeName()
249
+ } else {
250
+ return typeName
251
+ }
252
+ }
253
+
254
+ /** Return the type that values for this field must have. For scalar
255
+ * types, that's the type from the subgraph schema. For references to
256
+ * other entity types, this is the same as the type of the id of the
257
+ * referred type, i.e., `string` or `Bytes`*/
193
258
  _valueTypeFromGraphQl(gqlType) {
194
- return gqlType.get('kind') === 'NonNullType'
195
- ? this._valueTypeFromGraphQl(gqlType.get('type'), false)
196
- : gqlType.get('kind') === 'ListType'
197
- ? '[' + this._valueTypeFromGraphQl(gqlType.get('type')) + ']'
198
- : gqlType.getIn(['name', 'value'])
259
+ if (gqlType.get('kind') === 'NonNullType') {
260
+ return this._valueTypeFromGraphQl(gqlType.get('type'), false)
261
+ } else if (gqlType.get('kind') === 'ListType') {
262
+ return '[' + this._valueTypeFromGraphQl(gqlType.get('type')) + ']'
263
+ } else {
264
+ return this._resolveFieldType(gqlType)
265
+ }
266
+ }
267
+
268
+ /** Determine the base type of `gqlType` by removing any non-null
269
+ * constraints and using the type of elements of lists */
270
+ _baseType(gqlType) {
271
+ if (gqlType.get('kind') === 'NonNullType') {
272
+ return this._baseType(gqlType.get('type'))
273
+ } else if (gqlType.get('kind') === 'ListType') {
274
+ return this._baseType(gqlType.get('type'))
275
+ } else {
276
+ return gqlType.getIn(['name', 'value'])
277
+ }
199
278
  }
200
279
 
201
280
  _typeFromGraphQl(gqlType, nullable = true) {
@@ -207,7 +286,7 @@ Suggestion: add an '!' to the member type of the List, change from '${fieldValue
207
286
  } else {
208
287
  // NamedType
209
288
  let type = tsCodegen.namedType(
210
- typesCodegen.ascTypeForValue(gqlType.getIn(['name', 'value'])),
289
+ typesCodegen.ascTypeForValue(this._resolveFieldType(gqlType)),
211
290
  )
212
291
  // In AssemblyScript, primitives cannot be nullable.
213
292
  return nullable && !type.isPrimitive() ? tsCodegen.nullableType(type) : type
@@ -126,9 +126,7 @@ describe('Schema code generator', () => {
126
126
  if (id) {
127
127
  assert(
128
128
  id.kind == ValueKind.STRING,
129
- 'Cannot save Account entity with non-string ID. ' +
130
- 'Considering using .toHex() to convert the "id" to a string.'
131
- )
129
+ \`Entities of type Account must have an ID of type String but the id '\${id.displayData()}' is of type \${id.displayKind()}\`)
132
130
  store.set('Account', id.toString(), this)
133
131
  }
134
132
  `,
@@ -288,9 +286,7 @@ describe('Schema code generator', () => {
288
286
  if (id) {
289
287
  assert(
290
288
  id.kind == ValueKind.STRING,
291
- 'Cannot save Wallet entity with non-string ID. ' +
292
- 'Considering using .toHex() to convert the "id" to a string.'
293
- )
289
+ \`Entities of type Wallet must have an ID of type String but the id '\${id.displayData()}' is of type \${id.displayKind()}\`)
294
290
  store.set('Wallet', id.toString(), this)
295
291
  }
296
292
  `,
@@ -71,7 +71,7 @@ module.exports = {
71
71
  // because that would mean the CLI would generate code to
72
72
  // the wrong AssemblyScript version.
73
73
  await assertManifestApiVersion(manifest, '0.0.5')
74
- await assertGraphTsVersion(path.dirname(manifest), '0.22.0')
74
+ await assertGraphTsVersion(path.dirname(manifest), '0.25.0')
75
75
 
76
76
  const dataSourcesAndTemplates = await DataSourcesExtractor.fromFilePath(manifest)
77
77
 
@@ -200,7 +200,7 @@ module.exports = {
200
200
  // because that would mean the CLI would try to compile code
201
201
  // using the wrong AssemblyScript compiler.
202
202
  await assertManifestApiVersion(manifest, '0.0.5')
203
- await assertGraphTsVersion(path.dirname(manifest), '0.22.0')
203
+ await assertGraphTsVersion(path.dirname(manifest), '0.25.0')
204
204
 
205
205
  const dataSourcesAndTemplates = await DataSourcesExtractor.fromFilePath(manifest)
206
206
 
@@ -285,6 +285,7 @@ const getEtherscanLikeAPIUrl = (network) => {
285
285
  case "mumbai": return `https://api-testnet.polygonscan.com/api`;
286
286
  case "aurora": return `https://api.aurorascan.dev/api`;
287
287
  case "aurora-testnet": return `https://api-testnet.aurorascan.dev/api`;
288
+ case "optimism-kovan": return `https://api-kovan-optimistic.etherscan.io/api`;
288
289
  default: return `https://api-${network}.etherscan.io/api`;
289
290
  }
290
291
  }
@@ -4,6 +4,7 @@ const EthereumTemplateCodeGen = require('./ethereum/codegen/template')
4
4
  const EthereumABI = require('./ethereum/abi')
5
5
  const EthereumSubgraph = require('./ethereum/subgraph')
6
6
  const NearSubgraph = require('./near/subgraph')
7
+ const TendermintSubgraph = require('./tendermint/subgraph')
7
8
  const EthereumContract = require('./ethereum/contract')
8
9
  const NearContract = require('./near/contract')
9
10
  const EthereumManifestScaffold = require('./ethereum/scaffold/manifest')
@@ -27,6 +28,7 @@ module.exports = class Protocol {
27
28
  // New networks (or protocol perhaps) shouldn't have the `/contract` anymore (unless a new case makes use of it).
28
29
  ethereum: ['ethereum', 'ethereum/contract'],
29
30
  near: ['near'],
31
+ tendermint: ['tendermint']
30
32
  })
31
33
  }
32
34
 
@@ -61,6 +63,7 @@ module.exports = class Protocol {
61
63
  'aurora-testnet',
62
64
  ],
63
65
  near: ['near-mainnet', 'near-testnet'],
66
+ tendermint: ['cosmoshub-4']
64
67
  })
65
68
  }
66
69
 
@@ -76,6 +79,8 @@ module.exports = class Protocol {
76
79
  return 'Ethereum'
77
80
  case 'near':
78
81
  return 'NEAR'
82
+ case 'tendermint':
83
+ return 'Tendermint'
79
84
  }
80
85
  }
81
86
 
@@ -93,6 +98,19 @@ module.exports = class Protocol {
93
98
  return true
94
99
  case 'near':
95
100
  return false
101
+ case 'tendermint':
102
+ return false
103
+ }
104
+ }
105
+
106
+ hasContract() {
107
+ switch (this.name) {
108
+ case 'ethereum':
109
+ return true
110
+ case 'near':
111
+ return true
112
+ case 'tendermint':
113
+ return false
96
114
  }
97
115
  }
98
116
 
@@ -102,6 +120,8 @@ module.exports = class Protocol {
102
120
  return true
103
121
  case 'near':
104
122
  return false
123
+ case 'tendermint':
124
+ return false
105
125
  }
106
126
  }
107
127
 
@@ -111,6 +131,8 @@ module.exports = class Protocol {
111
131
  return true
112
132
  case 'near':
113
133
  return false
134
+ case 'tendermint':
135
+ return false
114
136
  }
115
137
  }
116
138
 
@@ -120,6 +142,8 @@ module.exports = class Protocol {
120
142
  return new EthereumTypeGenerator(options)
121
143
  case 'near':
122
144
  return null
145
+ case 'tendermint':
146
+ return null
123
147
  }
124
148
  }
125
149
 
@@ -144,6 +168,8 @@ module.exports = class Protocol {
144
168
  return EthereumABI
145
169
  case 'near':
146
170
  return null
171
+ case 'tendermint':
172
+ return null
147
173
  }
148
174
  }
149
175
 
@@ -155,6 +181,8 @@ module.exports = class Protocol {
155
181
  return new EthereumSubgraph(optionsWithProtocol)
156
182
  case 'near':
157
183
  return new NearSubgraph(optionsWithProtocol)
184
+ case 'tendermint':
185
+ return new TendermintSubgraph(optionsWithProtocol)
158
186
  default:
159
187
  throw new Error(`Data sources with kind '${this.name}' are not supported yet`)
160
188
  }
@@ -166,6 +194,8 @@ module.exports = class Protocol {
166
194
  return EthereumContract
167
195
  case 'near':
168
196
  return NearContract
197
+ case 'tendermint':
198
+ return null
169
199
  }
170
200
  }
171
201
 
@@ -175,6 +205,8 @@ module.exports = class Protocol {
175
205
  return EthereumManifestScaffold
176
206
  case 'near':
177
207
  return NearManifestScaffold
208
+ case 'tendermint':
209
+ return null
178
210
  }
179
211
  }
180
212
 
@@ -184,6 +216,8 @@ module.exports = class Protocol {
184
216
  return EthereumMappingScaffold
185
217
  case 'near':
186
218
  return NearMappingScaffold
219
+ case 'tendermint':
220
+ return null
187
221
  }
188
222
  }
189
223
  }
@@ -0,0 +1,64 @@
1
+ # Each referenced type's in any of the types below must be listed
2
+ # here either as `scalar` or `type` for the validation code to work
3
+ # properly.
4
+ #
5
+ # That's why `String` is listed as a scalar even though it's built-in
6
+ # GraphQL basic types.
7
+ scalar String
8
+ scalar File
9
+ scalar BigInt
10
+
11
+ type SubgraphManifest {
12
+ specVersion: String!
13
+ schema: Schema!
14
+ description: String
15
+ repository: String
16
+ graft: Graft
17
+ dataSources: [DataSource!]!
18
+ }
19
+
20
+ type Schema {
21
+ file: File!
22
+ }
23
+
24
+ type DataSource {
25
+ kind: String!
26
+ name: String!
27
+ network: String
28
+ source: ContractSource!
29
+ mapping: ContractMapping!
30
+ }
31
+
32
+ type ContractSource {
33
+ startBlock: BigInt
34
+ }
35
+
36
+ type ContractMapping {
37
+ apiVersion: String!
38
+ language: String!
39
+ file: File!
40
+ entities: [String!]!
41
+ blockHandlers: [BlockHandler!]
42
+ eventHandlers: [EventHandler!]
43
+ }
44
+
45
+ type BlockHandler {
46
+ handler: String!
47
+ }
48
+
49
+ enum EventOrigin {
50
+ BeginBlock
51
+ DeliverTx
52
+ EndBlock
53
+ }
54
+
55
+ type EventHandler {
56
+ event: String!
57
+ origin: EventOrigin
58
+ handler: String!
59
+ }
60
+
61
+ type Graft {
62
+ base: String!
63
+ block: BigInt!
64
+ }
@@ -0,0 +1,20 @@
1
+ const immutable = require('immutable')
2
+
3
+ module.exports = class TendermintSubgraph {
4
+ constructor(options = {}) {
5
+ this.manifest = options.manifest
6
+ this.resolveFile = options.resolveFile
7
+ this.protocol = options.protocol
8
+ }
9
+
10
+ validateManifest() {
11
+ return immutable.List()
12
+ }
13
+
14
+ handlerTypes() {
15
+ return immutable.List([
16
+ 'blockHandlers',
17
+ 'eventHandlers',
18
+ ])
19
+ }
20
+ }
@@ -50,7 +50,7 @@ module.exports = class Scaffold {
50
50
  },
51
51
  dependencies: {
52
52
  '@graphprotocol/graph-cli': GRAPH_CLI_VERSION,
53
- '@graphprotocol/graph-ts': `0.24.1`,
53
+ '@graphprotocol/graph-ts': `0.26.0`,
54
54
  },
55
55
  }),
56
56
  { parser: 'json' },
package/src/subgraph.js CHANGED
@@ -158,6 +158,10 @@ At least one such handler must be defined.`,
158
158
  }
159
159
 
160
160
  static validateContractValues(manifest, protocol) {
161
+ if (!protocol.hasContract()){
162
+ return immutable.List()
163
+ }
164
+
161
165
  return validation.validateContractValues(manifest, protocol)
162
166
  }
163
167
 
@@ -151,6 +151,23 @@ const validators = immutable.fromJS({
151
151
  ])
152
152
  },
153
153
 
154
+ EnumTypeDefinition: (value, ctx) => {
155
+ const enumValues = ctx.getIn(['type', 'values']).map((v) => {
156
+ return v.getIn(['name', 'value'])
157
+ })
158
+
159
+ const allowedValues = enumValues.toArray().join(', ')
160
+
161
+ return enumValues.includes(value)
162
+ ? List()
163
+ : immutable.fromJS([
164
+ {
165
+ path: ctx.get('path'),
166
+ message: `Unexpected enum value: ${value}, allowed values: ${allowedValues}`,
167
+ },
168
+ ])
169
+ },
170
+
154
171
  String: (value, ctx) =>
155
172
  typeof value === 'string'
156
173
  ? List()