mirror of
https://github.com/cerc-io/watcher-ts
synced 2025-07-27 02:32:07 +00:00
Fetch transaction arguments for indexed event (#137)
This commit is contained in:
parent
26d998d3a7
commit
c919d784bf
@ -2,12 +2,6 @@
|
|||||||
|
|
||||||
* Clone the [stack-orchestrator](https://github.com/vulcanize/stack-orchestrator) repo.
|
* Clone the [stack-orchestrator](https://github.com/vulcanize/stack-orchestrator) repo.
|
||||||
|
|
||||||
* Checkout the `develop` branch in stack-orchestrator repo.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git checkout develop
|
|
||||||
```
|
|
||||||
|
|
||||||
* Create a `config.sh` file.
|
* Create a `config.sh` file.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@ -25,7 +19,7 @@
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# In go-ethereum repo.
|
# In go-ethereum repo.
|
||||||
git checkout v1.10.19-statediff-4.0.3-alpha
|
git checkout v1.10.19-statediff-4.0.4-alpha
|
||||||
```
|
```
|
||||||
|
|
||||||
* To run the stack-orchestrator, the docker-compose version used is:
|
* To run the stack-orchestrator, the docker-compose version used is:
|
||||||
@ -148,6 +142,44 @@
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* 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:
|
* Run the following GQL subscription in generated watcher GraphQL endpoint:
|
||||||
|
|
||||||
```graphql
|
```graphql
|
||||||
@ -182,45 +214,36 @@
|
|||||||
yarn claimMember --contract $MOBY_ADDRESS --name memberName
|
yarn claimMember --contract $MOBY_ADDRESS --name memberName
|
||||||
```
|
```
|
||||||
|
|
||||||
* The events should be visible in the subscription at GQL endpoint.
|
* The events should be visible in the subscription at GQL endpoint. Note down the event blockHash from result.
|
||||||
|
|
||||||
* Check the names in the watcher GraphQL playground http://localhost:3010/graphql
|
* The isMember and isPhisher lists should be indexed. Check the database (moby-mask-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).
|
||||||
|
|
||||||
* Get the latest block
|
* Update the the previous query with event blockHash and check isPhisher and isMember in GraphQL playground
|
||||||
|
|
||||||
```graphql
|
```graphql
|
||||||
query {
|
query {
|
||||||
latestBlock {
|
isPhisher(
|
||||||
hash
|
blockHash: "EVENT_BLOCK_HASH"
|
||||||
number
|
contractAddress: "MOBY_ADDRESS",
|
||||||
|
key0: "TWT:phishername"
|
||||||
|
) {
|
||||||
|
value
|
||||||
|
proof {
|
||||||
|
data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
isMember(
|
||||||
* Check the `isPhisher` and `isMember` maps
|
blockHash: "EVENT_BLOCK_HASH"
|
||||||
|
contractAddress: "MOBY_ADDRESS",
|
||||||
```graphql
|
key0: "TWT:membername"
|
||||||
query {
|
) {
|
||||||
isPhisher(
|
value
|
||||||
blockHash: "LATEST_BLOCK_HASH"
|
proof {
|
||||||
contractAddress: "MOBY_ADDRESS",
|
data
|
||||||
key0: "TWT:phishername"
|
|
||||||
) {
|
|
||||||
value
|
|
||||||
proof {
|
|
||||||
data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isMember(
|
|
||||||
blockHash: "LATEST_BLOCK_HASH"
|
|
||||||
contractAddress: "MOBY_ADDRESS",
|
|
||||||
key0: "TWT:membername"
|
|
||||||
) {
|
|
||||||
value
|
|
||||||
proof {
|
|
||||||
data
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The data is fetched from watcher database as it is already indexed.
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
|
import { utils } from 'ethers';
|
||||||
|
|
||||||
// import { updateStateForMappingType, updateStateForElementaryType } from '@vulcanize/util';
|
// import { updateStateForMappingType, updateStateForElementaryType } from '@vulcanize/util';
|
||||||
|
|
||||||
import { Indexer, ResultEvent } from './indexer';
|
import { Indexer, KIND_PHISHERREGISTRY, ResultEvent } from './indexer';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook function to store an initial state.
|
* Hook function to store an initial state.
|
||||||
@ -75,6 +76,34 @@ export async function handleEvent (indexer: Indexer, eventData: ResultEvent): Pr
|
|||||||
assert(indexer);
|
assert(indexer);
|
||||||
assert(eventData);
|
assert(eventData);
|
||||||
|
|
||||||
// Use indexer methods to index data.
|
// Perform indexing based on the type of event.
|
||||||
// Pass `diff` parameter to indexer methods as true to save an auto-generated state from the indexed data.
|
switch (eventData.event.__typename) {
|
||||||
|
// In case of PhisherRegistry 'PhisherStatusUpdated' event.
|
||||||
|
case 'PhisherStatusUpdatedEvent': {
|
||||||
|
const txArgs = await getTxArgs(indexer, KIND_PHISHERREGISTRY, eventData.tx.hash);
|
||||||
|
|
||||||
|
// Update isPhisher entry for the identifier in database.
|
||||||
|
await indexer.isPhisher(eventData.block.hash, eventData.contract, txArgs.identifier, true);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// In case of PhisherRegistry 'MemberStatusUpdated' event.
|
||||||
|
case 'MemberStatusUpdatedEvent': {
|
||||||
|
const txArgs = await getTxArgs(indexer, KIND_PHISHERREGISTRY, eventData.tx.hash);
|
||||||
|
|
||||||
|
// Update isPhisher entry for the identifier in database.
|
||||||
|
await indexer.isMember(eventData.block.hash, eventData.contract, txArgs.identifier, true);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get transaction arguments for specified txHash.
|
||||||
|
const getTxArgs = async (indexer: Indexer, contractKind: string, txHash: string): Promise<utils.Result> => {
|
||||||
|
const tx = await indexer.getFullTransaction(txHash);
|
||||||
|
const contractInterface = await indexer.getContractInterface(contractKind);
|
||||||
|
assert(contractInterface);
|
||||||
|
const txDescription = contractInterface.parseTransaction({ data: tx.input });
|
||||||
|
return txDescription.args;
|
||||||
|
};
|
||||||
|
@ -27,7 +27,8 @@ import {
|
|||||||
BlockHeight,
|
BlockHeight,
|
||||||
IPFSClient,
|
IPFSClient,
|
||||||
StateKind,
|
StateKind,
|
||||||
IpldStatus as IpldStatusInterface
|
IpldStatus as IpldStatusInterface,
|
||||||
|
getFullTransaction
|
||||||
} from '@vulcanize/util';
|
} from '@vulcanize/util';
|
||||||
import { GraphWatcher } from '@vulcanize/graph-node';
|
import { GraphWatcher } from '@vulcanize/graph-node';
|
||||||
|
|
||||||
@ -43,7 +44,7 @@ import { IPLDBlock } from './entity/IPLDBlock';
|
|||||||
|
|
||||||
const log = debug('vulcanize:indexer');
|
const log = debug('vulcanize:indexer');
|
||||||
|
|
||||||
const KIND_PHISHERREGISTRY = 'PhisherRegistry';
|
export const KIND_PHISHERREGISTRY = 'PhisherRegistry';
|
||||||
|
|
||||||
const DELEGATIONTRIGGERED_EVENT = 'DelegationTriggered';
|
const DELEGATIONTRIGGERED_EVENT = 'DelegationTriggered';
|
||||||
const MEMBERSTATUSUPDATED_EVENT = 'MemberStatusUpdated';
|
const MEMBERSTATUSUPDATED_EVENT = 'MemberStatusUpdated';
|
||||||
@ -797,6 +798,16 @@ export class Indexer implements IPLDIndexerInterface {
|
|||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get full transaction data.
|
||||||
|
async getFullTransaction (txHash: string): Promise<any> {
|
||||||
|
return getFullTransaction(this._ethClient, txHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get contract interface for specified contract kind.
|
||||||
|
async getContractInterface (kind: string): Promise<ethers.utils.Interface | undefined> {
|
||||||
|
return this._contractMap.get(kind);
|
||||||
|
}
|
||||||
|
|
||||||
getEntityTypesMap (): Map<string, { [key: string]: string }> {
|
getEntityTypesMap (): Map<string, { [key: string]: string }> {
|
||||||
return this._entityTypesMap;
|
return this._entityTypesMap;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user