Skip to content

Filipe/substreams mappings #1490

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Dec 7, 2023
5 changes: 5 additions & 0 deletions .changeset/nervous-windows-serve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@graphprotocol/graph-cli': minor
---

substreams based triggers support
26 changes: 24 additions & 2 deletions packages/cli/src/compiler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ export default class Compiler {
);
}

if (protocol.name == 'substreams') {
if (protocol.name == 'substreams' || protocol.name == 'substreams/triggers') {
updatedDataSource = updatedDataSource
// Write data source ABIs to the output directory
.updateIn(['source', 'package'], (substreamsPackage: any) =>
Expand All @@ -569,6 +569,17 @@ export default class Compiler {
}),
);

if (updatedDataSource.getIn(['mapping', 'file'])) {
updatedDataSource = updatedDataSource.updateIn(
['mapping', 'file'],
(mappingFile: string) =>
path.relative(
this.options.outputDir,
path.resolve(this.sourceDir, mappingFile),
),
);
}

return updatedDataSource;
}

Expand Down Expand Up @@ -662,7 +673,7 @@ export default class Compiler {
}

// Upload all mappings
if (this.protocol.name === 'substreams') {
if (this.protocol.name === 'substreams' || this.protocol.name === 'substreams/triggers') {
for (const [i, dataSource] of subgraph.get('dataSources').entries()) {
updates.push({
keyPath: ['dataSources', i, 'source', 'package', 'file'],
Expand All @@ -672,6 +683,17 @@ export default class Compiler {
spinner,
),
});

if (dataSource.getIn(['mapping', 'file'])) {
updates.push({
keyPath: ['dataSources', i, 'mapping', 'file'],
value: await this._uploadFileToIPFS(
dataSource.getIn(['mapping', 'file']),
uploadedFiles,
spinner,
),
});
}
}
} else {
for (const [i, dataSource] of subgraph.get('dataSources').entries()) {
Expand Down
37 changes: 32 additions & 5 deletions packages/cli/src/protocols/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,24 @@ const protocolDebug = debug('graph-cli:protocol');

export default class Protocol {
static fromDataSources(dataSourcesAndTemplates: any) {
const firstDataSourceKind = dataSourcesAndTemplates[0].kind;
return new Protocol(firstDataSourceKind);
const firstDataSource = dataSourcesAndTemplates[0];
return new Protocol(firstDataSource);
}

name: ProtocolName;

// TODO: should assert non null? see the constructor switch default case comment
config!: ProtocolConfig;

constructor(name: ProtocolName) {
constructor(datasource: any) {
/**
* TODO: we should improve this `any` type, because some places
* we can initiate a Protocol with just a string (the name) and
* some other places use datasource object
*/
const name = typeof datasource === 'string' ? datasource : datasource.kind;
this.name = Protocol.normalizeName(name)!;
protocolDebug('Initializing protocol %s', this.name);

switch (this.name) {
case 'arweave':
Expand All @@ -54,6 +61,14 @@ export default class Protocol {
break;
case 'substreams':
this.config = substreamsProtocol;

/**
* Substreams triggers are a special case of substreams data sources
* which have a mapping file and a handler.
*/
if (datasource?.mapping?.file && datasource?.mapping.handler) {
this.name = 'substreams/triggers';
}
break;
default:
// Do not throw when undefined, a better error message is printed after the constructor
Expand Down Expand Up @@ -126,7 +141,13 @@ export default class Protocol {
],
substreams: ['mainnet'],
}) as immutable.Map<
'arweave' | 'ethereum' | 'near' | 'cosmos' | 'substreams',
| 'arweave'
| 'ethereum'
| 'near'
| 'cosmos'
| 'substreams'
// this is temporary, until we have a better way to handle substreams triggers
| 'substreams/triggers',
immutable.List<string>
>;
}
Expand Down Expand Up @@ -207,7 +228,13 @@ export default class Protocol {
}
}

export type ProtocolName = 'arweave' | 'ethereum' | 'near' | 'cosmos' | 'substreams';
export type ProtocolName =
| 'arweave'
| 'ethereum'
| 'near'
| 'cosmos'
| 'substreams'
| 'substreams/triggers';

export interface ProtocolConfig {
displayName: string;
Expand Down
4 changes: 4 additions & 0 deletions packages/cli/src/protocols/substreams/manifest.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,18 @@ type DataSource {

type SubstreamsSource {
package: SubstreamsPackage!
startBlock: BigInt
}

type SubstreamsPackage {
moduleName: String!
file: String!
params: String
}

type SubstreamMapping {
apiVersion: String!
kind: String!
file: File
handler: String
}
8 changes: 7 additions & 1 deletion packages/cli/src/subgraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,13 @@ export default class Subgraph {
// Parse the default subgraph schema
const schema = graphql.parse(
await fs.readFile(
path.join(__dirname, 'protocols', protocol.name, `manifest.graphql`),
path.join(
__dirname,
'protocols',
// TODO: substreams/triggers is a special case, should be handled better
protocol.name === 'substreams/triggers' ? 'substreams' : protocol.name,
`manifest.graphql`,
),
'utf-8',
),
);
Expand Down