Skip to content

Commit 6235e0a

Browse files
committed
Moved to one SubgraphManifest schema file per protocol
This will make it easier to add new network and will improve error messages when someone will be using fields that do not exist on a specific network but does in other (`temlates` for example used in NEAR were given a bunch of errors like the support was possible while it should have displayed an error on the `templates` node itself). Using `templates` on NEAR before this PR: ``` ✔ Apply migrations ✖ Failed to load subgraph from ../graph-node-dev/subgraphs/near/data-source/testnet.yaml: Error in ../graph-node-dev/subgraphs/near/data-source/testnet.yaml: Path: templates > 0 > source No value provided Path: templates > 0 > mapping Unexpected key in map: receiptHandlers Path: templates > 0 > mapping > abis No value provided ``` And with this PR: ``` $ ./bin/graph build ../graph-node-dev/subgraphs/near/data-source/testnet.yaml ✖ Failed to load subgraph from ../graph-node-dev/subgraphs/near/data-source/testnet.yaml: Error in ../graph-node-dev/subgraphs/near/data-source/testnet.yaml: Path: / Unexpected key in map: templates ```
1 parent 284ec68 commit 6235e0a

File tree

8 files changed

+189
-180
lines changed

8 files changed

+189
-180
lines changed

manifest-schema.graphql

Lines changed: 0 additions & 122 deletions
This file was deleted.

schemas/ethereum.graphql

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
scalar String
2+
scalar File
3+
scalar BigInt
4+
5+
type SubgraphManifest {
6+
specVersion: String!
7+
features: [String!]
8+
schema: Schema!
9+
description: String
10+
repository: String
11+
graft: Graft
12+
dataSources: [DataSource!]!
13+
templates: [DataSourceTemplate!]
14+
}
15+
16+
type Schema {
17+
file: File!
18+
}
19+
20+
type DataSource {
21+
kind: String!
22+
name: String!
23+
network: String
24+
source: ContractSource!
25+
mapping: ContractMapping!
26+
}
27+
28+
type ContractSource {
29+
address: String
30+
abi: String!
31+
startBlock: BigInt
32+
}
33+
34+
type ContractMapping {
35+
kind: String
36+
apiVersion: String!
37+
language: String!
38+
file: File!
39+
entities: [String!]!
40+
abis: [ContractAbi!]!
41+
blockHandlers: [BlockHandler!]
42+
callHandlers: [CallHandler!]
43+
eventHandlers: [ContractEventHandler!]
44+
}
45+
46+
type ContractAbi {
47+
name: String!
48+
file: File!
49+
}
50+
51+
type BlockHandler {
52+
handler: String!
53+
filter: BlockFilter
54+
}
55+
56+
type BlockFilter {
57+
kind: String!
58+
}
59+
60+
type CallHandler {
61+
function: String!
62+
handler: String!
63+
}
64+
65+
type ContractEventHandler {
66+
event: String!
67+
topic0: String
68+
handler: String!
69+
}
70+
71+
type Graft {
72+
base: String!
73+
block: BigInt!
74+
}
75+
76+
type DataSourceTemplate {
77+
kind: String!
78+
name: String!
79+
network: String
80+
source: ContractSourceTemplate!
81+
mapping: ContractMapping!
82+
}
83+
84+
type ContractSourceTemplate {
85+
abi: String!
86+
}

schemas/near.graphql

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
scalar String
2+
scalar File
3+
scalar BigInt
4+
5+
type SubgraphManifest {
6+
specVersion: String!
7+
schema: Schema!
8+
description: String
9+
repository: String
10+
graft: Graft
11+
dataSources: [DataSource!]!
12+
}
13+
14+
type Schema {
15+
file: File!
16+
}
17+
18+
type DataSource {
19+
kind: String!
20+
name: String!
21+
network: String
22+
source: ContractSource!
23+
mapping: ContractMapping!
24+
}
25+
26+
type ContractSource {
27+
account: String
28+
startBlock: BigInt
29+
}
30+
31+
type ContractMapping {
32+
apiVersion: String!
33+
language: String!
34+
file: File!
35+
entities: [String!]!
36+
blockHandlers: [BlockHandler!]
37+
receiptHandlers: [ReceiptHandler!]
38+
}
39+
40+
type BlockHandler {
41+
handler: String!
42+
}
43+
44+
type ReceiptHandler {
45+
handler: String!
46+
}
47+
48+
type Graft {
49+
base: String!
50+
block: BigInt!
51+
}

