mirror of
https://github.com/cerc-io/watcher-ts
synced 2025-01-06 19:38:05 +00:00
Add demo for erc721-watcher
This commit is contained in:
parent
99aaa9ae0a
commit
baa20de443
3
packages/erc721-watcher/.gitignore
vendored
Normal file
3
packages/erc721-watcher/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
#Hardhat files
|
||||
cache
|
||||
artifacts
|
@ -8,12 +8,6 @@
|
||||
yarn
|
||||
```
|
||||
|
||||
* Run the IPFS (go-ipfs version 0.12.2) daemon:
|
||||
|
||||
```bash
|
||||
ipfs daemon
|
||||
```
|
||||
|
||||
* Create a postgres12 database for the watcher:
|
||||
|
||||
```bash
|
||||
@ -41,13 +35,169 @@
|
||||
erc721-watcher-job-queue=# exit
|
||||
```
|
||||
|
||||
* The following core services should be setup and running on localhost:
|
||||
|
||||
* `vulcanize/go-ethereum` [v1.10.18-statediff-3.2.2](https://github.com/vulcanize/go-ethereum/releases/tag/v1.10.18-statediff-3.2.2) on port 8545
|
||||
|
||||
* `vulcanize/ipld-eth-server` [v3.2.2](https://github.com/vulcanize/ipld-eth-server/releases/tag/v3.2.2) 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 and provide the IPFS API address.
|
||||
## Demo
|
||||
|
||||
* 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>"
|
||||
```
|
||||
|
||||
* Open `http://localhost:3006/graphql` (GraphQL Playground) in a browser window
|
||||
|
||||
* Connect MetaMask to `http://localhost:8545` (with chain ID `41337`)
|
||||
|
||||
* 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: "0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc"
|
||||
) {
|
||||
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: "0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc"
|
||||
) {
|
||||
value
|
||||
proof {
|
||||
data
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* Mint token
|
||||
|
||||
```bash
|
||||
yarn nft:mint --nft $NFT_ADDRESS --to 0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc --token-id 1
|
||||
```
|
||||
|
||||
* Get the latest blockHash and run the following query for `balanceOf` and `ownerOf` (`eth_call`):
|
||||
|
||||
```graphql
|
||||
query {
|
||||
fromBalanceOf: balanceOf(
|
||||
blockHash: "LATEST_BLOCK_HASH"
|
||||
contractAddress: "NFT_ADDRESS"
|
||||
owner: "0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc"
|
||||
) {
|
||||
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 0xDC7d7A8920C8Eecc098da5B7522a5F31509b5Bfc --to $RECIPIENT_ADDRESS --token-id 1
|
||||
```
|
||||
|
||||
* 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.
|
||||
|
||||
## Customize
|
||||
|
||||
@ -99,7 +249,7 @@ GQL console: http://localhost:3006/graphql
|
||||
Watch a contract with its address and checkpointing on:
|
||||
|
||||
```bash
|
||||
yarn watch:contract --address 0x1F78641644feB8b64642e833cE4AFE93DD6e7833 --kind ERC20 --checkpoint true
|
||||
yarn watch:contract --address 0x1F78641644feB8b64642e833cE4AFE93DD6e7833 --kind ERC721 --checkpoint true
|
||||
```
|
||||
|
||||
Watch a contract with its identifier and checkpointing on:
|
||||
|
28
packages/erc721-watcher/hardhat.config.ts
Normal file
28
packages/erc721-watcher/hardhat.config.ts
Normal file
@ -0,0 +1,28 @@
|
||||
//
|
||||
// Copyright 2022 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import '@nomiclabs/hardhat-waffle';
|
||||
|
||||
import './test/tasks/nft-deploy';
|
||||
import './test/tasks/nft-mint';
|
||||
import './test/tasks/nft-transfer';
|
||||
import './test/tasks/block-latest';
|
||||
|
||||
// You need to export an object to set up your config
|
||||
// Go to https://hardhat.org/config/ to learn more
|
||||
|
||||
/**
|
||||
* @type import('hardhat/config').HardhatUserConfig
|
||||
*/
|
||||
export default {
|
||||
solidity: '0.8.0',
|
||||
networks: {
|
||||
docker: {
|
||||
url: 'http://geth:8545'
|
||||
}
|
||||
},
|
||||
paths: {
|
||||
sources: './test/contracts'
|
||||
}
|
||||
};
|
@ -15,7 +15,11 @@
|
||||
"checkpoint": "DEBUG=vulcanize:* ts-node src/cli/checkpoint.ts",
|
||||
"export-state": "DEBUG=vulcanize:* ts-node src/cli/export-state.ts",
|
||||
"import-state": "DEBUG=vulcanize:* ts-node src/cli/import-state.ts",
|
||||
"inspect-cid": "DEBUG=vulcanize:* ts-node src/cli/inspect-cid.ts"
|
||||
"inspect-cid": "DEBUG=vulcanize:* ts-node src/cli/inspect-cid.ts",
|
||||
"nft:deploy": "hardhat --network localhost nft-deploy",
|
||||
"nft:mint": "hardhat --network localhost nft-mint",
|
||||
"nft:transfer": "hardhat --network localhost nft-transfer",
|
||||
"block:latest": "hardhat --network localhost block-latest"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -50,6 +54,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ethersproject/abi": "^5.3.0",
|
||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
||||
"@types/express": "^4.17.11",
|
||||
"@types/yargs": "^17.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.25.0",
|
||||
@ -62,6 +68,7 @@
|
||||
"eslint-plugin-promise": "^5.1.0",
|
||||
"eslint-plugin-standard": "^5.0.0",
|
||||
"ts-node": "^10.0.0",
|
||||
"typescript": "^4.3.2"
|
||||
"typescript": "^4.3.2",
|
||||
"hardhat": "^2.3.0"
|
||||
}
|
||||
}
|
||||
|
@ -132,10 +132,8 @@ export class Indexer implements IPLDIndexerInterface {
|
||||
this._contractMap.set(KIND_ERC721, new ethers.utils.Interface(ERC721ABI));
|
||||
|
||||
this._entityTypesMap = new Map();
|
||||
this._populateEntityTypesMap();
|
||||
|
||||
this._relationsMap = new Map();
|
||||
this._populateRelationsMap();
|
||||
}
|
||||
|
||||
async init (): Promise<void> {
|
||||
|
@ -1,3 +0,0 @@
|
||||
//
|
||||
// Copyright 2021 Vulcanize, Inc.
|
||||
//
|
13
packages/erc721-watcher/test/contracts/TestNFT.sol
Normal file
13
packages/erc721-watcher/test/contracts/TestNFT.sol
Normal file
@ -0,0 +1,13 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
|
||||
|
||||
contract TestNFT is ERC721 {
|
||||
constructor() ERC721("TestNFT", "TNFT") {
|
||||
}
|
||||
|
||||
function mint(address to, uint256 tokenId) public {
|
||||
_safeMint(to, tokenId);
|
||||
}
|
||||
}
|
18
packages/erc721-watcher/test/tasks/block-latest.ts
Normal file
18
packages/erc721-watcher/test/tasks/block-latest.ts
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// Copyright 2022 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { task } from 'hardhat/config';
|
||||
import '@nomiclabs/hardhat-ethers';
|
||||
|
||||
task(
|
||||
'block-latest',
|
||||
'Prints the current block info',
|
||||
async (_, { ethers }) => {
|
||||
const blockNumber = await ethers.provider.getBlockNumber();
|
||||
const block = await ethers.provider.getBlock(blockNumber);
|
||||
|
||||
console.log('Block Number:', blockNumber);
|
||||
console.log('Block Hash:', block.hash);
|
||||
}
|
||||
);
|
15
packages/erc721-watcher/test/tasks/nft-deploy.ts
Normal file
15
packages/erc721-watcher/test/tasks/nft-deploy.ts
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// Copyright 2022 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { task } from 'hardhat/config';
|
||||
import '@nomiclabs/hardhat-ethers';
|
||||
|
||||
task('nft-deploy', 'Deploys NFT')
|
||||
.setAction(async (args, hre) => {
|
||||
await hre.run('compile');
|
||||
const NFT = await hre.ethers.getContractFactory('TestNFT');
|
||||
const nft = await NFT.deploy();
|
||||
|
||||
console.log('NFT deployed to:', nft.address);
|
||||
});
|
33
packages/erc721-watcher/test/tasks/nft-mint.ts
Normal file
33
packages/erc721-watcher/test/tasks/nft-mint.ts
Normal file
@ -0,0 +1,33 @@
|
||||
//
|
||||
// Copyright 2022 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { task, types } from 'hardhat/config';
|
||||
import '@nomiclabs/hardhat-ethers';
|
||||
import { ContractTransaction } from 'ethers';
|
||||
|
||||
task('nft-mint', 'Mint NFT')
|
||||
.addParam('nft', 'Contract address', undefined, types.string)
|
||||
.addParam('tokenId', 'Token ID', undefined, types.string)
|
||||
.addParam('to', 'Transfer recipient address', undefined, types.string)
|
||||
.setAction(async (args, hre) => {
|
||||
const { tokenId, to, nft: contractAddress } = args;
|
||||
await hre.run('compile');
|
||||
const NFT = await hre.ethers.getContractFactory('TestNFT');
|
||||
const nft = NFT.attach(contractAddress);
|
||||
|
||||
const transaction: ContractTransaction = await nft.mint(to, tokenId);
|
||||
|
||||
const receipt = await transaction.wait();
|
||||
|
||||
if (receipt.events) {
|
||||
const TransferEvent = receipt.events.find(el => el.event === 'Transfer');
|
||||
|
||||
if (TransferEvent && TransferEvent.args) {
|
||||
console.log('Transfer Event');
|
||||
console.log('from:', TransferEvent.args.from.toString());
|
||||
console.log('to:', TransferEvent.args.to.toString());
|
||||
console.log('tokenId:', TransferEvent.args.tokenId.toString());
|
||||
}
|
||||
}
|
||||
});
|
34
packages/erc721-watcher/test/tasks/nft-transfer.ts
Normal file
34
packages/erc721-watcher/test/tasks/nft-transfer.ts
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// Copyright 2022 Vulcanize, Inc.
|
||||
//
|
||||
|
||||
import { task, types } from 'hardhat/config';
|
||||
import '@nomiclabs/hardhat-ethers';
|
||||
import { ContractTransaction } from 'ethers';
|
||||
|
||||
task('nft-transfer', 'Move tokens to recipient')
|
||||
.addParam('nft', 'Contract address', undefined, types.string)
|
||||
.addParam('from', 'Transfer from address', undefined, types.string)
|
||||
.addParam('to', 'Transfer recipient address', undefined, types.string)
|
||||
.addParam('tokenId', 'Token ID to transfer', undefined, types.string)
|
||||
.setAction(async (args, hre) => {
|
||||
const { nft: contractAddress, from, to, tokenId } = args;
|
||||
await hre.run('compile');
|
||||
const NFT = await hre.ethers.getContractFactory('TestNFT');
|
||||
const nft = NFT.attach(contractAddress);
|
||||
|
||||
const transaction: ContractTransaction = await nft['safeTransferFrom(address,address,uint256)'](from, to, tokenId);
|
||||
|
||||
const receipt = await transaction.wait();
|
||||
|
||||
if (receipt.events) {
|
||||
const TransferEvent = receipt.events.find(el => el.event === 'Transfer');
|
||||
|
||||
if (TransferEvent && TransferEvent.args) {
|
||||
console.log('Transfer Event');
|
||||
console.log('from:', TransferEvent.args.from.toString());
|
||||
console.log('to:', TransferEvent.args.to.toString());
|
||||
console.log('tokenId:', TransferEvent.args.tokenId.toString());
|
||||
}
|
||||
}
|
||||
});
|
Loading…
Reference in New Issue
Block a user