Skip to content

Commit 22f9a50

Browse files
authored
Merge pull request #821 from streamingfast/feature/schema-per-protocol
Moved to one SubgraphManifest schema file per protocol
2 parents 61f88f8 + 00427b7 commit 22f9a50

File tree

12 files changed

+225
-156
lines changed

12 files changed

+225
-156
lines changed

manifest-schema.graphql

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

src/protocols/index.js

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,7 @@ module.exports = class Protocol {
6060
'aurora',
6161
'aurora-testnet',
6262
],
63-
near: [
64-
'near-mainnet',
65-
'near-testnet'
66-
],
63+
near: ['near-mainnet', 'near-testnet'],
6764
})
6865
}
6966

@@ -108,6 +105,15 @@ module.exports = class Protocol {
108105
}
109106
}
110107

108+
hasTemplates() {
109+
switch (this.name) {
110+
case 'ethereum':
111+
return true
112+
case 'near':
113+
return false
114+
}
115+
}
116+
111117
getTypeGenerator(options) {
112118
switch (this.name) {
113119
case 'ethereum':
@@ -118,13 +124,17 @@ module.exports = class Protocol {
118124
}
119125

120126
getTemplateCodeGen(template) {
127+
if (!this.hasTemplates()) {
128+
throw new Error(
129+
`Template data sources with kind '${this.name}' are not supported yet`,
130+
)
131+
}
132+
121133
switch (this.name) {
122134
case 'ethereum':
123135
return new EthereumTemplateCodeGen(template)
124136
default:
125-
throw new Error(
126-
`Template data sources with kind '${this.name}' are not supported yet`,
127-
)
137+
throw new Error(`Template data sources with kind '${this.name}' is unknown`)
128138
}
129139
}
130140

src/protocols/near/manifest.graphql

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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+
account: String
34+
startBlock: BigInt
35+
}
36+
37+
type ContractMapping {
38+
apiVersion: String!
39+
language: String!
40+
file: File!
41+
entities: [String!]!
42+
blockHandlers: [BlockHandler!]
43+
receiptHandlers: [ReceiptHandler!]
44+
}
45+
46+
type BlockHandler {
47+
handler: String!
48+
}
49+
50+
type ReceiptHandler {
51+
handler: String!
52+
}
53+
54+
type Graft {
55+
base: String!
56+
block: BigInt!
57+
}

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, 'protocols', protocol.name, `manifest.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)