Skip to content

Commit

Permalink
Add optional startBlock param (#26)
Browse files Browse the repository at this point in the history
* Add optional startBlock param

Signed-off-by: Maksim Dimitrov <[email protected]>

* Update Readme

Signed-off-by: Maksim Dimitrov <[email protected]>

---------

Signed-off-by: Maksim Dimitrov <[email protected]>
  • Loading branch information
dimitrovmaksim authored Feb 14, 2023
1 parent 30e9c6b commit 25176e4
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 18 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ This is a hardhat plugin that aims to make subgraph building easy for Ethereum d

### `init`
- Expects two parameters: `contractName: 'MyContract'` and `address: '0x123..'`
- Has optional param `startBlock` - the optional number of the block that the data source starts indexing from
- Workflow:
- Generates a subgraph in `./subgraph` using `generateScaffold` from `graph-cli`
- Generates a network.json file in `./subgraph` using `initNetworksConfig` from `graph-cli`
Expand All @@ -32,6 +33,7 @@ deploy()

### `update`
- Expects two parameters: `contractName: 'MyContract'` and `address: '0x123..'`
- Has optional param `startBlock` - the optional number of the block that the data source starts indexing from
- Workflow:
- Updates the contract ABI in `./subgraph/abis`
- Updates the contract Address in `network.json` if it's deployed to the same network. If the contract has been deployed to a network that is not present in the config file, adds an entry for the new network.
Expand All @@ -58,6 +60,7 @@ deploy()

### `add`
- Expects one mandatory parameter: `address: '0x123..`
- Has optional param `startBlock` - the optional number of the block that the data source starts indexing from
- Has four optional paramaters:
- `subgraphYaml: path/to/subgraph.yaml` (default is './subgraph.yaml')
- `abi: path/to/Contract.json` Loads abi from file
Expand All @@ -83,7 +86,8 @@ npx hardhat add --address 0x123... --abi path/to/Contract.json --contactName MyC
async function deploy(contractName: string) {
....
await contract.deployed();
return { contractName: MyContract , address: contract.address}
const deployTx = await contract.deployTransaction.wait();
return { contractName: MyContract , address: contract.address, blockNumber: deployTx.blockNumber}
}

deploy()
Expand Down
12 changes: 8 additions & 4 deletions src/helpers/subgraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,16 @@ export const initSubgraph = async (taskArgs: { contractName: string, address: st
}
)

export const updateNetworksFile = async (toolbox: any, network: string, dataSource: string, address: string, directory: string): Promise<void> => {
export const updateNetworksConfig = async (toolbox: any, network: string, dataSource: string, identifier: string, value: string | number, directory: string): Promise<void> => {
await toolbox.patching.update(path.join(directory, 'networks.json'), (config: any) => {
if(Object.keys(config).includes(network)) {
Object.assign(config[network], { [dataSource]: { "address": address } })
if (Object.prototype.hasOwnProperty.call(config, network)) {
if (Object.prototype.hasOwnProperty.call(config[network], dataSource)) {
Object.assign(config[network][dataSource], { [identifier]: value })
} else {
Object.assign(config[network], { [dataSource]: { [identifier]: value } })
}
} else {
Object.assign(config, { [network]: { [dataSource]: { "address": address } }})
Object.assign(config, { [network]: { [dataSource]: {[identifier]: value } }})
}
return config
})
Expand Down
34 changes: 21 additions & 13 deletions src/tasks.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import path from 'path'
import * as YAML from 'yaml'
import * as toolbox from 'gluegun'
import { subtask, task } from 'hardhat/config'
import { task, types } from 'hardhat/config'
import { compareAbiEvents } from './helpers/events'
import { parseName } from 'hardhat/utils/contract-names'
import { generateDockerCompose, generatePackageScripts } from './helpers/generator'
import { checkForRepo, initRepository, initGitignore } from './helpers/git'
import { initSubgraph, runCodegen, updateNetworksFile, runGraphAdd } from './helpers/subgraph'
import { initSubgraph, runCodegen, updateNetworksConfig, runGraphAdd } from './helpers/subgraph'

const Protocol = require('@graphprotocol/graph-cli/src/protocols')
const Subgraph = require('@graphprotocol/graph-cli/src/subgraph')
Expand All @@ -17,6 +17,7 @@ task("graph", "Wrapper task that will conditionally execute init, update or add.
.addOptionalPositionalParam("subtask", "Specify which subtask to execute")
.addParam("contractName", "The name of the contract")
.addParam("address", "The address of the contract")
.addOptionalParam("startBlock", 'The subgraph startBlock', undefined, types.int)
.addFlag("mergeEntities", "Whether the entities should be merged")
.setAction(async (taskArgs, hre) => {
const directory = hre.config.paths.subgraph
Expand All @@ -41,19 +42,14 @@ task("graph", "Wrapper task that will conditionally execute init, update or add.
await hre.run(subtask || command, args)
});

const getArtifactPath = async (hre: any, contractName: string): Promise<string> => {
const artifact = await hre.artifacts.readArtifact(contractName)
return path.join(hre.config.paths.artifacts, artifact.sourceName, `${artifact.contractName}.json`)
}


/// MAYBE INIT AND UPDATE SHOULD NOT BE SUBTASKS BUT JUST FUNCTIONS?
subtask("init", "Initialize a subgraph")
task("init", "Initialize a subgraph")
.addParam("contractName", "The name of the contract")
.addParam("address", "The address of the contract")
.addOptionalParam("startBlock", 'The subgraph startBlock', undefined, types.int)
.setAction(async (taskArgs, hre) => {
const directory = hre.config.paths.subgraph
const subgraphName = hre.config.subgraph.name
const network = hre.network.name || hre.config.defaultNetwork

if (toolbox.filesystem.exists(directory) == "dir" && toolbox.filesystem.exists(path.join(directory, 'subgraph.yaml')) == "file") {
toolbox.print.error("Subgraph already exists! Please use the update subtask to update an existing subgraph!")
Expand All @@ -70,6 +66,8 @@ subtask("init", "Initialize a subgraph")
process.exit(1)
}

await updateNetworksConfig(toolbox, network, taskArgs.contractName, 'startBlock', taskArgs.startBlock, directory)

const isGitRepo = await checkForRepo(toolbox)
if (!isGitRepo) {
const repo = await initRepository(toolbox)
Expand Down Expand Up @@ -102,9 +100,10 @@ subtask("init", "Initialize a subgraph")
}
})

subtask("update", "Updates an existing subgraph from artifact or contract address")
task("update", "Updates an existing subgraph from artifact or contract address")
.addParam("contractName", "The name of the contract")
.addParam("address", "The address of the contract")
.addOptionalParam("startBlock", 'The subgraph startBlock', undefined, types.int)
.setAction(async (taskArgs, hre) => {
const directory = hre.config.paths.subgraph
const network = hre.network.name || hre.config.defaultNetwork
Expand Down Expand Up @@ -142,7 +141,8 @@ subtask("update", "Updates an existing subgraph from artifact or contract addres
toolbox.filesystem.write(path.join(directory, subgraphAbi.file), artifact.abi)

step(spinner, `Updating contract's ${network} address in networks.json`)
await updateNetworksFile(toolbox, network, dataSource.name, taskArgs.address, directory)
await updateNetworksConfig(toolbox, network, dataSource.name, 'address', taskArgs.address, directory)
await updateNetworksConfig(toolbox, network, dataSource.name, 'startBlock', taskArgs.startBlock, directory)

step(spinner, `Checking events for changes`)
const eventsChanged = await compareAbiEvents(spinner, toolbox, dataSource, artifact.abi)
Expand All @@ -160,14 +160,16 @@ subtask("update", "Updates an existing subgraph from artifact or contract addres

task("add", "Add a dataSource to the project")
.addParam("address", "The address of the contract")
.addFlag("mergeEntities", "Whether the entities should be merged")
.addOptionalParam("startBlock", 'The subgraph startBlock', undefined, types.int)
.addOptionalParam("subgraphYaml", "The location of the subgraph.yaml file", "subgraph.yaml")
.addOptionalParam("contractName", "The name of the contract", "Contract")
.addFlag("mergeEntities", "Whether the entities should be merged")
.addOptionalParam("abi", "Path to local abi file")
.setAction(async (taskArgs, hre) => {
const directory = hre.config.paths.subgraph
const subgraph = toolbox.filesystem.read(path.join(directory, taskArgs.subgraphYaml), 'utf8')
const { contractName } = parseName(taskArgs.contractName)
const network = hre.network.name || hre.config.defaultNetwork

if (!toolbox.filesystem.exists(directory) || !subgraph) {
toolbox.print.error("No subgraph found! Please first initialize a new subgraph!")
Expand All @@ -181,8 +183,14 @@ task("add", "Add a dataSource to the project")
async (spinner: any) => {
step(spinner, `Initiating graph add command`)
await runGraphAdd(hre, taskArgs, directory)
await updateNetworksConfig(toolbox, network, contractName, 'startBlock', taskArgs.startBlock, directory)

return true
}
)
})

const getArtifactPath = async (hre: any, contractName: string): Promise<string> => {
const artifact = await hre.artifacts.readArtifact(contractName)
return path.join(hre.config.paths.artifacts, artifact.sourceName, `${artifact.contractName}.json`)
}

0 comments on commit 25176e4

Please sign in to comment.