feat: subgraph updated handlers (#235)

* feat: add verifier when contract is initialized

* feat: initialize git repository on new mint

* feat: add created at in token entity

* feat: add created at in ap entity

* feat: handle verifier role grant and revoke

* feat: add verified field to token

* refactor: create constants file

* feat: add total tokens counter on collection entity

* refactor: verify verifier address for mint event

* refactor: remove collection id
This commit is contained in:
Felipe Mendes 2023-04-28 12:22:51 -03:00 committed by GitHub
parent f685d6800b
commit a20ec8bb22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 123 additions and 68 deletions

View File

@ -31,7 +31,7 @@ type NewMint @entity(immutable: true) {
color: Int!
accessPointAutoApproval: Boolean!
triggeredBy: Bytes! # address
owner: Owner! # address
owner: Owner! # address
verifier: Bytes!
blockNumber: BigInt!
blockTimestamp: BigInt!
@ -79,7 +79,9 @@ type Token @entity {
gitRepository: GitRepository!
commitHash: String!
accessPoints: [AccessPoint!] @derivedFrom(field: "token")
verifier: Verifier! # Address
verifier: Verifier # Address
verified: Boolean!
createdAt: BigInt!
}
# Owner entity for collection, access points, and tokens
@ -115,4 +117,10 @@ type AccessPoint @entity {
nameVerified: Boolean!
owner: Owner!
creationStatus: String!
}
createdAt: BigInt!
}
type Collection @entity {
id: Bytes!
totalTokens: BigInt!
}

View File

@ -1,4 +1,4 @@
import { Bytes, log } from '@graphprotocol/graph-ts';
import { Bytes, log, store } from '@graphprotocol/graph-ts';
// Event Imports [based on the yaml config]
import {
@ -7,15 +7,8 @@ import {
} from '../generated/FleekNFA/FleekNFA';
// Entity Imports [based on the schema]
import { Owner, Token } from '../generated/schema';
enum CollectionRoles {
Owner,
}
enum TokenRoles {
Controller,
}
import { Owner, Token, Verifier } from '../generated/schema';
import { CollectionRoles, TokenRoles } from './constants';
export function handleCollectionRoleChanged(
event: CollectionRoleChangedEvent
@ -25,35 +18,56 @@ export function handleCollectionRoleChanged(
const role = event.params.role;
const status = event.params.status;
if (role === CollectionRoles.Owner) {
// Owner role
if (status) {
// granted
let owner = Owner.load(toAddress);
if (!owner) {
owner = new Owner(toAddress);
switch (role) {
case CollectionRoles.Owner:
// Owner role
if (status) {
// granted
let owner = Owner.load(toAddress);
if (!owner) {
owner = new Owner(toAddress);
}
owner.collection = true;
owner.save();
} else {
// revoked
const owner = Owner.load(toAddress);
if (!owner) {
log.error(
'Owner entity not found. Role: {}, byAddress: {}, toAddress: {}',
[role.toString(), byAddress.toHexString(), toAddress.toHexString()]
);
return;
}
owner.collection = false;
owner.save();
}
owner.collection = true;
owner.save();
} else {
// revoked
const owner = Owner.load(toAddress);
if (!owner) {
log.error(
'Owner entity not found. Role: {}, byAddress: {}, toAddress: {}',
[role.toString(), byAddress.toHexString(), toAddress.toHexString()]
);
return;
break;
case CollectionRoles.Verifier:
// Verifier role
if (status) {
// granted
let verifier = Verifier.load(toAddress);
if (!verifier) {
verifier = new Verifier(toAddress);
}
verifier.save();
} else {
// revoked
const verifier = Verifier.load(toAddress);
if (verifier) {
store.remove('Verifier', verifier.id.toString());
}
}
owner.collection = false;
owner.save();
}
} else {
log.error('Role not supported. Role: {}, byAddress: {}, toAddress: {}', [
role.toString(),
byAddress.toHexString(),
toAddress.toHexString(),
]);
break;
default:
log.error('Role not supported. Role: {}, byAddress: {}, toAddress: {}', [
role.toString(),
byAddress.toHexString(),
toAddress.toHexString(),
]);
}
}

View File

@ -29,6 +29,7 @@ export function handleNewAccessPoint(event: NewAccessPointEvent): void {
accessPointEntity.token = Bytes.fromByteArray(
Bytes.fromBigInt(event.params.tokenId)
);
accessPointEntity.createdAt = event.block.timestamp;
// Load / Create an Owner entity
let ownerEntity = Owner.load(event.params.owner);

View File

@ -0,0 +1,8 @@
export enum CollectionRoles {
Owner,
Verifier,
}
export enum TokenRoles {
Controller,
}

View File

@ -1,10 +1,10 @@
import { log, ethereum } from '@graphprotocol/graph-ts';
import { log, ethereum, BigInt } from '@graphprotocol/graph-ts';
// Event Imports [based on the yaml config]
import { Initialized as InitializedEvent } from '../generated/FleekNFA/FleekNFA';
// Entity Imports [based on the schema]
import { Owner } from '../generated/schema';
import { Collection, Owner, Verifier } from '../generated/schema';
export function handleInitialized(event: InitializedEvent): void {
// This is the contract creation transaction.
log.warning('This is the contract creation transaction.', []);
@ -14,9 +14,18 @@ export function handleInitialized(event: InitializedEvent): void {
receipt.contractAddress.toHexString(),
]);
// start collection entity
const collection = new Collection(event.address.toHexString());
collection.totalTokens = BigInt.fromU32(0);
collection.save();
// add owner
const owner = new Owner(event.transaction.from);
owner.collection = true;
owner.save();
// add verifier
const verifier = new Verifier(event.transaction.from);
verifier.save();
}
}

View File

@ -2,7 +2,6 @@ import { Bytes } from '@graphprotocol/graph-ts';
// Event Imports [based on the yaml config]
import {
MetadataUpdate as MetadataUpdateEvent,
MetadataUpdate1 as MetadataUpdateEvent1,
MetadataUpdate2 as MetadataUpdateEvent2,
MetadataUpdate3 as MetadataUpdateEvent3,
@ -159,6 +158,9 @@ export function handleMetadataUpdateWithBooleanValue(
if (event.params.key == 'accessPointAutoApproval') {
token.accessPointAutoApproval = event.params.value;
}
if (event.params.key == 'verified') {
token.verified = event.params.value;
}
token.save();
}
}

View File

@ -1,10 +1,17 @@
import { Bytes, log } from '@graphprotocol/graph-ts';
import { BigInt, Bytes, log } from '@graphprotocol/graph-ts';
// Event Imports [based on the yaml config]
import { NewMint as NewMintEvent } from '../generated/FleekNFA/FleekNFA';
// Entity Imports [based on the schema]
import { Owner, NewMint, Token } from '../generated/schema';
import {
Owner,
NewMint,
Token,
GitRepository,
Collection,
Verifier,
} from '../generated/schema';
export function handleNewMint(event: NewMintEvent): void {
const newMintEntity = new NewMint(
@ -67,14 +74,41 @@ export function handleNewMint(event: NewMintEvent): void {
token.color = color;
token.accessPointAutoApproval = accessPointAutoApproval;
token.owner = ownerAddress;
token.verifier = verifierAddress;
token.verified = false;
token.mintTransaction = event.transaction.hash.concatI32(
event.logIndex.toI32()
);
token.mintedBy = event.params.minter;
token.controllers = [ownerAddress];
token.createdAt = event.block.timestamp;
if (Verifier.load(verifierAddress)) {
token.verifier = verifierAddress;
}
// Populate GitRepository entity
let repository = GitRepository.load(gitRepository);
if (!repository) {
repository = new GitRepository(gitRepository);
}
let repositoryTokens = repository.tokens;
if (repositoryTokens === null) {
repositoryTokens = [token.id];
} else {
repositoryTokens.push(token.id);
}
repository.tokens = repositoryTokens;
// Increase total tokens counter
const collection = Collection.load(event.address.toHexString());
if (collection) {
collection.totalTokens = collection.totalTokens.plus(BigInt.fromU32(1));
collection.save();
}
// Save entities
owner.save();
token.save();
repository.save();
}

View File

@ -256,13 +256,6 @@
dependencies:
assemblyscript "0.19.10"
"@graphprotocol/graph-ts@^0.27.0":
version "0.27.0"
resolved "https://registry.yarnpkg.com/@graphprotocol/graph-ts/-/graph-ts-0.27.0.tgz#948fe1716f6082964a01a63a19bcbf9ac44e06ff"
integrity sha512-r1SPDIZVQiGMxcY8rhFSM0y7d/xAbQf5vHMWUf59js1KgoyWpM6P3tczZqmQd7JTmeyNsDGIPzd9FeaxllsU4w==
dependencies:
assemblyscript "0.19.10"
"@rescript/std@9.0.0":
version "9.0.0"
resolved "https://registry.yarnpkg.com/@rescript/std/-/std-9.0.0.tgz#df53f3fa5911cb4e85bd66b92e9e58ddf3e4a7e1"
@ -496,7 +489,7 @@ assemblyscript@0.19.10:
binaryen "101.0.0-nightly.20210723"
long "^4.0.0"
assemblyscript@0.19.23, assemblyscript@^0.19.20:
assemblyscript@0.19.23:
version "0.19.23"
resolved "https://registry.yarnpkg.com/assemblyscript/-/assemblyscript-0.19.23.tgz#16ece69f7f302161e2e736a0f6a474e6db72134c"
integrity sha512-fwOQNZVTMga5KRsfY80g7cpOl4PsFQczMwHzdtgoqLXaYhkhavufKb0sB0l3T1DUxpAufA0KNhlbpuuhZUwxMA==
@ -2227,15 +2220,6 @@ mafmt@^7.0.0:
dependencies:
multiaddr "^7.3.0"
matchstick-as@0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/matchstick-as/-/matchstick-as-0.5.0.tgz#cdafc1ef49d670b9cbe98e933bc2a5cb7c450aeb"
integrity sha512-4K619YDH+so129qt4RB4JCNxaFwJJYLXPc7drpG+/mIj86Cfzg6FKs/bA91cnajmS1CLHdhHl9vt6Kd6Oqvfkg==
dependencies:
"@graphprotocol/graph-ts" "^0.27.0"
assemblyscript "^0.19.20"
wabt "1.0.24"
md5.js@^1.3.4:
version "1.3.5"
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
@ -3399,11 +3383,6 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
wabt@1.0.24:
version "1.0.24"
resolved "https://registry.yarnpkg.com/wabt/-/wabt-1.0.24.tgz#c02e0b5b4503b94feaf4a30a426ef01c1bea7c6c"
integrity sha512-8l7sIOd3i5GWfTWciPL0+ff/FK/deVK2Q6FN+MPz4vfUcD78i2M/49XJTwF6aml91uIiuXJEsLKWMB2cw/mtKg==
wcwidth@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"