Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add GQL API for transferCount entity #129

Merged
merged 1 commit into from
Jun 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions packages/erc721-watcher/demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@

* Custom property `transferCount` should be 1 initially.

* Run the getState query at the endpoint to get the latest IPLDBlock for NFT_ADDRESS:
* Run the `getState` query at the endpoint to get the latest IPLDBlock for NFT_ADDRESS:

```graphql
query {
Expand Down Expand Up @@ -190,7 +190,25 @@

* `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 `balanceOf` and `ownerOf` (`eth_call`):
* 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 {
Expand Down Expand Up @@ -239,19 +257,21 @@

* An auto-generated `diff_staged` IPLDBlock should be added with parent CID pointing to the previous IPLDBlock.

* Custom property `transferCount` should be incremented after transfer. This can be checked in the getState query and in IPFS webUI mentioned in the later steps.
* Custom property `transferCount` should be incremented after transfer. This can be checked in the `getState` query and in IPFS webUI mentioned in the later steps.

* 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.

* Get the latest blockHash and replace the blockHash in the above 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 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 --address $NFT_ADDRESS
```

* Run the getState query again with the output blockHash and kind checkpoint at the endpoint.
* 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.

Expand Down
8 changes: 6 additions & 2 deletions packages/erc721-watcher/src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//

import assert from 'assert';
import { Connection, ConnectionOptions, DeepPartial, FindConditions, QueryRunner, FindManyOptions, FindOneOptions } from 'typeorm';
import { Connection, ConnectionOptions, DeepPartial, FindConditions, QueryRunner, FindManyOptions, FindOneOptions, LessThanOrEqual } from 'typeorm';
import path from 'path';

import { IPLDDatabase as BaseDatabase, IPLDDatabaseInterface, QueryOptions, StateKind, Where } from '@vulcanize/util';
Expand Down Expand Up @@ -129,14 +129,18 @@ export class Database implements IPLDDatabaseInterface {
});
}

async getTransferCount (queryRunner: QueryRunner, { id, blockHash }: DeepPartial<TransferCount>): Promise<TransferCount | undefined> {
async getTransferCount (queryRunner: QueryRunner, { id, blockHash, blockNumber }: DeepPartial<TransferCount>): Promise<TransferCount | undefined> {
const repo = queryRunner.manager.getRepository(TransferCount);
const whereOptions: FindConditions<TransferCount> = { id };

if (blockHash) {
whereOptions.blockHash = blockHash;
}

if (blockNumber) {
whereOptions.blockNumber = LessThanOrEqual(blockNumber);
}

const findOptions = {
where: whereOptions,
order: {
Expand Down
7 changes: 4 additions & 3 deletions packages/erc721-watcher/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,17 @@ export async function handleEvent (indexer: Indexer, eventData: ResultEvent): Pr
// "transferCount": "1"
// }
// Fetch transferCount entity from database.
let transferCount = await indexer.transferCount(eventData.block.hash, eventData.contract);
let transferCount = await indexer.getTransferCount(eventData.contract, eventData.block);

if (!transferCount) {
transferCount = new TransferCount();
transferCount.blockHash = eventData.block.hash;
transferCount.blockNumber = eventData.block.number;
transferCount.id = eventData.contract;
transferCount.count = 0;
}

transferCount.blockHash = eventData.block.hash;
transferCount.blockNumber = eventData.block.number;

// Increment count on transfer event.
transferCount.count++;

Expand Down
4 changes: 2 additions & 2 deletions packages/erc721-watcher/src/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,12 +431,12 @@ export class Indexer implements IPLDIndexerInterface {
return result;
}

async transferCount (blockHash: string, contractAddress: string): Promise<TransferCount | undefined> {
async getTransferCount (id: string, block: BlockHeight): Promise<TransferCount | undefined> {
const dbTx = await this._db.createTransactionRunner();
let res;

try {
res = await this._db.getTransferCount(dbTx, { id: contractAddress, blockHash });
res = await this._db.getTransferCount(dbTx, { id, blockHash: block.hash, blockNumber: block.number });
await dbTx.commitTransaction();
} catch (error) {
await dbTx.rollbackTransaction();
Expand Down
7 changes: 7 additions & 0 deletions packages/erc721-watcher/src/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ValueResult, BlockHeight, StateKind } from '@vulcanize/util';

import { Indexer } from './indexer';
import { EventWatcher } from './events';
import { TransferCount } from './entity/TransferCount';

const log = debug('vulcanize:resolver');

Expand Down Expand Up @@ -128,6 +129,12 @@ export const createResolvers = async (indexer: Indexer, eventWatcher: EventWatch
return indexer._operatorApprovals(blockHash, contractAddress, key0, key1);
},

transferCount: async (_: any, { id, block = {} }: { id: string, block: BlockHeight }) => {
log('transferCount', id, block);

return indexer.getTransferCount(id, block);
},

events: async (_: any, { blockHash, contractAddress, name }: { blockHash: string, contractAddress: string, name?: string }) => {
log('events', blockHash, contractAddress, name);

Expand Down
11 changes: 11 additions & 0 deletions packages/erc721-watcher/src/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ scalar BigDecimal

scalar Bytes

input Block_height {
hash: Bytes
number: Int
}

type Proof {
data: String!
}
Expand Down Expand Up @@ -99,6 +104,12 @@ type Query {
_operatorApprovals(blockHash: String!, contractAddress: String!, key0: String!, key1: String!): ResultBoolean!
getStateByCID(cid: String!): ResultIPLDBlock
getState(blockHash: String!, contractAddress: String!, kind: String): ResultIPLDBlock
transferCount(id: String!, block: Block_height): TransferCount!
}

type TransferCount {
id: ID!
count: Int!
}

type Mutation {
Expand Down