Merge pull request #288 from cerc-io/cleanup-readmes

Watcher docs updates
This commit is contained in:
Zach 2023-01-16 10:44:19 -05:00 committed by GitHub
commit 64a30b7a4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 1076 additions and 1871 deletions

15
.github/CONTRIBUTING.md vendored Normal file
View File

@ -0,0 +1,15 @@
# Contributing
To update versions in all packages run the following:
```bash
yarn version:set <VERSION>
yarn version:set-codegen <VERSION>
```
Example:
```bash
yarn version:set 0.2.20
yarn version:set-codegen 0.2.20
```

View File

@ -1,58 +1,56 @@
# watcher-ts
![Cute Panopticon](./docs/watchers-graphic.png)
Watchers make managing data in Dapp development as frictionless as possible. They do this by querying, transforming, and caching Ethereum state data cheaper and faster compared to existing solutions. This data also comes with evidence for generating cryptographic proofs to provide verification that the data is authentic. Public watchers are found in the [packages](/packages) directory.
Go [here](https://github.com/cerc-io/stack-orchestrator/tree/main/app/data/stacks/erc20) for a quick start demo of setting up the stack and deploying/using the erc20 watcher via the Laconic Stack Orchestrator.
## Prerequisites
### User Mode
- `laconic-so` [Install](https://github.com/cerc-io/stack-orchestrator#setup)
The Laconic Stack Orchestrator provides all the tools to quickly get started with watchers.
### Developer Mode
- `yarn` [Install](https://yarnpkg.com/getting-started/install)
- `postgres` [Install](https://www.postgresql.org/download/)
You'll need the above if you plan on digging into this repo, writing your own watchers, or experimenting with watchers not currently supported by Stack Orchestrator. See [CONTRIBUTING.md](.github/CONTRIBUTING.md) for more information.
## Services
The default configuration files used by watchers assume the following services are setup and running on localhost:
* [cerc-io/go-ethereum](https://github.com/cerc-io/go-ethereum/tree/v1.10.25-statediff-v4) on port 8545
* [cerc-io/ipld-eth-server](https://github.com/cerc-io/ipld-eth-server) with native GQL API enabled, on port 8082
* [cerc-io/ipld-eth-db](https://github.com/cerc-io/ipld-eth-db) to populate the postgres database for `ipld-eth-server`
These services are dockerized by the Laconic Stack Orchestrator (`laconic-so`). [Use it](https://github.com/cerc-io/stack-orchestrator) unless you plan on digging into those codebases. For more information on setting up these services up by hand, see [here](/docs/README.md)
## Setup
This project uses [yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/).
From the root of this repository, run:
Install packages (Node.JS v16.13.1):
`yarn && yarn build`
```bash
yarn
```
to download dependencies and build all the watchers.
Build packages:
Orient yourself with the available CLI commands [here](docs/cli.md) and in some cases, watchers have in-depth demos (e.g. [mobymask](/packages/mobymask-watcher))
```bash
yarn build
```
[//]: # (TODO: ## Generating Watchers)
## Tests
* [graph-node](./packages/graph-node/README.md)
## Services
## Further Reading
The default config files used by the watchers assume the following services are setup and running on localhost:
[//]: # (TODO: link to docs.laconic.com when ready)
* `vulcanize/go-ethereum` on port 8545
* `vulcanize/ipld-eth-server` with native GQL API enabled, on port 8082
### Note
* In `vulcanize/ipld-eth-server`, add the following statement to `[ethereum]` section in `environments/config.toml`:
`chainConfig = "./chain.json" # ETH_CHAIN_CONFIG`
## Watchers
* [eden-watcher](./packages/eden-watcher/README.md)
* [erc20-watcher](./packages/erc20-watcher/README.md)
* [erc721-watcher](./packages/erc721-watcher/README.md)
* [graph-test-watcher](./packages/graph-test-watcher/README.md)
* [mobymask-watcher](./packages/mobymask-watcher/README.md)
## Development
* To update versions in all packages run the following:
```bash
yarn version:set <VERSION>
yarn version:set-codegen <VERSION>
```
Example
```bash
yarn version:set 0.2.20
yarn version:set-codegen 0.2.20
```
- [Watchers Blog Post](https://www.laconic.com/blog/laconic-watchers)

85
docs/README.md Normal file
View File

@ -0,0 +1,85 @@
# Watcher Documentation
This document is specifically focused on standing up a minimal core version of the Laconic Stack *without* using [Stack Orchestrator]( https://github.com/cerc-io/stack-orchestrator). If this is your first foray into the stack, start with Stack Orchestrator. To understand what is going on under the hood or to make contributions to this repo, this is a good place to start.
There are 3 main components to setting up an environment for running watchers:
- core services
- configure postgres
- edit config file
After which you should be able to navigate to the `README.md` of any watcher and run through its demo using `yarn`. The common `yarn` CLI commands for watchers are documented [here](../cli.md).
## Core services
The following core services should be setup and running on localhost:
* `cerc-io/go-ethereum` [v1.10.26-statediff-4.2.2-alpha](https://github.com/cerc-io/go-ethereum/releases/tag/v1.10.26-statediff-4.2.2-alpha)
on port 8545
* `cerc-io/ipld-eth-server` [v4.2.2-alpha](https://github.com/cerc-io/ipld-eth-server/releases/tag/v4.2.2-alpha) with native GQL API enabled, on port 8082
* `cerc-io/ipld-eth-db` [v4.2.2-alpha](https://github.com/cerc-io/ipld-eth-db/releases/tag/v4.2.2-alpha) is the postgres schema required for `ipld-eth-server`
## Setup Postgres
In this example, we use the `erc20-watcher`; for another watcher substitute with its name.
Create a postgres database for the watcher:
```bash
sudo su - postgres
createdb erc20-watcher
```
Create a postgres database for the job queue:
```
sudo su - postgres
createdb erc20-watcher-job-queue
```
Enable the `pgcrypto` [extension](https://github.com/timgit/pg-boss/tree/master/docs#database-install) on the job queue database.
```
postgres@tesla:~$ psql -U postgres -h localhost erc20-watcher-job-queue
Password for user postgres:
psql (12.7 (Ubuntu 12.7-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
erc20-watcher-job-queue=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION
erc20-watcher-job-queue=# exit
```
## Config File
In each watchers' directory is a config file: `packages/<watcher>/environments/local.toml`:
* Update the database connection settings.
* Update the `upstream` config and provide the `ipld-eth-server` GraphQL API endpoint.
* Select "active" vs. "lazy" watcher depending on its kind.
For example:
```toml
[server]
kind = "active"
[database]
type = "postgres"
host = "localhost"
port = 5432
database = "erc20-watcher"
username = "postgres"
password = "postgres"
[jobQueue]
dbConnectionString = "postgres://postgres:postgres@localhost/erc20-watcher-job-queue"
[upstream]
[upstream.ethServer]
gqlApiEndpoint = "http://127.0.0.1:8082/graphql"
rpcProviderEndpoint = "http://127.0.0.1:8081"
```
Now that your environment is setup, you can test run any watcher!

127
docs/cli.md Normal file
View File

@ -0,0 +1,127 @@
## Watcher CLI commands
Non-exhaustive list of (yarn) CLI commands available for watchers. Assumes you have an environment setup either [by hand](./README.md) or using [Stack Orchestrator](https://github.com/cerc-io/stack-orchestrator), and have built `yarn && yarn build` a specific watcher.
If the watcher is an `active` watcher, run the job-runner:
```bash
yarn job-runner
```
```
# For development.
yarn server:dev
# For specifying config file.
yarn server -f environments/local.toml
```
If the watcher is `lazy` omit the above step, then run the server:
```bash
yarn server
```
This will enable the GraphQL playground at: `http://localhost:<port>/graphql`
where `<port>` is set in the `environments/local.toml` of each watcher.
To watch a contract:
```bash
yarn watch:contract --address <contract-address> --kind <contract-kind> --checkpoint <true | false> --starting-block <block-number>
```
* `address`: Address or identifier of the contract to be watched.
* `kind`: Kind of the contract.
* `checkpoint`: Turn checkpointing on (`true` | `false`).
* `starting-block`: Starting block for the contract (default: `1`).
Example:
Watch a contract with its address and checkpointing on:
```bash
yarn watch:contract --address 0x1F78641644feB8b64642e833cE4AFE93DD6e7833 --kind ERC20 --checkpoint true
```
To fill a block range:
```bash
yarn fill --start-block <from-block> --end-block <to-block>
```
* `start-block`: Block number to start filling from.
* `end-block`: Block number till which to fill.
To create a checkpoint for a contract:
```bash
yarn checkpoint create --address <contract-address> --block-hash <block-hash>
```
* `address`: Address or identifier of the contract for which to create a checkpoint.
* `block-hash`: Hash of a block (in the pruned region) at which to create the checkpoint (default: latest canonical block hash).
To verify a checkpoint:
```bash
yarn checkpoint verify --cid <checkpoint-cid>
```
* `cid`: CID of the checkpoint for which to verify.
To reset the watcher to a previous block number:
```bash
yarn reset watcher --block-number <previous-block-number>
```
* `block-number`: Block number to which to reset the watcher.
To reset the job-queue:
```bash
yarn reset job-queue
```
To reset the state:
```bash
yarn reset state --block-number <previous-block-number>
```
## Import/Export State
To export and import the watcher state:
In the source watcher, export watcher state:
```bash
yarn export-state --export-file [export-file-path] --block-number [snapshot-block-height]
```
* `export-file`: Path of file to which to export the watcher data.
* `block-number`: Block height at which to take snapshot for export.
In the target watcher, run the job-runner:
```bash
yarn job-runner
```
Import watcher state:
```bash
yarn import-state --import-file <import-file-path>
```
* `import-file`: Path of file from which to import the watcher data.
To inspect a CID:
```bash
yarn inspect-cid --cid <cid>
```
* `cid`: CID to be inspected.

BIN
docs/watchers-graphic.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 MiB

20
packages/README.md Normal file
View File

@ -0,0 +1,20 @@
# Watchers Directory
Here contains all the publicly available watchers for your experimenting purposes. For general information on setting up the stack and the CLI commands used to interact with watchers, see the [docs](/docs) directory.
## Customizing Watchers
* Indexing on an event:
* Edit the custom hook function `handleEvent` (triggered on an event) in [hooks.ts](./src/hooks.ts) to perform corresponding indexing using the `Indexer` object.
* While using the indexer storage methods for indexing, pass `diff` as true if default state is desired to be generated using the state variables being indexed.
* Generating state:
* Edit the custom hook function `createInitialState` (triggered if the watcher passes the start block, checkpoint: `true`) in [hooks.ts](./src/hooks.ts) to save an initial `State` using the `Indexer` object.
* Edit the custom hook function `createStateDiff` (triggered on a block) in [hooks.ts](./src/hooks.ts) to save the state in a `diff` `State` using the `Indexer` object. The default state (if exists) is updated.
* Edit the custom hook function `createStateCheckpoint` (triggered just before default and CLI checkpoint) in [hooks.ts](./src/hooks.ts) to save the state in a `checkpoint` `State` using the `Indexer` object.

View File

@ -2,79 +2,32 @@
## Setup
Create a postgres12 database for the job queue:
```
sudo su - postgres
createdb address-watcher-job-queue
```
Enable the `pgcrypto` extension on the job queue database (https://github.com/timgit/pg-boss/blob/master/docs/usage.md#intro).
Example:
```
postgres@tesla:~$ psql -U postgres -h localhost address-watcher-job-queue
Password for user postgres:
psql (12.7 (Ubuntu 12.7-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
address-watcher-job-queue=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION
address-watcher-job-queue=# exit
```
Create a postgres12 database for the address watcher:
```
sudo su - postgres
createdb address-watcher
```
Update `environments/local.toml` with database connection settings for both the databases.
Update the `upstream` config in `environments/local.toml` and provide the `ipld-eth-server` GQL API and the tracing API (`debug_traceTransaction` RPC provider) endpoints.
## Run
Run the following scripts in different terminals.
First try the [stack orchestrator](https://github.com/cerc-io/stack-orchestrator) to quickly get started. Advanced users can see [here](/docs/README.md) for instructions on setting up a local environment by hand.
Build files:
```
yarn build
```bash
yarn && yarn build
```
GQL server:
## Run
```
Run the following commands in different terminals:
GraphQL server:
```bash
yarn server
# For development.
yarn server:dev
# For specifying config file.
yarn server -f environments/local.toml
```
Job runner for processing the tracing requests queue:
```
```bash
yarn job-runner
# For development.
yarn job-runner:dev
# For specifying config file.
yarn job-runner -f environments/local.toml
```
To fill a block range:
```
```bash
yarn fill --start-block 1 --end-block 1000
# For specifying config file.
yarn fill -f environments/local.toml --start-block 1 --end-block 1000
```

View File

@ -2,199 +2,15 @@
## Setup
* Run the following command to install required packages:
First try the [stack orchestrator](https://github.com/cerc-io/stack-orchestrator) to quickly get started. Advanced users can see [here](/docs/README.md) for instructions on setting up a local environment by hand.
```bash
yarn
```
* Create a postgres12 database for the watcher:
```bash
sudo su - postgres
createdb eden-watcher
```
* If the watcher is an `active` watcher:
Create database for the job queue and enable the `pgcrypto` extension on them (https://github.com/timgit/pg-boss/blob/master/docs/usage.md#intro):
```
createdb eden-watcher-job-queue
```
```
postgres@tesla:~$ psql -U postgres -h localhost eden-watcher-job-queue
Password for user postgres:
psql (12.7 (Ubuntu 12.7-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
eden-watcher-job-queue=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION
eden-watcher-job-queue=# exit
```
* In the [config file](./environments/local.toml):
* Update the database connection settings.
* Update the `upstream` config and provide the `ipld-eth-server` GQL API endpoint.
* Update the `server` config with state checkpoint settings.
## Customize
* Indexing on an event:
* Edit the custom hook function `handleEvent` (triggered on an event) in [hooks.ts](./src/hooks.ts) to perform corresponding indexing using the `Indexer` object.
* While using the indexer storage methods for indexing, pass `diff` as true if default state is desired to be generated using the state variables being indexed.
* Generating state:
* Edit the custom hook function `createInitialState` (triggered if the watcher passes the start block, checkpoint: `true`) in [hooks.ts](./src/hooks.ts) to save an initial `State` using the `Indexer` object.
* Edit the custom hook function `createStateDiff` (triggered on a block) in [hooks.ts](./src/hooks.ts) to save the state in a `diff` `State` using the `Indexer` object. The default state (if exists) is updated.
* Edit the custom hook function `createStateCheckpoint` (triggered just before default and CLI checkpoint) in [hooks.ts](./src/hooks.ts) to save the state in a `checkpoint` `State` using the `Indexer` object.
## Run
* If the watcher is a `lazy` watcher:
Setup with:
* Run the server:
```bash
yarn && yarn build
```
```bash
yarn server
```
GQL console: http://localhost:3012/graphql
* If the watcher is an `active` watcher:
* Run the job-runner:
```bash
yarn job-runner
```
* Run the server:
```bash
yarn server
```
GQL console: http://localhost:3012/graphql
* To watch a contract:
```bash
yarn watch:contract --address <contract-address> --kind <contract-kind> --checkpoint <true | false> --starting-block [block-number]
```
* `address`: Address or identifier of the contract to be watched.
* `kind`: Kind of the contract.
* `checkpoint`: Turn checkpointing on (`true` | `false`).
* `starting-block`: Starting block for the contract (default: `1`).
Examples:
Watch a contract with its address and checkpointing on:
```bash
yarn watch:contract --address 0x1F78641644feB8b64642e833cE4AFE93DD6e7833 --kind ERC20 --checkpoint true
```
Watch a contract with its identifier and checkpointing on:
```bash
yarn watch:contract --address MyProtocol --kind protocol --checkpoint true
```
* To fill a block range:
```bash
yarn fill --start-block <from-block> --end-block <to-block>
```
* `start-block`: Block number to start filling from.
* `end-block`: Block number till which to fill.
* To create a checkpoint for a contract:
```bash
yarn checkpoint create --address <contract-address> --block-hash [block-hash]
```
* `address`: Address or identifier of the contract for which to create a checkpoint.
* `block-hash`: Hash of a block (in the pruned region) at which to create the checkpoint (default: latest canonical block hash).
* To verify a checkpoint:
```bash
yarn checkpoint verify --cid <checkpoint-cid>
```
`cid`: CID of the checkpoint for which to verify.
* To reset the watcher to a previous block number:
* Reset watcher:
```bash
yarn reset watcher --block-number <previous-block-number>
```
* Reset job-queue:
```bash
yarn reset job-queue
```
* Reset state:
```bash
yarn reset state --block-number <previous-block-number>
```
* `block-number`: Block number to which to reset the watcher.
* To export and import the watcher state:
* In source watcher, export watcher state:
```bash
yarn export-state --export-file [export-file-path] --block-number [snapshot-block-height]
```
* `export-file`: Path of file to which to export the watcher data.
* `block-number`: Block height at which to take snapshot for export.
* In target watcher, run job-runner:
```bash
yarn job-runner
```
* Import watcher state:
```bash
yarn import-state --import-file <import-file-path>
```
* `import-file`: Path of file from which to import the watcher data.
* Run server:
```bash
yarn server
```
* To inspect a CID:
```bash
yarn inspect-cid --cid <cid>
```
* `cid`: CID to be inspected.
then checkout the [CLI guide](/docs/cli.md) for examples of commands that can be run on this watcher.

View File

@ -1,68 +1,8 @@
# ERC20 Watcher
## Setup
First try the [erc20 demo in stack orchestrator](https://github.com/cerc-io/stack-orchestrator/tree/main/app/data/stacks/erc20) to quickly get started. Advanced users can see [here](/docs/README.md) for instructions on setting up a local environment by hand.
Create a postgres12 database for the job queue:
```
sudo su - postgres
createdb erc20-watcher-job-queue
```
Enable the `pgcrypto` extension on the job queue database (https://github.com/timgit/pg-boss/blob/master/docs/usage.md#intro).
Example:
```
postgres@tesla:~$ psql -U postgres -h localhost erc20-watcher-job-queue
Password for user postgres:
psql (12.7 (Ubuntu 12.7-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
erc20-watcher-job-queue=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION
erc20-watcher-job-queue=# exit
```
Create a postgres12 database for the erc20 watcher:
```
sudo su - postgres
createdb erc20-watcher
```
Update `environments/local.toml` with database connection settings for both the databases.
```toml
[database]
type = "postgres"
host = "localhost"
port = 5432
database = "erc20-watcher"
username = "postgres"
password = "postgres"
[jobQueue]
dbConnectionString = "postgres://postgres:postgres@localhost/erc20-watcher-job-queue"
```
Update the `upstream` config in `environments/local.toml`. Provide the `ipld-eth-server` GQL and RPC API endpoints.
```toml
[upstream]
[upstream.ethServer]
gqlApiEndpoint = "http://127.0.0.1:8082/graphql"
rpcProviderEndpoint = "http://127.0.0.1:8081"
```
Ensure that watcher is of active kind. Update the kind in `server` config to active.
```toml
[server]
kind = "active"
```
## Run
Follow the steps below or follow the [Demo](./demo.md)
## Build
Build files:
@ -70,116 +10,170 @@ Build files:
yarn build
```
Run the watcher:
## Run
Start the job runner:
```bash
$ yarn job-runner
# For development.
$ yarn job-runner:dev
# For specifying config file.
$ yarn job-runner -f environments/local.toml
yarn job-runner
```
Start the server:
For development or to specify the config file:
```bash
yarn job-runner:dev
yarn job-runner -f environments/local.toml
```
Then, Start the server:
```bash
$ yarn server
# For development.
$ yarn server:dev
# For specifying config file.
$ yarn server -f environments/local.toml
yarn server
```
GQL console: http://localhost:3001/graphql
For development or to specify the config file:
```bash
yarn server:dev
yarn server -f environments/local.toml
```
See the GQL console at: http://localhost:3001/graphql
Note: the port may be different depending on your configuration.
Deploy an ERC20 token:
```bash
$ yarn token:deploy
yarn token:deploy
```
In the output you'll see:
```bash
GLD Token deployed to: 0xTokenAddress
```
Export the address of the deployed token to a shell variable for later use:
```bash
export TOKEN_ADDRESS=0xTokenAddress
```
Start watching a token:
Get the main account address:
```bash
$ yarn watch:contract --address 0xTokenAddress --startingBlock <start-block> --kind ERC20 --checkpoint false
# For specifying config file.
$ yarn watch:contract -f environments/local.toml --address 0xTokenAddress --startingBlock <start-block> --kind ERC20 --checkpoint false
yarn account
```
Example:
and export it as well:
```bash
$ yarn watch:contract --address 0xfE0034a874c2707c23F91D7409E9036F5e08ac34 --startingBlock 100 --kind ERC20 --checkpoint false
export PRIMARY_ACCOUNT=0xPrimaryAccount
```
Run the following command to watch the contract:
```bash
yarn watch:contract --address $TOKEN_ADDRESS --kind ERC20 --checkpoint false
```
For specifying a config file:
```bash
yarn watch:contract -f environments/local.toml --address 0xTokenAddress --kind ERC20 --checkpoint false
```
To fill a block range:
```bash
yarn fill --startBlock <from-block> --endBlock <to-block>
# For specifying config file.
$ yarn fill -f environments/local.toml --startBlock <from-block> --endBlock <to-block>
```
Example:
To get the current block hash at any time, run:
```bash
$ yarn fill --startBlock 1000 --endBlock 2000
yarn block:latest
```
### Example GQL Queries
Add a new account to Metamask and export the account address to a shell variable for later use:
```text
{
name(blockHash: "0x5ef95c9847f15179b64fa57994355623f899aca097ad779421b8dff866a8b9c3", token: "0x1ca7c995f8eF0A2989BbcE08D5B7Efe50A584aa1") {
```bash
export RECIPIENT_ADDRESS=0xRecipientAddress
```
Run the following GQL query against the [http://127.0.0.1:3001/graphql](http://127.0.0.1:3001/graphql) to get the name, symbol and total supply of the deployed token:
```graphql
query {
name(
blockHash: "LATEST_BLOCK_HASH"
token: "0xTokenAddress"
) {
value
proof {
data
}
}
symbol(blockHash: "0x5ef95c9847f15179b64fa57994355623f899aca097ad779421b8dff866a8b9c3", token: "0x1ca7c995f8eF0A2989BbcE08D5B7Efe50A584aa1") {
symbol(
blockHash: "LATEST_BLOCK_HASH"
token: "0xTokenAddress"
) {
value
proof {
data
}
}
totalSupply(blockHash: "0x5ef95c9847f15179b64fa57994355623f899aca097ad779421b8dff866a8b9c3", token: "0x1ca7c995f8eF0A2989BbcE08D5B7Efe50A584aa1") {
totalSupply(
blockHash: "LATEST_BLOCK_HASH"
token: "0xTokenAddress"
) {
value
proof {
data
}
}
}
```
balanceOf(blockHash: "0x5ef95c9847f15179b64fa57994355623f899aca097ad779421b8dff866a8b9c3", token: "0x1ca7c995f8eF0A2989BbcE08D5B7Efe50A584aa1", owner: "0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc") {
Run the following GQL query to get balances for the main and the recipient account at the latest block hash:
```graphql
query {
fromBalanceOf: balanceOf(
blockHash: "LATEST_BLOCK_HASH"
token: "0xTokenAddress",
# main/primary account having all the balance initially
owner: "0xPrimaryAccount"
) {
value
proof {
data
}
}
allowance(blockHash: "0x81ed2b04af35b1b276281c37243212731202d5a191a27d07b22a605fd442998d", token: "0x1ca7c995f8eF0A2989BbcE08D5B7Efe50A584aa1", owner: "0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc", spender: "0xCA6D29232D1435D8198E3E5302495417dD073d61") {
toBalanceOf: balanceOf(
blockHash: "LATEST_BLOCK_HASH"
token: "0xTokenAddress",
owner: "0xRecipientAddress"
) {
value
proof {
data
}
}
}
```
events(blockHash: "0x3441ba476dff95c58528afe754ceec659e0ef8ff1b59244ec4545f4f9784a51c", token: "0x1ca7c995f8eF0A2989BbcE08D5B7Efe50A584aa1") {
Run the following GQL subscription at the GraphQL endpoint:
```graphql
subscription {
onEvent {
blockHash
contract
event {
__typename
... on TransferEvent {
from
to
value
}
},
... on ApprovalEvent {
owner
spender
@ -192,3 +186,13 @@ $ yarn fill --startBlock 1000 --endBlock 2000
}
}
```
Transfer tokens to the recipient account:
```bash
yarn token:transfer --token $TOKEN_ADDRESS --to $RECIPIENT_ADDRESS --amount 100
```
A Transfer event to the `RECIPIENT_ADDRESS` should be visible in the subscription.
Get the latest block hash again, then fire the GQL query above to get updated balances for the main (from) and the recipient (to) account.

View File

@ -1,200 +0,0 @@
# Demo
* The following core services need to be running for the demo:
* [ipld-eth-db](https://github.com/cerc-io/ipld-eth-db)
* Version: [v4.2.3-alpha](https://github.com/cerc-io/ipld-eth-db/releases/tag/v4.2.3-alpha)
* [geth](https://github.com/cerc-io/go-ethereum)
* State diffing service should use `ipld-eth-db` for database.
* Version: [v1.10.26-statediff-4.2.2-alpha](https://github.com/cerc-io/go-ethereum/releases/tag/v1.10.26-statediff-4.2.2-alpha)
* Endpoint: http://127.0.0.1:8545
* [ipld-eth-server](https://github.com/cerc-io/ipld-eth-server)
* Should use `ipld-eth-db` for database.
* Version: [v4.2.3-alpha](https://github.com/cerc-io/ipld-eth-server/releases/tag/v4.2.3-alpha)
* Endpoints:
* GQL: http://127.0.0.1:8082/graphql
* RPC: http://127.0.0.1:8081
* Create a postgres12 database for the watcher:
```bash
sudo su - postgres
# If database already exists
# dropdb erc20-watcher
createdb erc20-watcher
```
* Create database for the job queue and enable the `pgcrypto` extension on them (https://github.com/timgit/pg-boss/blob/master/docs/usage.md#intro):
```bash
# If database already exists
# dropdb erc20-watcher-job-queue
createdb erc20-watcher-job-queue
```
```
postgres@tesla:~$ psql -U postgres -h localhost erc20-watcher-job-queue
Password for user postgres:
psql (12.7 (Ubuntu 12.7-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
erc20-watcher-job-queue=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION
erc20-watcher-job-queue=# exit
```
* In the [config file](./environments/local.toml) update the `database` connection settings.
* In `watcher-ts` repo, follow the instructions in [Setup](../../README.md#setup) for installing and building packages.
```bash
# After setup
yarn && yarn build
```
* Run the job-runner:
```bash
yarn job-runner
```
* Run the watcher:
```bash
yarn server
```
* Deploy an ERC20 token:
```bash
yarn token:deploy
# GLD Token deployed to: TOKEN_ADDRESS
```
Export the address of the deployed token to a shell variable for later use:
```bash
export TOKEN_ADDRESS="<TOKEN_ADDRESS>"
```
* Run the following command to watch the contract:
```bash
yarn watch:contract --address $TOKEN_ADDRESS --kind ERC20 --checkpoint false
```
* Add a second account to Metamask and export the account address to a shell variable for later use:
```bash
export RECIPIENT_ADDRESS="<RECIPIENT_ADDRESS>"
```
* To get the current block hash at any time, run:
```bash
yarn block:latest
```
* Run the following GQL query against the [GraphQL endpoint](http://127.0.0.1:3001/graphql) to get name, symbol and total supply of the deployed token:
```graphql
query {
name(
blockHash: "LATEST_BLOCK_HASH"
token: "TOKEN_ADDRESS"
) {
value
proof {
data
}
}
symbol(
blockHash: "LATEST_BLOCK_HASH"
token: "TOKEN_ADDRESS"
) {
value
proof {
data
}
}
totalSupply(
blockHash: "LATEST_BLOCK_HASH"
token: "TOKEN_ADDRESS"
) {
value
proof {
data
}
}
}
```
* Run the following GQL query against the [GraphQL endpoint](http://127.0.0.1:3001/graphql) to get balances for the main and the recipient account at the latest block hash:
```graphql
query {
fromBalanceOf: balanceOf(
blockHash: "LATEST_BLOCK_HASH"
token: "TOKEN_ADDRESS",
# main account having all the balance initially
owner: "0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc"
) {
value
proof {
data
}
}
toBalanceOf: balanceOf(
blockHash: "LATEST_BLOCK_HASH"
token: "TOKEN_ADDRESS",
owner: "RECIPIENT_ADDRESS"
) {
value
proof {
data
}
}
}
```
* Run the following GQL subscription at the GraphQL endpoint:
```graphql
subscription {
onEvent {
blockHash
contract
event {
__typename
... on TransferEvent {
from
to
value
},
... on ApprovalEvent {
owner
spender
value
}
}
proof {
data
}
}
}
```
* Transfer tokens to the recipient account:
```bash
yarn token:transfer --token $TOKEN_ADDRESS --to $RECIPIENT_ADDRESS --amount 100
```
* A Transfer event to RECIPIENT_ADDRESS shall be visible in the subscription at endpoint.
* Fire the GQL query above to get updated balances for the main (from) and the recipient (to) account.

View File

@ -1,202 +1,305 @@
# erc721-watcher
First try the [erc721 demo in stack orchestrator](https://github.com/cerc-io/stack-orchestrator/tree/main/app/data/stacks/erc721) to quickly get started. Advanced users can see [here](/docs/README.md) for instructions on setting up a local environment by hand.
## Setup
* Run the following command to install required packages:
Run the following command to install required packages:
```bash
yarn
```bash
yarn && yarn build
```
If the watcher is "active", first run the job-runner:
```bash
yarn job-runner
```
then run the watcher:
```bash
yarn server
```
For "lazy" watchers, you only need to run the above command.
Deploy an ERC721 token:
```bash
yarn nft:deploy
```
```
# NFT deployed to: 0xNFTAddress
```
Export the address of the deployed token to a shell variable for later use:
```bash
export NFT_ADDRESS="0xNFTAddress"
```
* Create a postgres12 database for the watcher:
```bash
sudo su - postgres
createdb erc721-watcher
```
* If the watcher is an `active` watcher:
Create database for the job queue and enable the `pgcrypto` extension on them (https://github.com/timgit/pg-boss/blob/master/docs/usage.md#intro):
```
createdb erc721-watcher-job-queue
```
```
postgres@tesla:~$ psql -U postgres -h localhost erc721-watcher-job-queue
Password for user postgres:
psql (12.7 (Ubuntu 12.7-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
erc721-watcher-job-queue=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION
erc721-watcher-job-queue=# exit
```
* The following core services should be setup and running on localhost:
* `vulcanize/go-ethereum` [v1.10.18-statediff-4.0.2-alpha](https://github.com/vulcanize/go-ethereum/releases/tag/v1.10.18-statediff-4.0.2-alpha) on port 8545
* `vulcanize/ipld-eth-server` [v4.0.3-alpha](https://github.com/vulcanize/ipld-eth-server/releases/tag/v4.0.3-alpha) with native GQL API enabled, on port 8082
* In the [config file](./environments/local.toml):
* Update the database connection settings.
* Update the `upstream` config and provide the `ipld-eth-server` GQL API endpoint.
* Update the `server` config with state checkpoint settings.
## Customize
* Indexing on an event:
* Edit the custom hook function `handleEvent` (triggered on an event) in [hooks.ts](./src/hooks.ts) to perform corresponding indexing using the `Indexer` object.
* While using the indexer storage methods for indexing, pass `diff` as true if default state is desired to be generated using the state variables being indexed.
* Generating state:
* Edit the custom hook function `createInitialState` (triggered if the watcher passes the start block, checkpoint: `true`) in [hooks.ts](./src/hooks.ts) to save an initial `State` using the `Indexer` object.
* Edit the custom hook function `createStateDiff` (triggered on a block) in [hooks.ts](./src/hooks.ts) to save the state in a `diff` `State` using the `Indexer` object. The default state (if exists) is updated.
* Edit the custom hook function `createStateCheckpoint` (triggered just before default and CLI checkpoint) in [hooks.ts](./src/hooks.ts) to save the state in a `checkpoint` `State` using the `Indexer` object.
## Run
Follow the steps below or follow the [Demo](./demo.md)
* Run the watcher:
* If the watcher is a `lazy` watcher:
* Run the server:
```bash
yarn server
```
GQL console: http://localhost:3006/graphql
* If the watcher is an `active` watcher:
* Run the job-runner:
```bash
yarn job-runner
```
* Run the server:
```bash
yarn server
```
GQL console: http://localhost:3012/graphql
* To watch a contract:
```bash
yarn watch:contract --address <contract-address> --kind <contract-kind> --checkpoint <true | false> --starting-block [block-number]
```
* `address`: Address or identifier of the contract to be watched.
* `kind`: Kind of the contract.
* `checkpoint`: Turn checkpointing on (`true` | `false`).
* `starting-block`: Starting block for the contract (default: `1`).
Examples:
Watch a contract with its address and checkpointing on:
```bash
yarn watch:contract --address 0x1F78641644feB8b64642e833cE4AFE93DD6e7833 --kind ERC721 --checkpoint true
```
Watch a contract with its identifier and checkpointing on:
```bash
yarn watch:contract --address MyProtocol --kind protocol --checkpoint true
```
* To fill a block range:
```bash
yarn fill --start-block <from-block> --end-block <to-block>
```
* `start-block`: Block number to start filling from.
* `end-block`: Block number till which to fill.
* To create a checkpoint for a contract:
```bash
yarn checkpoint create --address <contract-address> --block-hash [block-hash]
```
* `address`: Address or identifier of the contract for which to create a checkpoint.
* `block-hash`: Hash of a block (in the pruned region) at which to create the checkpoint (default: latest canonical block hash).
* To reset the watcher to a previous block number:
* Reset watcher:
```bash
yarn reset watcher --block-number <previous-block-number>
```
* Reset job-queue:
```bash
yarn reset job-queue
```
* Reset state:
```bash
yarn reset state --block-number <previous-block-number>
```
* `block-number`: Block number to which to reset the watcher.
* To export and import the watcher state:
* In source watcher, export watcher state:
```bash
yarn export-state --export-file [export-file-path] --block-number [snapshot-block-height]
```
* `export-file`: Path of file to which to export the watcher data.
* `block-number`: Block height at which to take snapshot for export.
* In target watcher, run job-runner:
```bash
yarn job-runner
```
* Import watcher state:
```bash
yarn import-state --import-file <import-file-path>
```
* `import-file`: Path of file from which to import the watcher data.
* Run server:
```bash
yarn server
```
* To inspect a CID:
```bash
yarn inspect-cid --cid <cid>
```
* `cid`: CID to be inspected.
Run the following GQL mutation in generated watcher GraphQL endpoint http://127.0.0.1:3006/graphql
```graphql
mutation {
watchContract(
address: "0xNFTAddress"
kind: "ERC721"
checkpoint: true
)
}
```
TODO: settle on WC (signer/primary/main...across the docs)
Get the signer (primary/main) account address and export to a shell variable:
```bash
yarn account
```
```bash
export SIGNER_ADDRESS="0xSignerAddress"
```
Connect MetaMask to `http://localhost:8545` (with chain ID `99`)
Add a an account to Metamask and export the account address to a shell variable for later use:
```bash
export RECIPIENT_ADDRESS="0xRecipientAddress"
```
To get the current block hash at any time, run:
```bash
yarn block:latest
```
Run the following GQL query (`eth_call`) in the GraphQL playground at http://127.0.0.1:3006/graphql
```graphql
query {
name(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "0xNFTAddress"
) {
value
proof {
data
}
}
symbol(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "0xNFTAddress"
) {
value
proof {
data
}
}
balanceOf(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "0xNFTAddress"
owner: "0xSignerAddress"
) {
value
proof {
data
}
}
}
```
Run the following GQL query (`storage`) in generated watcher GraphQL endpoint http://127.0.0.1:3006/graphql
```graphql
query {
_name(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "0xNFTAddress"
) {
value
proof {
data
}
}
_symbol(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "0xNFTAddress"
) {
value
proof {
data
}
}
_balances(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "0xNFTAddress"
key0: "0xSignerAddress"
) {
value
proof {
data
}
}
}
```
Run the following GQL subscription in the playground:
```graphql
subscription {
onEvent {
event {
__typename
... on TransferEvent {
from
to
tokenId
},
... on ApprovalEvent {
owner
approved
tokenId
}
},
block {
number
hash
}
}
}
```
Mint token
```bash
yarn nft:mint --nft $NFT_ADDRESS --to $SIGNER_ADDRESS --token-id 1
```
- A Transfer event to 0xSignerAddress should be visible in the subscription.
- An auto-generated `diff_staged` `State` should be added with parent CID pointing to the initial `checkpoint` `State`.
- Custom property `transferCount` should be 1 initially.
- Run the `getState` query at the endpoint to get the latest `State` for 0xNFTAddress:
```graphql
query {
getState (
blockHash: "EVENT_BLOCK_HASH"
contractAddress: "0xNFTAddress"
# kind: "checkpoint"
# kind: "diff"
kind: "diff_staged"
) {
cid
block {
cid
hash
number
timestamp
parentHash
}
contractAddress
data
}
}
```
- `diff` States get created corresponding to the `diff_staged` blocks when their respective eth_blocks reach the pruned region.
- `data` contains the default state and also the custom state property `transferCount` that is indexed in [hooks.ts](./src/hooks.ts) file.
- Get the latest blockHash and run the following query for `transferCount` entity:
```graphql
query {
transferCount(
block: {
hash: "LATEST_BLOCK_HASH"
}
id: "0xNFTAddress"
) {
id
count
}
}
```
*Note: Contract address is assigned to the Entity ID.*
With the latest blockHash, run the following query for `balanceOf` and `ownerOf` (`eth_call`):
```graphql
query {
fromBalanceOf: balanceOf(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "0xNFTAddress"
owner: "0xSignerAddress"
) {
value
proof {
data
}
}
toBalanceOf: balanceOf(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "0xNFTAddress"
owner: "0xRecipientAddress"
) {
value
proof {
data
}
}
ownerOf(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "0xNFTAddress"
tokenId: 1
) {
value
proof {
data
}
}
}
```
Transfer token
```bash
yarn nft:transfer --nft $NFT_ADDRESS --from $SIGNER_ADDRESS --to $RECIPIENT_ADDRESS --token-id 1
```
- An Approval event for SIGNER_ADDRESS shall be visible in the subscription at endpoint.
- A Transfer event to $RECIPIENT_ADDRESS shall be visible in the subscription at endpoint.
- An auto-generated `diff_staged` State should be added with parent CID pointing to the previous State.
- Custom property `transferCount` should be incremented after transfer. This can be checked in the `getState` query.
- Get the latest blockHash and replace the blockHash in the above `eth_call` query. The result should be different and the token should be transferred to the recipient.
- Run the `getState` query again at the endpoint with the event blockHash.
- Run the `transferCount` entity query again with the latest blockHash. The updated count should be returned.
- After the `diff` block has been created (can check if event block number pruned in yarn server log), create a checkpoint using CLI in `packages/erc721-watcher`:
```bash
yarn checkpoint create --address $NFT_ADDRESS
```
- Run the `getState` query again with the output blockHash and kind `checkpoint` at the endpoint.
- The latest checkpoint should have the aggregate of state diffs since the last checkpoint.
- The `State` entries can be seen in pg-admin in table `state`.
- The state should have auto indexed data and also custom property `transferCount` according to code in [hooks](./src/hooks.ts) file `handleEvent` method.
For more `yarn` sub-commands available, see the [CLI guide](/docs/cli.md)

View File

@ -1,343 +0,0 @@
# Demo
* The following core services need to be running for the demo:
* [ipld-eth-db](https://github.com/cerc-io/ipld-eth-db)
* Version: [v4.2.3-alpha](https://github.com/cerc-io/ipld-eth-db/releases/tag/v4.2.3-alpha)
* [geth](https://github.com/cerc-io/go-ethereum)
* State diffing service should use `ipld-eth-db` for database.
* Version: [v1.10.26-statediff-4.2.2-alpha](https://github.com/cerc-io/go-ethereum/releases/tag/v1.10.26-statediff-4.2.2-alpha)
* Endpoint: http://127.0.0.1:8545
* [ipld-eth-server](https://github.com/cerc-io/ipld-eth-server)
* Should use `ipld-eth-db` for database.
* Version: [v4.2.3-alpha](https://github.com/cerc-io/ipld-eth-server/releases/tag/v4.2.3-alpha)
* Endpoints:
* GQL: http://127.0.0.1:8082/graphql
* RPC: http://127.0.0.1:8081
* Create a postgres12 database for the watcher:
```bash
sudo su - postgres
# If database already exists
# dropdb erc721-watcher
createdb erc721-watcher
```
* Create database for the job queue and enable the `pgcrypto` extension on them (https://github.com/timgit/pg-boss/blob/master/docs/usage.md#intro):
```bash
# If database already exists
# dropdb erc721-watcher-job-queue
createdb erc721-watcher-job-queue
```
```
postgres@tesla:~$ psql -U postgres -h localhost erc721-watcher-job-queue
Password for user postgres:
psql (12.7 (Ubuntu 12.7-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
erc721-watcher-job-queue=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION
erc721-watcher-job-queue=# exit
```
* In the [config file](./environments/local.toml) update the `database` connection settings.
* In `watcher-ts` repo, follow the instructions in [Setup](../../README.md#setup) for installing and building packages.
```bash
# After setup
yarn && yarn build
```
* Run the job-runner:
```bash
yarn job-runner
```
* Run the watcher:
```bash
yarn server
```
* Deploy an ERC721 token:
```bash
yarn nft:deploy
# NFT deployed to: NFT_ADDRESS
```
Export the address of the deployed token to a shell variable for later use:
```bash
export NFT_ADDRESS="<NFT_ADDRESS>"
```
* Run the following GQL mutation in generated watcher GraphQL endpoint http://127.0.0.1:3006/graphql
```graphql
mutation {
watchContract(
address: "NFT_ADDRESS"
kind: "ERC721"
checkpoint: true
)
}
```
* Get the signer account address and export to a shell variable:
```bash
yarn account
```
```bash
export SIGNER_ADDRESS="<SIGNER_ADDRESS>"
```
* Connect MetaMask to `http://localhost:8545` (with chain ID `99`)
* Add a second account to Metamask and export the account address to a shell variable for later use:
```bash
export RECIPIENT_ADDRESS="<RECIPIENT_ADDRESS>"
```
* To get the current block hash at any time, run:
```bash
yarn block:latest
```
* Run the following GQL query (`eth_call`) in generated watcher GraphQL endpoint http://127.0.0.1:3006/graphql
```graphql
query {
name(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "NFT_ADDRESS"
) {
value
proof {
data
}
}
symbol(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "NFT_ADDRESS"
) {
value
proof {
data
}
}
balanceOf(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "NFT_ADDRESS"
owner: "SIGNER_ADDRESS"
) {
value
proof {
data
}
}
}
```
* Run the following GQL query (`storage`) in generated watcher GraphQL endpoint http://127.0.0.1:3006/graphql
```graphql
query {
_name(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "NFT_ADDRESS"
) {
value
proof {
data
}
}
_symbol(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "NFT_ADDRESS"
) {
value
proof {
data
}
}
_balances(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "NFT_ADDRESS"
key0: "SIGNER_ADDRESS"
) {
value
proof {
data
}
}
}
```
* Run the following GQL subscription in generated watcher GraphQL endpoint:
```graphql
subscription {
onEvent {
event {
__typename
... on TransferEvent {
from
to
tokenId
},
... on ApprovalEvent {
owner
approved
tokenId
}
},
block {
number
hash
}
}
}
```
* Mint token
```bash
yarn nft:mint --nft $NFT_ADDRESS --to $SIGNER_ADDRESS --token-id 1
```
* A Transfer event to SIGNER_ADDRESS shall be visible in the subscription at endpoint.
* An auto-generated `diff_staged` `State` should be added with parent CID pointing to the initial `checkpoint` `State`.
* Custom property `transferCount` should be 1 initially.
* Run the `getState` query at the endpoint to get the latest `State` for NFT_ADDRESS:
```graphql
query {
getState (
blockHash: "EVENT_BLOCK_HASH"
contractAddress: "NFT_ADDRESS"
# kind: "checkpoint"
# kind: "diff"
kind: "diff_staged"
) {
cid
block {
cid
hash
number
timestamp
parentHash
}
contractAddress
data
}
}
```
* `diff` States get created corresponding to the `diff_staged` blocks when their respective eth_blocks reach the pruned region.
* `data` contains the default state and also the custom state property `transferCount` that is indexed in [hooks.ts](./src/hooks.ts) file.
* Get the latest blockHash and run the following query for `transferCount` entity:
```graphql
query {
transferCount(
block: {
hash: "LATEST_BLOCK_HASH"
}
id: "NFT_ADDRESS"
) {
id
count
}
}
```
*Note: Contract address is assigned to the Entity ID.*
* With the latest blockHash, run the following query for `balanceOf` and `ownerOf` (`eth_call`):
```graphql
query {
fromBalanceOf: balanceOf(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "NFT_ADDRESS"
owner: "SIGNER_ADDRESS"
) {
value
proof {
data
}
}
toBalanceOf: balanceOf(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "NFT_ADDRESS"
owner: "RECIPIENT_ADDRESS"
) {
value
proof {
data
}
}
ownerOf(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "NFT_ADDRESS"
tokenId: 1
) {
value
proof {
data
}
}
}
```
* Transfer token
```bash
yarn nft:transfer --nft $NFT_ADDRESS --from $SIGNER_ADDRESS --to $RECIPIENT_ADDRESS --token-id 1
```
* An Approval event for SIGNER_ADDRESS shall be visible in the subscription at endpoint.
* A Transfer event to $RECIPIENT_ADDRESS shall be visible in the subscription at endpoint.
* An auto-generated `diff_staged` State should be added with parent CID pointing to the previous State.
* Custom property `transferCount` should be incremented after transfer. This can be checked in the `getState` query.
* Get the latest blockHash and replace the blockHash in the above `eth_call` query. The result should be different and the token should be transferred to the recipient.
* Run the `getState` query again at the endpoint with the event blockHash.
* Run the `transferCount` entity query again with the latest blockHash. The updated count should be returned.
* After the `diff` block has been created (can check if event block number pruned in yarn server log), create a checkpoint using CLI in `packages/erc721-watcher`:
```bash
yarn checkpoint create --address $NFT_ADDRESS
```
* Run the `getState` query again with the output blockHash and kind `checkpoint` at the endpoint.
* The latest checkpoint should have the aggregate of state diffs since the last checkpoint.
* The `State` entries can be seen in pg-admin in table `state`.
* The state should have auto indexed data and also custom property `transferCount` according to code in [hooks](./src/hooks.ts) file `handleEvent` method.

View File

@ -2,201 +2,140 @@
## Setup
* Run the following command to install required packages:
First try the [stack orchestrator](https://github.com/cerc-io/stack-orchestrator) to quickly get started. Advanced users can see [here](/docs/README.md) for instructions on setting up a local environment by hand.
```bash
yarn
```
Run the following command to install required packages:
* Create a postgres12 database for the watcher:
```bash
sudo su - postgres
createdb graph-test-watcher
```
* If the watcher is an `active` watcher:
Create database for the job queue and enable the `pgcrypto` extension on them (https://github.com/timgit/pg-boss/blob/master/docs/usage.md#intro):
```
createdb graph-test-watcher-job-queue
```
```
postgres@tesla:~$ psql -U postgres -h localhost graph-test-watcher-job-queue
Password for user postgres:
psql (12.7 (Ubuntu 12.7-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
graph-test-watcher-job-queue=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION
graph-test-watcher-job-queue=# exit
```
* In the [config file](./environments/local.toml):
* Update the database connection settings.
* Update the `upstream` config and provide the `ipld-eth-server` GQL API endpoint.
* Update the `server` config with state checkpoint settings.
## Customize
* Indexing on an event:
* Edit the custom hook function `handleEvent` (triggered on an event) in [hooks.ts](./src/hooks.ts) to perform corresponding indexing using the `Indexer` object.
* While using the indexer storage methods for indexing, pass `diff` as true if default state is desired to be generated using the state variables being indexed.
* Generating state:
* Edit the custom hook function `createInitialState` (triggered if the watcher passes the start block, checkpoint: `true`) in [hooks.ts](./src/hooks.ts) to save an initial `State` using the `Indexer` object.
* Edit the custom hook function `createStateDiff` (triggered on a block) in [hooks.ts](./src/hooks.ts) to save the state in a `diff` `State` using the `Indexer` object. The default state (if exists) is updated.
* Edit the custom hook function `createStateCheckpoint` (triggered just before default and CLI checkpoint) in [hooks.ts](./src/hooks.ts) to save the state in a `checkpoint` `State` using the `Indexer` object.
* The existing example hooks in [hooks.ts](./src/hooks.ts) are for an `ERC20` contract.
```bash
yarn
```
## Run
Follow the steps below or follow the [Demo](./demo.md)
* In [packages/graph-node](../graph-node/), deploy an `Example` contract:
* Run the server:
```bash
yarn example:deploy
```
* Set the returned address to the variable `$EXAMPLE_ADDRESS`:
```bash
EXAMPLE_ADDRESS=<EXAMPLE_ADDRESS>
```
* In [packages/graph-node/test/subgraph/example1/subgraph.yaml](../graph-node/test/subgraph/example1/subgraph.yaml):
* Set the source address for `Example1` datasource to the `EXAMPLE_ADDRESS`.
* Set the `startBlock` less than or equal to the latest mined block.
* Build the example subgraph:
```bash
yarn build:example
```
* Run the job-runner:
```bash
yarn job-runner
```
* Run the watcher:
```bash
yarn server
```
GQL console: http://localhost:3008/graphql
* The output from the block handler in the mapping code should be visible in the `job-runner` for each block.
* If the watcher is an `active` watcher:
* Run the following GQL subscription at the graphql endpoint http://127.0.0.1:3008/graphql
* Run the job-runner:
```graphql
subscription {
onEvent {
event {
__typename
... on TestEvent {
param1
param2
},
},
block {
number
hash
}
}
}
```
* In [packages/graph-node](../graph-node/), trigger the `Test` event by calling a example contract method:
```bash
yarn example:test --address $EXAMPLE_ADDRESS
```
* A `Test` event shall be visible in the subscription at endpoint.
* The subgraph entity `Category` should be updated in the database.
* An auto-generated `diff-staged` entry `State` should be added.
* Run the query for entity in at the endpoint:
```graphql
query {
category(
block: { hash: "EVENT_BLOCK_HASH" },
id: "1"
) {
__typename
id
count
name
}
}
```
* Run the `getState` query at the endpoint to get the latest `State` for `EXAMPLE_ADDRESS`:
```graphql
query {
getState (
blockHash: "EVENT_BLOCK_HASH"
contractAddress: "EXAMPLE_ADDRESS"
# kind: "checkpoint"
# kind: "diff"
kind: "diff_staged"
) {
cid
block {
cid
hash
number
timestamp
parentHash
}
contractAddress
data
}
}
```
* `diff` states get created corresponding to the `diff_staged` states when their respective blocks reach the pruned region.
* In [packages/graph-test-watcher](./):
* After the `diff` state has been created, create a `checkpoint`:
```bash
yarn job-runner
yarn checkpoint create --address $EXAMPLE_ADDRESS
```
* Run the server:
* A `checkpoint` state should be created at the latest canonical block hash.
```bash
yarn server
```
* Run the `getState` query again at the endpoint with the output `blockHash` and kind `checkpoint`.
* All the `State` entries can be seen in `pg-admin` in table `state`.
GQL console: http://localhost:3008/graphql
* To watch a contract:
```bash
yarn watch:contract --address <contract-address> --kind <contract-kind> --checkpoint <true | false> --starting-block [block-number]
```
* `address`: Address or identifier of the contract to be watched.
* `kind`: Kind of the contract.
* `checkpoint`: Turn checkpointing on (`true` | `false`).
* `starting-block`: Starting block for the contract (default: `1`).
Examples:
Watch a contract with its address and checkpointing on:
```bash
yarn watch:contract --address 0x1F78641644feB8b64642e833cE4AFE93DD6e7833 --kind ERC20 --checkpoint true
```
Watch a contract with its identifier and checkpointing on:
```bash
yarn watch:contract --address MyProtocol --kind protocol --checkpoint true
```
* To fill a block range:
```bash
yarn fill --start-block <from-block> --end-block <to-block>
```
* `start-block`: Block number to start filling from.
* `end-block`: Block number till which to fill.
* To create a checkpoint for a contract:
```bash
yarn checkpoint create --address <contract-address> --block-hash [block-hash]
```
* `address`: Address or identifier of the contract for which to create a checkpoint.
* `block-hash`: Hash of a block (in the pruned region) at which to create the checkpoint (default: latest canonical block hash).
* To verify a checkpoint:
```bash
yarn checkpoint verify --cid <checkpoint-cid>
```
`cid`: CID of the checkpoint for which to verify.
* To reset the watcher to a previous block number:
* Reset watcher:
```bash
yarn reset watcher --block-number <previous-block-number>
```
* Reset job-queue:
```bash
yarn reset job-queue
```
* Reset state:
```bash
yarn reset state --block-number <previous-block-number>
```
* `block-number`: Block number to which to reset the watcher.
* To export and import the watcher state:
* In source watcher, export watcher state:
```bash
yarn export-state --export-file [export-file-path] --block-number [snapshot-block-height]
```
* `export-file`: Path of file to which to export the watcher data.
* `block-number`: Block height at which to take snapshot for export.
* In target watcher, run job-runner:
```bash
yarn job-runner
```
* Import watcher state:
```bash
yarn import-state --import-file <import-file-path>
```
* `import-file`: Path of file from which to import the watcher data.
* Run server:
```bash
yarn server
```
* To inspect a CID:
```bash
yarn inspect-cid --cid <cid>
```
* `cid`: CID to be inspected.
* The existing example hooks in [hooks.ts](./src/hooks.ts) are for an `ERC20` contract.

View File

@ -1,182 +0,0 @@
# Demo
* The following core services need to be running for the demo:
* [ipld-eth-db](https://github.com/cerc-io/ipld-eth-db)
* Version: [v4.2.3-alpha](https://github.com/cerc-io/ipld-eth-db/releases/tag/v4.2.3-alpha)
* [geth](https://github.com/cerc-io/go-ethereum)
* State diffing service should use `ipld-eth-db` for database.
* Version: [v1.10.26-statediff-4.2.2-alpha](https://github.com/cerc-io/go-ethereum/releases/tag/v1.10.26-statediff-4.2.2-alpha)
* Endpoint: http://127.0.0.1:8545
* [ipld-eth-server](https://github.com/cerc-io/ipld-eth-server)
* Should use `ipld-eth-db` for database.
* Version: [v4.2.3-alpha](https://github.com/cerc-io/ipld-eth-server/releases/tag/v4.2.3-alpha)
* Endpoints:
* GQL: http://127.0.0.1:8082/graphql
* RPC: http://127.0.0.1:8081
* Create a postgres12 database for the watcher:
```bash
sudo su - postgres
# If database already exists
# dropdb graph-test-watcher
createdb graph-test-watcher
```
* Create database for the job queue and enable the `pgcrypto` extension on them (https://github.com/timgit/pg-boss/blob/master/docs/usage.md#intro):
```bash
# If database already exists
# dropdb graph-test-watcher-job-queue
createdb graph-test-watcher-job-queue
```
```
postgres@tesla:~$ psql -U postgres -h localhost graph-test-watcher-job-queue
Password for user postgres:
psql (12.7 (Ubuntu 12.7-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
graph-test-watcher-job-queue=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION
graph-test-watcher-job-queue=# exit
```
* In the [config file](./environments/local.toml) update the `database` connection settings.
* In `watcher-ts` repo, follow the instructions in [Setup](../../README.md#setup) for installing and building packages.
```bash
# After setup
yarn && yarn build
```
* In [packages/graph-node](../graph-node/), deploy an `Example` contract:
```bash
yarn example:deploy
```
* Set the returned address to the variable `$EXAMPLE_ADDRESS`:
```bash
EXAMPLE_ADDRESS=<EXAMPLE_ADDRESS>
```
* In [packages/graph-node/test/subgraph/example1/subgraph.yaml](../graph-node/test/subgraph/example1/subgraph.yaml):
* Set the source address for `Example1` datasource to the `EXAMPLE_ADDRESS`.
* Set the `startBlock` less than or equal to the latest mined block.
* Build the example subgraph:
```bash
yarn build:example
```
* Run the job-runner:
```bash
yarn job-runner
```
* Run the watcher:
```bash
yarn server
```
* The output from the block handler in the mapping code should be visible in the `job-runner` for each block.
* Run the following GQL subscription at the graphql endpoint http://127.0.0.1:3008/graphql
```graphql
subscription {
onEvent {
event {
__typename
... on TestEvent {
param1
param2
},
},
block {
number
hash
}
}
}
```
* In [packages/graph-node](../graph-node/), trigger the `Test` event by calling a example contract method:
```bash
yarn example:test --address $EXAMPLE_ADDRESS
```
* A `Test` event shall be visible in the subscription at endpoint.
* The subgraph entity `Category` should be updated in the database.
* An auto-generated `diff-staged` entry `State` should be added.
* Run the query for entity in at the endpoint:
```graphql
query {
category(
block: { hash: "EVENT_BLOCK_HASH" },
id: "1"
) {
__typename
id
count
name
}
}
```
* Run the `getState` query at the endpoint to get the latest `State` for `EXAMPLE_ADDRESS`:
```graphql
query {
getState (
blockHash: "EVENT_BLOCK_HASH"
contractAddress: "EXAMPLE_ADDRESS"
# kind: "checkpoint"
# kind: "diff"
kind: "diff_staged"
) {
cid
block {
cid
hash
number
timestamp
parentHash
}
contractAddress
data
}
}
```
* `diff` states get created corresponding to the `diff_staged` states when their respective blocks reach the pruned region.
* In [packages/graph-test-watcher](./):
* After the `diff` state has been created, create a `checkpoint`:
```bash
yarn checkpoint create --address $EXAMPLE_ADDRESS
```
* A `checkpoint` state should be created at the latest canonical block hash.
* Run the `getState` query again at the endpoint with the output `blockHash` and kind `checkpoint`.
* All the `State` entries can be seen in `pg-admin` in table `state`.

View File

@ -1,192 +1,281 @@
# mobymask-watcher
# MobyMask Watcher
First try the [mobymask demo in stack orchestrator](https://github.com/cerc-io/stack-orchestrator/tree/main/app/data/stacks/mobymask) to quickly get started. Advanced users can see [here](/docs/README.md) for instructions on setting up a local environment by hand.
## Setup
* Run the following command to install required packages:
Run the following command to install required packages:
```bash
yarn
```bash
yarn && yarn build
```
If the watcher is "lazy", run the server:
```bash
yarn server
```
GQL console: http://localhost:3010/graphql
If the watcher is "active", run the job-runner:
```bash
yarn job-runner
```
then the server:
```bash
yarn server
```
Next, clone the MobyMask repo and checkout this branch:
```bash
git clone https://github.com/cerc-io/MobyMask && cd MobyMask
git checkout use-laconic-watcher-as-hosted-index
```
Install the packages:
```bash
yarn
```
Deploy the contract:
```bash
cd packages/hardhat
yarn deploy
# deploying "PhisherRegistry" (tx: 0xaebeb2e883ece1f679304ec46f5dc61ca74f9e168427268a7dfa8802195b8de0)...: deployed at 0xMobyAddress with 2306221 gas
# $ hardhat run scripts/publish.js
# ✅ Published contracts to the subgraph package.
# Done in 14.28s.
```
Export the address of the deployed contract to a shell variable for later use:
```bash
export MOBY_ADDRESS="0xMobyAddress"
```
Run the following GQL mutation in watcher GraphQL endpoint http://127.0.0.1:3010/graphql
```graphql
mutation {
watchContract(
address: "MOBY_ADDRESS"
kind: "PhisherRegistry"
checkpoint: true
)
}
```
Get the latest block
```graphql
query {
latestBlock {
hash
number
}
}
```
* Create a postgres12 database for the watcher:
Run the following GQL query in GraphQL endpoint
```graphql
query {
isPhisher(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "MOBY_ADDRESS"
key0: "TWT:phishername"
) {
value
proof {
data
}
}
isMember(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "MOBY_ADDRESS"
key0: "TWT:membername"
) {
value
proof {
data
}
}
}
```
Run the following GQL subscription in generated watcher GraphQL endpoint:
```graphql
subscription {
onEvent {
event {
__typename
... on PhisherStatusUpdatedEvent {
entity
isPhisher
},
... on MemberStatusUpdatedEvent {
entity
isMember
}
},
block {
number
hash
}
}
}
```
Update isPhiser and isMember lists with names
```bash
yarn claimPhisher --contract $MOBY_ADDRESS --name phisherName
```
```bash
yarn claimMember --contract $MOBY_ADDRESS --name memberName
```
- The events should be visible in the subscription at GQL endpoint. Note down the event blockHash from result.
- The isMember and isPhisher lists should be indexed. Check the database (mobymask-watcher) tables `is_phisher` and `is_member`, there should be entries at the event blockHash and the value should be true. The data is indexed in `handleEvent` method in the [hooks file](./src/hooks.ts).
Update the the previous query with event blockHash and check isPhisher and isMember in GraphQL playground
```graphql
query {
isPhisher(
blockHash: "EVENT_BLOCK_HASH"
contractAddress: "MOBY_ADDRESS",
key0: "TWT:phishername"
) {
value
proof {
data
}
}
isMember(
blockHash: "EVENT_BLOCK_HASH"
contractAddress: "MOBY_ADDRESS",
key0: "TWT:membername"
) {
value
proof {
data
}
}
}
```
The data is fetched from watcher database as it is already indexed.
## Additional Commands
To watch a contract, run:
```bash
yarn watch:contract --address <contract-address> --kind <contract-kind> --checkpoint <true | false> --starting-block [block-number]
```
where:
- `address`: Address or identifier of the contract to be watched.
- `kind`: Kind of the contract.
- `checkpoint`: Turn checkpointing on (`true` | `false`).
- `starting-block`: Starting block for the contract (default: `1`).
Examples:
Watch a contract with its address and checkpointing on:
```bash
yarn watch:contract --address 0x1F78641644feB8b64642e833cE4AFE93DD6e7833 --kind ERC20 --checkpoint true
```
```bash
sudo su - postgres
createdb mobymask-watcher
```
Watch a contract with its identifier and checkpointing on:
* If the watcher is an `active` watcher:
```bash
yarn watch:contract --address MyProtocol --kind protocol --checkpoint true
```
Create database for the job queue and enable the `pgcrypto` extension on them (https://github.com/timgit/pg-boss/blob/master/docs/usage.md#intro):
To fill a block range:
```
createdb mobymask-watcher-job-queue
```
```bash
yarn fill --start-block <from-block> --end-block <to-block>
```
```
postgres@tesla:~$ psql -U postgres -h localhost mobymask-watcher-job-queue
Password for user postgres:
psql (12.7 (Ubuntu 12.7-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
* `start-block`: Block number to start filling from.
* `end-block`: Block number till which to fill.
mobymask-watcher-job-queue=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION
mobymask-watcher-job-queue=# exit
```
To create a checkpoint for a contract:
* In the [config file](./environments/local.toml):
```bash
yarn checkpoint create --address <contract-address> --block-hash [block-hash]
```
* Update the database connection settings.
* `address`: Address or identifier of the contract for which to create a checkpoint.
* `block-hash`: Hash of a block (in the pruned region) at which to create the checkpoint (default: latest canonical block hash).
* Update the `upstream` config and provide the `ipld-eth-server` GQL API endpoint.
To reset the watcher to a previous block number:
* Update the `server` config with state checkpoint settings.
```bash
yarn reset watcher --block-number <previous-block-number>
```
## Customize
Reset job-queue:
* Indexing on an event:
```bash
yarn reset job-queue
```
* Edit the custom hook function `handleEvent` (triggered on an event) in [hooks.ts](./src/hooks.ts) to perform corresponding indexing using the `Indexer` object.
Reset state:
* While using the indexer storage methods for indexing, pass `diff` as true if default state is desired to be generated using the state variables being indexed.
```bash
yarn reset state --block-number <previous-block-number>
```
* Generating state:
* `block-number`: Block number to which to reset the watcher.
* Edit the custom hook function `createInitialState` (triggered if the watcher passes the start block, checkpoint: `true`) in [hooks.ts](./src/hooks.ts) to save an initial `State` using the `Indexer` object.
To export and import the watcher state:
* Edit the custom hook function `createStateDiff` (triggered on a block) in [hooks.ts](./src/hooks.ts) to save the state in a `diff` `State` using the `Indexer` object. The default state (if exists) is updated.
In the source watcher, export watcher state:
* Edit the custom hook function `createStateCheckpoint` (triggered just before default and CLI checkpoint) in [hooks.ts](./src/hooks.ts) to save the state in a `checkpoint` `State` using the `Indexer` object.
```bash
yarn export-state --export-file [export-file-path] --block-number [snapshot-block-height]
```
## Run
* `export-file`: Path of file to which to export the watcher data.
* `block-number`: Block height at which to take snapshot for export.
Follow the steps below or follow the [Demo](./demo.md)
In the target watcher, run job-runner:
* Run the server:
```bash
yarn job-runner
```
```bash
yarn server
```
Import watcher state:
GQL console: http://localhost:3010/graphql
```bash
yarn import-state --import-file <import-file-path>
```
* If the watcher is an `active` watcher:
* `import-file`: Path of file from which to import the watcher data.
* Run the job-runner:
Run server:
```bash
yarn job-runner
```
```bash
yarn server
```
* Run the server:
To inspect a CID:
```bash
yarn server
```
```bash
yarn inspect-cid --cid <cid>
```
GQL console: http://localhost:3010/graphql
* To watch a contract:
```bash
yarn watch:contract --address <contract-address> --kind <contract-kind> --checkpoint <true | false> --starting-block [block-number]
```
* `address`: Address or identifier of the contract to be watched.
* `kind`: Kind of the contract.
* `checkpoint`: Turn checkpointing on (`true` | `false`).
* `starting-block`: Starting block for the contract (default: `1`).
Examples:
Watch a contract with its address and checkpointing on:
```bash
yarn watch:contract --address 0x1F78641644feB8b64642e833cE4AFE93DD6e7833 --kind ERC20 --checkpoint true
```
Watch a contract with its identifier and checkpointing on:
```bash
yarn watch:contract --address MyProtocol --kind protocol --checkpoint true
```
* To fill a block range:
```bash
yarn fill --start-block <from-block> --end-block <to-block>
```
* `start-block`: Block number to start filling from.
* `end-block`: Block number till which to fill.
* To create a checkpoint for a contract:
```bash
yarn checkpoint create --address <contract-address> --block-hash [block-hash]
```
* `address`: Address or identifier of the contract for which to create a checkpoint.
* `block-hash`: Hash of a block (in the pruned region) at which to create the checkpoint (default: latest canonical block hash).
* To reset the watcher to a previous block number:
* Reset watcher:
```bash
yarn reset watcher --block-number <previous-block-number>
```
* Reset job-queue:
```bash
yarn reset job-queue
```
* Reset state:
```bash
yarn reset state --block-number <previous-block-number>
```
* `block-number`: Block number to which to reset the watcher.
* To export and import the watcher state:
* In source watcher, export watcher state:
```bash
yarn export-state --export-file [export-file-path] --block-number [snapshot-block-height]
```
* `export-file`: Path of file to which to export the watcher data.
* `block-number`: Block height at which to take snapshot for export.
* In target watcher, run job-runner:
```bash
yarn job-runner
```
* Import watcher state:
```bash
yarn import-state --import-file <import-file-path>
```
* `import-file`: Path of file from which to import the watcher data.
* Run server:
```bash
yarn server
```
* To inspect a CID:
```bash
yarn inspect-cid --cid <cid>
```
* `cid`: CID to be inspected.
* `cid`: CID to be inspected.

View File

@ -1,219 +0,0 @@
# Demo
* The following core services need to be running for the demo:
* [ipld-eth-db](https://github.com/cerc-io/ipld-eth-db)
* Version: [v4.2.3-alpha](https://github.com/cerc-io/ipld-eth-db/releases/tag/v4.2.3-alpha)
* [geth](https://github.com/cerc-io/go-ethereum)
* State diffing service should use `ipld-eth-db` for database.
* Version: [v1.10.26-statediff-4.2.2-alpha](https://github.com/cerc-io/go-ethereum/releases/tag/v1.10.26-statediff-4.2.2-alpha)
* Endpoint: http://127.0.0.1:8545
* [ipld-eth-server](https://github.com/cerc-io/ipld-eth-server)
* Should use `ipld-eth-db` for database.
* Version: [v4.2.3-alpha](https://github.com/cerc-io/ipld-eth-server/releases/tag/v4.2.3-alpha)
* Endpoints:
* GQL: http://127.0.0.1:8082/graphql
* RPC: http://127.0.0.1:8081
* Create a postgres12 database for the watcher:
```bash
sudo su - postgres
# If database already exists
# dropdb mobymask-watcher
createdb mobymask-watcher
```
* Create database for the job queue and enable the `pgcrypto` extension on them (https://github.com/timgit/pg-boss/blob/master/docs/usage.md#intro):
```bash
# If database already exists
# dropdb mobymask-watcher-job-queue
createdb mobymask-watcher-job-queue
```
```
postgres@tesla:~$ psql -U postgres -h localhost mobymask-watcher-job-queue
Password for user postgres:
psql (12.7 (Ubuntu 12.7-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.
mobymask-watcher-job-queue=# CREATE EXTENSION pgcrypto;
CREATE EXTENSION
mobymask-watcher-job-queue=# exit
```
* In the [config file](./environments/local.toml) update the `database` connection settings.
* In `watcher-ts` repo, follow the instructions in [Setup](../../README.md#setup) for installing and building packages.
```bash
# After setup
yarn && yarn build
```
* Run the job-runner:
```bash
yarn job-runner
```
* Change directory to `packages/mobymask-watcher/` and run the watcher:
```bash
yarn server
```
* Clone the [MobyMask](https://github.com/cerc-io/MobyMask) repo.
* Checkout to the branch with changes for using this watcher:
```bash
# In MobyMask repo.
git checkout use-laconic-watcher-as-hosted-index
```
* Run yarn to install the packages
```bash
yarn
```
* Deploy the contract:
```bash
cd packages/hardhat
yarn deploy
# deploying "PhisherRegistry" (tx: 0xaebeb2e883ece1f679304ec46f5dc61ca74f9e168427268a7dfa8802195b8de0)...: deployed at <MOBY_ADDRESS> with 2306221 gas
# $ hardhat run scripts/publish.js
# ✅ Published contracts to the subgraph package.
# Done in 14.28s.
```
Export the address of the deployed contract to a shell variable for later use:
```bash
export MOBY_ADDRESS="<MOBY_ADDRESS>"
```
* Run the following GQL mutation in watcher GraphQL endpoint http://127.0.0.1:3010/graphql
```graphql
mutation {
watchContract(
address: "MOBY_ADDRESS"
kind: "PhisherRegistry"
checkpoint: true
)
}
```
* Get the latest block
```graphql
query {
latestBlock {
hash
number
}
}
```
* Run the following GQL query in GraphQL endpoint
```graphql
query {
isPhisher(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "MOBY_ADDRESS"
key0: "TWT:phishername"
) {
value
proof {
data
}
}
isMember(
blockHash: "LATEST_BLOCK_HASH"
contractAddress: "MOBY_ADDRESS"
key0: "TWT:membername"
) {
value
proof {
data
}
}
}
```
* Run the following GQL subscription in generated watcher GraphQL endpoint:
```graphql
subscription {
onEvent {
event {
__typename
... on PhisherStatusUpdatedEvent {
entity
isPhisher
},
... on MemberStatusUpdatedEvent {
entity
isMember
}
},
block {
number
hash
}
}
}
```
* Update isPhiser and isMember lists with names
```bash
yarn claimPhisher --contract $MOBY_ADDRESS --name phisherName
```
```bash
yarn claimMember --contract $MOBY_ADDRESS --name memberName
```
* The events should be visible in the subscription at GQL endpoint. Note down the event blockHash from result.
* The isMember and isPhisher lists should be indexed. Check the database (mobymask-watcher) tables `is_phisher` and `is_member`, there should be entries at the event blockHash and the value should be true. The data is indexed in `handleEvent` method in the [hooks file](./src/hooks.ts).
* Update the the previous query with event blockHash and check isPhisher and isMember in GraphQL playground
```graphql
query {
isPhisher(
blockHash: "EVENT_BLOCK_HASH"
contractAddress: "MOBY_ADDRESS",
key0: "TWT:phishername"
) {
value
proof {
data
}
}
isMember(
blockHash: "EVENT_BLOCK_HASH"
contractAddress: "MOBY_ADDRESS",
key0: "TWT:membername"
) {
value
proof {
data
}
}
}
```
The data is fetched from watcher database as it is already indexed.