feat: updating subgraph following the ACL refactor (#144)
* refactor: remove unavailable imports, remove outdated entities, add command to regenerate the compile and codegen. * feat: add handler for initialized, tokenrolechanged and collectionrolechanged. * refactor: remove the collection entity. * refactor: implement zoruka's requested changes - best practice recommendations.
This commit is contained in:
parent
7971ae8cc7
commit
c8a63b8618
|
|
@ -31,7 +31,7 @@ type NewMint @entity(immutable: true) {
|
|||
color: Int!
|
||||
accessPointAutoApproval: Boolean!
|
||||
triggeredBy: Bytes! # address
|
||||
tokenOwner: Owner! # address
|
||||
owner: Owner! # address
|
||||
blockNumber: BigInt!
|
||||
blockTimestamp: BigInt!
|
||||
transactionHash: Bytes!
|
||||
|
|
@ -80,28 +80,19 @@ type Token @entity {
|
|||
accessPoints: [AccessPoint!] @derivedFrom(field: "token")
|
||||
}
|
||||
|
||||
# Owner entity for collection, access points, and tokens
|
||||
type Owner @entity {
|
||||
id: Bytes! # address
|
||||
tokens: [Token!] @derivedFrom(field: "owner")
|
||||
accessPoints: [AccessPoint!] @derivedFrom(field: "owner")
|
||||
collection: Boolean!
|
||||
}
|
||||
|
||||
# Controller entity for tokens
|
||||
type Controller @entity {
|
||||
id: Bytes! # address
|
||||
tokens: [Token!] @derivedFrom(field: "controllers")
|
||||
}
|
||||
type Collection @entity {
|
||||
id: Bytes! #address
|
||||
deployer: Bytes! #address
|
||||
transactionHash: Bytes! #transaction hash
|
||||
owners: [CollectionOwner!]
|
||||
}
|
||||
|
||||
type CollectionOwner @entity {
|
||||
id: Bytes! # address
|
||||
accessGrantedBy: Bytes! #address
|
||||
transactionHash: Bytes!
|
||||
}
|
||||
|
||||
type GitRepository @entity {
|
||||
id: String! # transaction hash of the first transaction this repository appeared in
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
import { Address, Bytes, log, store, ethereum, BigInt } from '@graphprotocol/graph-ts';
|
||||
|
||||
// Event Imports [based on the yaml config]
|
||||
import {
|
||||
Approval as ApprovalEvent,
|
||||
ApprovalForAll as ApprovalForAllEvent,
|
||||
MetadataUpdate as MetadataUpdateEvent,
|
||||
MetadataUpdate1 as MetadataUpdateEvent1,
|
||||
MetadataUpdate2 as MetadataUpdateEvent2,
|
||||
TokenRoleChanged as TokenRoleChangedEvent,
|
||||
MetadataUpdate3 as MetadataUpdateEvent3,
|
||||
CollectionRoleChanged as CollectionRoleChangedEvent,
|
||||
Initialized as InitializedEvent,
|
||||
Transfer as TransferEvent,
|
||||
NewMint as NewMintEvent,
|
||||
ChangeAccessPointCreationStatus as ChangeAccessPointCreationStatusEvent,
|
||||
|
|
@ -14,21 +19,28 @@ import {
|
|||
ChangeAccessPointNameVerify as ChangeAccessPointNameVerifyEvent,
|
||||
ChangeAccessPointContentVerify as ChangeAccessPointContentVerifyEvent,
|
||||
} from '../generated/FleekNFA/FleekNFA';
|
||||
|
||||
// Entity Imports [based on the schema]
|
||||
import {
|
||||
AccessPoint,
|
||||
Approval,
|
||||
ApprovalForAll,
|
||||
Collection,
|
||||
CollectionOwner,
|
||||
Controller,
|
||||
Owner,
|
||||
GitRepository as GitRepositoryEntity,
|
||||
MetadataUpdate,
|
||||
NewMint,
|
||||
Owner,
|
||||
Token,
|
||||
Transfer,
|
||||
} from '../generated/schema';
|
||||
|
||||
enum CollectionRoles {
|
||||
Owner,
|
||||
};
|
||||
|
||||
enum TokenRoles {
|
||||
Controller,
|
||||
};
|
||||
|
||||
export function handleApproval(event: ApprovalEvent): void {
|
||||
let entity = new Approval(
|
||||
event.transaction.hash.concatI32(event.logIndex.toI32())
|
||||
|
|
@ -87,7 +99,7 @@ export function handleNewMint(event: NewMintEvent): void {
|
|||
newMintEntity.color = color;
|
||||
newMintEntity.accessPointAutoApproval = accessPointAutoApproval;
|
||||
newMintEntity.triggeredBy = event.params.minter;
|
||||
newMintEntity.tokenOwner = ownerAddress;
|
||||
newMintEntity.owner = ownerAddress;
|
||||
newMintEntity.blockNumber = event.block.number;
|
||||
newMintEntity.blockTimestamp = event.block.timestamp;
|
||||
newMintEntity.transactionHash = event.transaction.hash;
|
||||
|
|
@ -97,7 +109,6 @@ export function handleNewMint(event: NewMintEvent): void {
|
|||
// Create Token, Owner, and Controller entities
|
||||
|
||||
let owner = Owner.load(ownerAddress);
|
||||
let controller = Controller.load(ownerAddress);
|
||||
let gitRepositoryEntity = GitRepositoryEntity.load(gitRepository);
|
||||
let token = new Token(Bytes.fromByteArray(Bytes.fromBigInt(tokenId)));
|
||||
|
||||
|
|
@ -106,11 +117,6 @@ export function handleNewMint(event: NewMintEvent): void {
|
|||
owner = new Owner(ownerAddress);
|
||||
}
|
||||
|
||||
if (!controller) {
|
||||
// Create a new controller entity
|
||||
controller = new Controller(ownerAddress);
|
||||
}
|
||||
|
||||
if (!gitRepositoryEntity) {
|
||||
// Create a new gitRepository entity
|
||||
gitRepositoryEntity = new GitRepositoryEntity(gitRepository);
|
||||
|
|
@ -136,7 +142,6 @@ export function handleNewMint(event: NewMintEvent): void {
|
|||
|
||||
// Save entities
|
||||
owner.save();
|
||||
controller.save();
|
||||
gitRepositoryEntity.save();
|
||||
token.save();
|
||||
}
|
||||
|
|
@ -257,6 +262,91 @@ export function handleMetadataUpdateWithIntValue(
|
|||
}
|
||||
}
|
||||
|
||||
export function handleInitialized(event: InitializedEvent): void {
|
||||
// This is the contract creation transaction.
|
||||
log.warning('This is the contract creation transaction.', []);
|
||||
if (event.receipt) {
|
||||
let receipt = event.receipt as ethereum.TransactionReceipt;
|
||||
log.warning('Contract address is: {}', [
|
||||
receipt.contractAddress.toHexString(),
|
||||
]);
|
||||
|
||||
// add owner
|
||||
let owner = new Owner(event.transaction.from);
|
||||
owner.collection = true;
|
||||
owner.save();
|
||||
}
|
||||
}
|
||||
|
||||
export function handleCollectionRoleChanged(event: CollectionRoleChangedEvent): void {
|
||||
let toAddress = event.params.toAddress;
|
||||
let byAddress = event.params.byAddress;
|
||||
let role = event.params.role;
|
||||
let status = event.params.status;
|
||||
|
||||
if (role === 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
|
||||
let 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();
|
||||
}
|
||||
} else {
|
||||
log.error('Role not supported. Role: {}, byAddress: {}, toAddress: {}', [role.toString(), byAddress.toHexString(), toAddress.toHexString()]);
|
||||
}
|
||||
}
|
||||
|
||||
export function handleTokenRoleChanged(event: TokenRoleChangedEvent): void {
|
||||
let tokenId = event.params.tokenId;
|
||||
let toAddress = event.params.toAddress;
|
||||
let byAddress = event.params.byAddress;
|
||||
let role = event.params.role;
|
||||
let status = event.params.status;
|
||||
|
||||
// load token
|
||||
let token = Token.load(Bytes.fromByteArray(Bytes.fromBigInt(tokenId)));
|
||||
if (!token) {
|
||||
log.error('Token not found. TokenId: {}', [tokenId.toString()]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (role === TokenRoles.Controller) {
|
||||
// Controller role
|
||||
// get the list of controllers.
|
||||
let token_controllers = token.controllers;
|
||||
if (!token_controllers) {
|
||||
token_controllers = [];
|
||||
}
|
||||
if (status) {
|
||||
// granted
|
||||
token_controllers.push(toAddress);
|
||||
} else {
|
||||
// revoked
|
||||
// remove address from the controllers list
|
||||
const index = token_controllers.indexOf(event.params.toAddress, 0);
|
||||
if (index > -1) {
|
||||
token_controllers.splice(index, 1);
|
||||
}
|
||||
}
|
||||
token.controllers = token_controllers;
|
||||
} else {
|
||||
log.error('Role not supported. Role: {}, byAddress: {}, toAddress: {}', [role.toString(), byAddress.toHexString(), toAddress.toHexString()]);
|
||||
}
|
||||
}
|
||||
|
||||
export function handleMetadataUpdateWithBooleanValue(event: MetadataUpdateEvent3): void {
|
||||
/**
|
||||
* accessPointAutoApproval
|
||||
|
|
@ -343,7 +433,7 @@ export function handleTransfer(event: TransferEvent): void {
|
|||
accessPointEntity.score = BigInt.fromU32(0);
|
||||
accessPointEntity.contentVerified = false;
|
||||
accessPointEntity.nameVerified = false;
|
||||
accessPointEntity.status = 'DRAFT'; // Since a `ChangeAccessPointCreationStatus` event is emitted instantly after `NewAccessPoint`, the status will be updated in that handler.
|
||||
accessPointEntity.creationStatus = 'DRAFT'; // Since a `ChangeAccessPointCreationStatus` event is emitted instantly after `NewAccessPoint`, the status will be updated in that handler.
|
||||
accessPointEntity.owner = event.params.owner;
|
||||
accessPointEntity.token = Bytes.fromByteArray(Bytes.fromBigInt(event.params.tokenId));
|
||||
|
||||
|
|
@ -369,18 +459,24 @@ export function handleChangeAccessPointCreationStatus(event: ChangeAccessPointCr
|
|||
let status = event.params.status;
|
||||
|
||||
if (accessPointEntity) {
|
||||
if (status == 0) {
|
||||
accessPointEntity.status = 'DRAFT';
|
||||
} else if (status == 1) {
|
||||
accessPointEntity.status = 'APPROVED';
|
||||
} else if (status == 2) {
|
||||
accessPointEntity.status = 'REJECTED';
|
||||
} else if (status == 3) {
|
||||
accessPointEntity.status = 'REMOVED';
|
||||
} else {
|
||||
// Unknown status
|
||||
log.error('Unable to handle ChangeAccessPointCreationStatus. Unknown status. Status: {}, AccessPoint: {}', [status.toString(), event.params.apName]);
|
||||
switch (status) {
|
||||
case 0:
|
||||
accessPointEntity.creationStatus = 'DRAFT';
|
||||
break;
|
||||
case 1:
|
||||
accessPointEntity.creationStatus = 'APPROVED';
|
||||
break;
|
||||
case 2:
|
||||
accessPointEntity.creationStatus = 'REJECTED';
|
||||
break;
|
||||
case 3:
|
||||
accessPointEntity.creationStatus = 'REMOVED';
|
||||
break;
|
||||
default:
|
||||
// Unknown status
|
||||
log.error('Unable to handle ChangeAccessPointCreationStatus. Unknown status. Status: {}, AccessPoint: {}', [status.toString(), event.params.apName]);
|
||||
}
|
||||
|
||||
accessPointEntity.save();
|
||||
} else {
|
||||
// Unknown access point
|
||||
|
|
|
|||
|
|
@ -19,9 +19,10 @@ dataSources:
|
|||
- NewMint
|
||||
- Transfer
|
||||
- Token
|
||||
- Owner
|
||||
- Controller
|
||||
- TokenOwner
|
||||
- TokenController
|
||||
- CollectionOwner
|
||||
- Collection
|
||||
- GithubRepository
|
||||
- AccessPoint
|
||||
- ChangeAccessPointCreationStatus
|
||||
|
|
@ -49,6 +50,14 @@ dataSources:
|
|||
handler: handleNewMint
|
||||
- event: Transfer(indexed address,indexed address,indexed uint256)
|
||||
handler: handleTransfer
|
||||
- event: TokenRoleChanged(indexed uint256,indexed uint8,indexed address,bool,address)
|
||||
handler: handleTokenRoleChanged
|
||||
- event: TokenRolesCleared(indexed uint256,address)
|
||||
handler: handleTokenRolesCleared
|
||||
- event: CollectionRoleChanged(indexed uint8,indexed address,bool,address)
|
||||
handler: handleCollectionRoleChanged
|
||||
- event: Initialized(uint8)
|
||||
handler: handleInitialized
|
||||
- event: ChangeAccessPointContentVerify(string,uint256,indexed bool,indexed address)
|
||||
handler: handleChangeAccessPointContentVerify
|
||||
- event: ChangeAccessPointNameVerify(string,uint256,indexed bool,indexed address)
|
||||
|
|
|
|||
Loading…
Reference in New Issue