Skip to content

Feature/near data source template #824

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

Draft
wants to merge 2 commits into
base: ci/sf/feature/schema-per-protocol
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 0 additions & 122 deletions manifest-schema.graphql

This file was deleted.

86 changes: 86 additions & 0 deletions schemas/ethereum.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
scalar String
scalar File
scalar BigInt

type SubgraphManifest {
specVersion: String!
features: [String!]
schema: Schema!
description: String
repository: String
graft: Graft
dataSources: [DataSource!]!
templates: [DataSourceTemplate!]
}

type Schema {
file: File!
}

type DataSource {
kind: String!
name: String!
network: String
source: ContractSource!
mapping: ContractMapping!
}

type ContractSource {
address: String
abi: String!
startBlock: BigInt
}

type ContractMapping {
kind: String
apiVersion: String!
language: String!
file: File!
entities: [String!]!
abis: [ContractAbi!]!
blockHandlers: [BlockHandler!]
callHandlers: [CallHandler!]
eventHandlers: [ContractEventHandler!]
}

type ContractAbi {
name: String!
file: File!
}

type BlockHandler {
handler: String!
filter: BlockFilter
}

type BlockFilter {
kind: String!
}

type CallHandler {
function: String!
handler: String!
}

type ContractEventHandler {
event: String!
topic0: String
handler: String!
}

type Graft {
base: String!
block: BigInt!
}

type DataSourceTemplate {
kind: String!
name: String!
network: String
source: ContractSourceTemplate!
mapping: ContractMapping!
}

type ContractSourceTemplate {
abi: String!
}
59 changes: 59 additions & 0 deletions schemas/near.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
scalar String
scalar File
scalar BigInt

type SubgraphManifest {
specVersion: String!
schema: Schema!
description: String
repository: String
graft: Graft
dataSources: [DataSource!]!
templates: [DataSourceTemplate!]
}

type Schema {
file: File!
}

type DataSource {
kind: String!
name: String!
network: String
source: ContractSource!
mapping: ContractMapping!
}

type ContractSource {
account: String
startBlock: BigInt
}

type ContractMapping {
apiVersion: String!
language: String!
file: File!
entities: [String!]!
blockHandlers: [BlockHandler!]
receiptHandlers: [ReceiptHandler!]
}

type BlockHandler {
handler: String!
}

type ReceiptHandler {
handler: String!
}

type Graft {
base: String!
block: BigInt!
}

type DataSourceTemplate {
kind: String!
name: String!
network: String
mapping: ContractMapping!
}
27 changes: 20 additions & 7 deletions src/protocols/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const immutable = require('immutable')
const EthereumTypeGenerator = require('./ethereum/type-generator')
const EthereumTemplateCodeGen = require('./ethereum/codegen/template')
const NearTemplateCodeGen = require('./near/codegen/template')
const EthereumABI = require('./ethereum/abi')
const EthereumSubgraph = require('./ethereum/subgraph')
const NearSubgraph = require('./near/subgraph')
Expand Down Expand Up @@ -60,10 +61,7 @@ module.exports = class Protocol {
'aurora',
'aurora-testnet',
],
near: [
'near-mainnet',
'near-testnet'
],
near: ['near-mainnet', 'near-testnet'],
})
}

Expand Down Expand Up @@ -108,6 +106,15 @@ module.exports = class Protocol {
}
}

hasTemplates() {
switch (this.name) {
case 'ethereum':
return true
case 'near':
return true
}
}

getTypeGenerator(options) {
switch (this.name) {
case 'ethereum':
Expand All @@ -118,13 +125,19 @@ module.exports = class Protocol {
}

getTemplateCodeGen(template) {
if (!this.hasTemplates()) {
throw new Error(
`Template data sources with kind '${this.name}' are not supported yet`,
)
}

switch (this.name) {
case 'ethereum':
return new EthereumTemplateCodeGen(template)
case 'near':
return new NearTemplateCodeGen(template)
default:
throw new Error(
`Template data sources with kind '${this.name}' are not supported yet`,
)
throw new Error(`Template data sources with kind '${this.name}' is unknown`)
}
}

Expand Down
40 changes: 40 additions & 0 deletions src/protocols/near/codegen/template.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const tsCodegen = require('../../../codegen/typescript')

module.exports = class NearTemplateCodeGen {
constructor(template) {
this.template = template
}

generateModuleImports() {
return []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you'll need to add 'near' here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not required because there is actually no near type involved in the generated code:

import { DataSourceTemplate, DataSourceContext } from "@graphprotocol/graph-ts";

export class receipts extends DataSourceTemplate {
  static create(account: string): void {
    DataSourceTemplate.create("receipts", [account]);
  }

  static createWithContext(account: string, context: DataSourceContext): void {
    DataSourceTemplate.createWithContext("receipts", [account], context);
  }
}

I tested the full flow of NEAR data source template and it worked great.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see why I thought that, that's because you're not using the Account type from the near module. I would prefer that instead of using string directly. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ambivalent.

If we go with Account, it should be used thoroughly everywhere, right now it's a mixed usage in graph-ts (mostly 50/50).

The second thing that makes it me doubt is how people on NEAR are used to work directly with string. I've research this a little bit and it seems AccountId is used more (https://github.com/near/near-sdk-rs/blob/05c389c75a568af3f37a3346d6f7b4064852e1de/near-sdk/src/types/account_id.rs#L39) although I've seen various example dealing with String directly. The AssemblyScript however does not seems to have an AccountId alias and seems to deal with string directly: https://github.com/near/near-sdk-as/blob/master/sdk-core/assembly/contract.ts#L12.

I prefer string personally as it make the cognitive load lower. If we choose to still wrap it, I'm voting more for AccountId to align with the Rust SDK for NEAR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I see 🤔

Well we can discuss that later then, I'm gonna merge this, thanks for the PR!!

}

generateCreateMethod() {
const name = this.template.get('name')

return tsCodegen.staticMethod(
'create',
[tsCodegen.param('account', tsCodegen.namedType('string'))],
tsCodegen.namedType('void'),
`
DataSourceTemplate.create('${name}', [account])
`,
)
}

generateCreateWithContextMethod() {
const name = this.template.get('name')

return tsCodegen.staticMethod(
'createWithContext',
[
tsCodegen.param('account', tsCodegen.namedType('string')),
tsCodegen.param('context', tsCodegen.namedType('DataSourceContext')),
],
tsCodegen.namedType('void'),
`
DataSourceTemplate.createWithContext('${name}', [account], context)
`,
)
}
}
Loading