src/protocols/index.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const immutable = require('immutable')
22
const EthereumTypeGenerator = require('./ethereum/type-generator')
33
const EthereumTemplateCodeGen = require('./ethereum/codegen/template')
4+
const NearTemplateCodeGen = require('./near/codegen/template')
45
const EthereumABI = require('./ethereum/abi')
56
const EthereumSubgraph = require('./ethereum/subgraph')
67
const NearSubgraph = require('./near/subgraph')
@@ -60,10 +61,7 @@ module.exports = class Protocol {
6061
'aurora',
6162
'aurora-testnet',
6263
],
63-
near: [
64-
'near-mainnet',
65-
'near-testnet'
66-
],
64+
near: ['near-mainnet', 'near-testnet'],
6765
})
6866
}
6967

@@ -108,6 +106,15 @@ module.exports = class Protocol {
108106
}
109107
}
110108

109+
hasTemplates() {
110+
switch (this.name) {
111+
case 'ethereum':
112+
return true
113+
case 'near':
114+
return false
115+
}
116+
}
117+
111118
getTypeGenerator(options) {
112119
switch (this.name) {
113120
case 'ethereum':
@@ -118,13 +125,17 @@ module.exports = class Protocol {
118125
}
119126

120127
getTemplateCodeGen(template) {
128+
if (!this.hasTemplates()) {
129+
throw new Error(
130+
`Template data sources with kind '${this.name}' are not supported yet`,
131+
)
132+
}
133+
121134
switch (this.name) {
122135
case 'ethereum':
123136
return new EthereumTemplateCodeGen(template)
124137
default:
125-
throw new Error(
126-
`Template data sources with kind '${this.name}' are not supported yet`,
127-
)
138+
throw new Error(`Template data sources with kind '${this.name}' is unknown`)
128139
}
129140
}
130141

src/subgraph.js

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const buildCombinedWarning = (filename, warnings) =>
2727
? warnings.reduce(
2828
(msg, w) =>
2929
`${msg}
30-
30+
3131
Path: ${w.get('path').size === 0 ? '/' : w.get('path').join(' > ')}
3232
${w
3333
.get('message')
@@ -39,9 +39,21 @@ const buildCombinedWarning = (filename, warnings) =>
3939

4040
module.exports = class Subgraph {
4141
static async validate(data, protocol, { resolveFile }) {
42+
if (protocol.name == null) {
43+
return immutable.fromJS([
44+
{
45+
path: [],
46+
message: `Unable to determine for which protocol manifest file is built for. Ensure you have at least one 'dataSources' and/or 'templates' elements defined in your subgraph.`,
47+
},
48+
])
49+
}
50+
4251
// Parse the default subgraph schema
4352
let schema = graphql.parse(
44-
await fs.readFile(path.join(__dirname, '..', 'manifest-schema.graphql'), 'utf-8'),
53+
await fs.readFile(
54+
path.join(__dirname, '..', 'schemas', `${protocol.name}.graphql`),
55+
'utf-8',
56+
),
4557
)
4658

4759
// Obtain the root `SubgraphManifest` type from the schema
@@ -146,10 +158,7 @@ At least one such handler must be defined.`,
146158
}
147159

148160
static validateContractValues(manifest, protocol) {
149-
return validation.validateContractValues(
150-
manifest,
151-
protocol,
152-
)
161+
return validation.validateContractValues(manifest, protocol)
153162
}
154163

155164
// Validate that data source names are unique, so they don't overwrite each other.
@@ -200,17 +209,13 @@ More than one template named '${name}', template names must be unique.`,
200209
return yaml.stringify(manifest.toJS())
201210
}
202211

203-
static async load(
204-
filename,
205-
{ protocol, skipValidation } = { skipValidation: false }
206-
) {
212+
static async load(filename, { protocol, skipValidation } = { skipValidation: false }) {
207213
// Load and validate the manifest
208214
let data = null
209215

210-
if(filename.match(/.js$/)) {
216+
if (filename.match(/.js$/)) {
211217
data = require(path.resolve(filename))
212-
}
213-
else {
218+
} else {
214219
data = yaml.parse(await fs.readFile(filename, 'utf-8'))
215220
}
216221

0 commit comments

Comments
 (0)