@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.
- package/README.md +6 -6
- package/examples/basic-event-handlers/package.json +1 -1
- package/examples/basic-event-handlers/yarn.lock +4 -4
- package/examples/example-subgraph/package.json +1 -1
- package/examples/example-subgraph/yarn.lock +4 -4
- package/package.json +1 -1
- package/src/codegen/schema.js +105 -26
- package/src/codegen/schema.test.js +2 -6
- package/src/commands/codegen.js +1 -1
- package/src/commands/deploy.js +1 -1
- package/src/commands/init.js +1 -0
- package/src/protocols/index.js +34 -0
- package/src/protocols/tendermint/manifest.graphql +64 -0
- package/src/protocols/tendermint/subgraph.js +20 -0
- package/src/scaffold/index.js +1 -1
- package/src/subgraph.js +4 -0
- package/src/validation/manifest.js +17 -0
- package/src/validation/schema.js +120 -119
- package/tests/cli/init/ethereum/from-example/.gitattributes +1 -0
- package/tests/cli/init/ethereum/from-example/LICENSE +21 -0
- package/tests/cli/init/ethereum/from-example/README.md +3 -0
- package/tests/cli/init/ethereum/from-example/abis/Gravity.json +1 -0
- package/tests/cli/init/ethereum/from-example/bin/Counter.bin +1 -0
- package/tests/cli/init/ethereum/from-example/contracts/Gravity.sol +63 -0
- package/tests/cli/init/ethereum/from-example/contracts/Migrations.sol +23 -0
- package/tests/cli/init/ethereum/from-example/docker-compose.yml +39 -0
- package/tests/cli/init/ethereum/from-example/migrations/1_initial_migration.js +5 -0
- package/tests/cli/init/ethereum/from-example/migrations/2_deploy_contract.js +5 -0
- package/tests/cli/init/ethereum/from-example/migrations/3_create_gravatars.js +15 -0
- package/tests/cli/init/ethereum/from-example/package.json +23 -0
- package/tests/cli/init/ethereum/from-example/schema.graphql +6 -0
- package/tests/cli/init/ethereum/from-example/src/mapping.ts +22 -0
- package/tests/cli/init/ethereum/from-example/subgraph.yaml +27 -0
- package/tests/cli/init/ethereum/from-example/truffle.js +27 -0
- 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
|
[](https://www.npmjs.com/package/@graphprotocol/graph-cli)
|
|
4
|
-
[](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 `
|
|
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 `
|
|
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 `
|
|
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 `
|
|
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 `
|
|
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.
|
|
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.
|
|
6
|
-
version "0.
|
|
7
|
-
resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.
|
|
8
|
-
integrity sha512-
|
|
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
|
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
# yarn lockfile v1
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
"@graphprotocol/graph-ts@0.
|
|
6
|
-
version "0.
|
|
7
|
-
resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.
|
|
8
|
-
integrity sha512-
|
|
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
package/src/codegen/schema.js
CHANGED
|
@@ -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',
|
|
127
|
+
[tsCodegen.param('id', idField.tsNamedType())],
|
|
78
128
|
undefined,
|
|
79
129
|
`
|
|
80
130
|
super()
|
|
81
|
-
this.set('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,
|
|
144
|
+
assert(id != null,
|
|
145
|
+
'Cannot save ${entityName} entity without an ID')
|
|
95
146
|
if (id) {
|
|
96
|
-
assert(
|
|
97
|
-
|
|
98
|
-
|
|
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(
|
|
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}',
|
|
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
|
|
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 '${
|
|
167
|
-
Suggestion: add an '!' to the member type of the List, change from '${
|
|
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
|
-
|
|
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
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
`,
|
package/src/commands/codegen.js
CHANGED
|
@@ -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.
|
|
74
|
+
await assertGraphTsVersion(path.dirname(manifest), '0.25.0')
|
|
75
75
|
|
|
76
76
|
const dataSourcesAndTemplates = await DataSourcesExtractor.fromFilePath(manifest)
|
|
77
77
|
|
package/src/commands/deploy.js
CHANGED
|
@@ -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.
|
|
203
|
+
await assertGraphTsVersion(path.dirname(manifest), '0.25.0')
|
|
204
204
|
|
|
205
205
|
const dataSourcesAndTemplates = await DataSourcesExtractor.fromFilePath(manifest)
|
|
206
206
|
|
package/src/commands/init.js
CHANGED
|
@@ -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
|
}
|
package/src/protocols/index.js
CHANGED
|
@@ -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
|
+
}
|
package/src/scaffold/index.js
CHANGED
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()
|