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!
|
color: Int!
|
||||||
accessPointAutoApproval: Boolean!
|
accessPointAutoApproval: Boolean!
|
||||||
triggeredBy: Bytes! # address
|
triggeredBy: Bytes! # address
|
||||||
tokenOwner: Owner! # address
|
owner: Owner! # address
|
||||||
blockNumber: BigInt!
|
blockNumber: BigInt!
|
||||||
blockTimestamp: BigInt!
|
blockTimestamp: BigInt!
|
||||||
transactionHash: Bytes!
|
transactionHash: Bytes!
|
||||||
|
|
@ -80,28 +80,19 @@ type Token @entity {
|
||||||
accessPoints: [AccessPoint!] @derivedFrom(field: "token")
|
accessPoints: [AccessPoint!] @derivedFrom(field: "token")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Owner entity for collection, access points, and tokens
|
||||||
type Owner @entity {
|
type Owner @entity {
|
||||||
id: Bytes! # address
|
id: Bytes! # address
|
||||||
tokens: [Token!] @derivedFrom(field: "owner")
|
tokens: [Token!] @derivedFrom(field: "owner")
|
||||||
accessPoints: [AccessPoint!] @derivedFrom(field: "owner")
|
accessPoints: [AccessPoint!] @derivedFrom(field: "owner")
|
||||||
|
collection: Boolean!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Controller entity for tokens
|
||||||
type Controller @entity {
|
type Controller @entity {
|
||||||
id: Bytes! # address
|
id: Bytes! # address
|
||||||
tokens: [Token!] @derivedFrom(field: "controllers")
|
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 {
|
type GitRepository @entity {
|
||||||
id: String! # transaction hash of the first transaction this repository appeared in
|
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';
|
import { Address, Bytes, log, store, ethereum, BigInt } from '@graphprotocol/graph-ts';
|
||||||
|
|
||||||
|
// Event Imports [based on the yaml config]
|
||||||
import {
|
import {
|
||||||
Approval as ApprovalEvent,
|
Approval as ApprovalEvent,
|
||||||
ApprovalForAll as ApprovalForAllEvent,
|
ApprovalForAll as ApprovalForAllEvent,
|
||||||
MetadataUpdate as MetadataUpdateEvent,
|
MetadataUpdate as MetadataUpdateEvent,
|
||||||
MetadataUpdate1 as MetadataUpdateEvent1,
|
MetadataUpdate1 as MetadataUpdateEvent1,
|
||||||
MetadataUpdate2 as MetadataUpdateEvent2,
|
MetadataUpdate2 as MetadataUpdateEvent2,
|
||||||
|
TokenRoleChanged as TokenRoleChangedEvent,
|
||||||
MetadataUpdate3 as MetadataUpdateEvent3,
|
MetadataUpdate3 as MetadataUpdateEvent3,
|
||||||
|
CollectionRoleChanged as CollectionRoleChangedEvent,
|
||||||
|
Initialized as InitializedEvent,
|
||||||
Transfer as TransferEvent,
|
Transfer as TransferEvent,
|
||||||
NewMint as NewMintEvent,
|
NewMint as NewMintEvent,
|
||||||
ChangeAccessPointCreationStatus as ChangeAccessPointCreationStatusEvent,
|
ChangeAccessPointCreationStatus as ChangeAccessPointCreationStatusEvent,
|
||||||
|
|
@ -14,21 +19,28 @@ import {
|
||||||
ChangeAccessPointNameVerify as ChangeAccessPointNameVerifyEvent,
|
ChangeAccessPointNameVerify as ChangeAccessPointNameVerifyEvent,
|
||||||
ChangeAccessPointContentVerify as ChangeAccessPointContentVerifyEvent,
|
ChangeAccessPointContentVerify as ChangeAccessPointContentVerifyEvent,
|
||||||
} from '../generated/FleekNFA/FleekNFA';
|
} from '../generated/FleekNFA/FleekNFA';
|
||||||
|
|
||||||
|
// Entity Imports [based on the schema]
|
||||||
import {
|
import {
|
||||||
AccessPoint,
|
AccessPoint,
|
||||||
Approval,
|
Approval,
|
||||||
ApprovalForAll,
|
ApprovalForAll,
|
||||||
Collection,
|
Owner,
|
||||||
CollectionOwner,
|
|
||||||
Controller,
|
|
||||||
GitRepository as GitRepositoryEntity,
|
GitRepository as GitRepositoryEntity,
|
||||||
MetadataUpdate,
|
MetadataUpdate,
|
||||||
NewMint,
|
NewMint,
|
||||||
Owner,
|
|
||||||
Token,
|
Token,
|
||||||
Transfer,
|
Transfer,
|
||||||
} from '../generated/schema';
|
} from '../generated/schema';
|
||||||
|
|
||||||
|
enum CollectionRoles {
|
||||||
|
Owner,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum TokenRoles {
|
||||||
|
Controller,
|
||||||
|
};
|
||||||
|
|
||||||
export function handleApproval(event: ApprovalEvent): void {
|
export function handleApproval(event: ApprovalEvent): void {
|
||||||
let entity = new Approval(
|
let entity = new Approval(
|
||||||
event.transaction.hash.concatI32(event.logIndex.toI32())
|
event.transaction.hash.concatI32(event.logIndex.toI32())
|
||||||
|
|
@ -87,7 +99,7 @@ export function handleNewMint(event: NewMintEvent): void {
|
||||||
newMintEntity.color = color;
|
newMintEntity.color = color;
|
||||||
newMintEntity.accessPointAutoApproval = accessPointAutoApproval;
|
newMintEntity.accessPointAutoApproval = accessPointAutoApproval;
|
||||||
newMintEntity.triggeredBy = event.params.minter;
|
newMintEntity.triggeredBy = event.params.minter;
|
||||||
newMintEntity.tokenOwner = ownerAddress;
|
newMintEntity.owner = ownerAddress;
|
||||||
newMintEntity.blockNumber = event.block.number;
|
newMintEntity.blockNumber = event.block.number;
|
||||||
newMintEntity.blockTimestamp = event.block.timestamp;
|
newMintEntity.blockTimestamp = event.block.timestamp;
|
||||||
newMintEntity.transactionHash = event.transaction.hash;
|
newMintEntity.transactionHash = event.transaction.hash;
|
||||||
|
|
@ -97,7 +109,6 @@ export function handleNewMint(event: NewMintEvent): void {
|
||||||
// Create Token, Owner, and Controller entities
|
// Create Token, Owner, and Controller entities
|
||||||
|
|
||||||
let owner = Owner.load(ownerAddress);
|
let owner = Owner.load(ownerAddress);
|
||||||
let controller = Controller.load(ownerAddress);
|
|
||||||
let gitRepositoryEntity = GitRepositoryEntity.load(gitRepository);
|
let gitRepositoryEntity = GitRepositoryEntity.load(gitRepository);
|
||||||
let token = new Token(Bytes.fromByteArray(Bytes.fromBigInt(tokenId)));
|
let token = new Token(Bytes.fromByteArray(Bytes.fromBigInt(tokenId)));
|
||||||
|
|
||||||
|
|
@ -106,11 +117,6 @@ export function handleNewMint(event: NewMintEvent): void {
|
||||||
owner = new Owner(ownerAddress);
|
owner = new Owner(ownerAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!controller) {
|
|
||||||
// Create a new controller entity
|
|
||||||
controller = new Controller(ownerAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gitRepositoryEntity) {
|
if (!gitRepositoryEntity) {
|
||||||
// Create a new gitRepository entity
|
// Create a new gitRepository entity
|
||||||
gitRepositoryEntity = new GitRepositoryEntity(gitRepository);
|
gitRepositoryEntity = new GitRepositoryEntity(gitRepository);
|
||||||
|
|
@ -136,7 +142,6 @@ export function handleNewMint(event: NewMintEvent): void {
|
||||||
|
|
||||||
// Save entities
|
// Save entities
|
||||||
owner.save();
|
owner.save();
|
||||||
controller.save();
|
|
||||||
gitRepositoryEntity.save();
|
gitRepositoryEntity.save();
|
||||||
token.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 {
|
export function handleMetadataUpdateWithBooleanValue(event: MetadataUpdateEvent3): void {
|
||||||
/**
|
/**
|
||||||
* accessPointAutoApproval
|
* accessPointAutoApproval
|
||||||
|
|
@ -343,7 +433,7 @@ export function handleTransfer(event: TransferEvent): void {
|
||||||
accessPointEntity.score = BigInt.fromU32(0);
|
accessPointEntity.score = BigInt.fromU32(0);
|
||||||
accessPointEntity.contentVerified = false;
|
accessPointEntity.contentVerified = false;
|
||||||
accessPointEntity.nameVerified = 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.owner = event.params.owner;
|
||||||
accessPointEntity.token = Bytes.fromByteArray(Bytes.fromBigInt(event.params.tokenId));
|
accessPointEntity.token = Bytes.fromByteArray(Bytes.fromBigInt(event.params.tokenId));
|
||||||
|
|
||||||
|
|
@ -369,18 +459,24 @@ export function handleChangeAccessPointCreationStatus(event: ChangeAccessPointCr
|
||||||
let status = event.params.status;
|
let status = event.params.status;
|
||||||
|
|
||||||
if (accessPointEntity) {
|
if (accessPointEntity) {
|
||||||
if (status == 0) {
|
switch (status) {
|
||||||
accessPointEntity.status = 'DRAFT';
|
case 0:
|
||||||
} else if (status == 1) {
|
accessPointEntity.creationStatus = 'DRAFT';
|
||||||
accessPointEntity.status = 'APPROVED';
|
break;
|
||||||
} else if (status == 2) {
|
case 1:
|
||||||
accessPointEntity.status = 'REJECTED';
|
accessPointEntity.creationStatus = 'APPROVED';
|
||||||
} else if (status == 3) {
|
break;
|
||||||
accessPointEntity.status = 'REMOVED';
|
case 2:
|
||||||
} else {
|
accessPointEntity.creationStatus = 'REJECTED';
|
||||||
// Unknown status
|
break;
|
||||||
log.error('Unable to handle ChangeAccessPointCreationStatus. Unknown status. Status: {}, AccessPoint: {}', [status.toString(), event.params.apName]);
|
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();
|
accessPointEntity.save();
|
||||||
} else {
|
} else {
|
||||||
// Unknown access point
|
// Unknown access point
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,10 @@ dataSources:
|
||||||
- NewMint
|
- NewMint
|
||||||
- Transfer
|
- Transfer
|
||||||
- Token
|
- Token
|
||||||
- Owner
|
- TokenOwner
|
||||||
- Controller
|
- TokenController
|
||||||
- CollectionOwner
|
- CollectionOwner
|
||||||
|
- Collection
|
||||||
- GithubRepository
|
- GithubRepository
|
||||||
- AccessPoint
|
- AccessPoint
|
||||||
- ChangeAccessPointCreationStatus
|
- ChangeAccessPointCreationStatus
|
||||||
|
|
@ -49,6 +50,14 @@ dataSources:
|
||||||
handler: handleNewMint
|
handler: handleNewMint
|
||||||
- event: Transfer(indexed address,indexed address,indexed uint256)
|
- event: Transfer(indexed address,indexed address,indexed uint256)
|
||||||
handler: handleTransfer
|
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)
|
- event: ChangeAccessPointContentVerify(string,uint256,indexed bool,indexed address)
|
||||||
handler: handleChangeAccessPointContentVerify
|
handler: handleChangeAccessPointContentVerify
|
||||||
- event: ChangeAccessPointNameVerify(string,uint256,indexed bool,indexed address)
|
- event: ChangeAccessPointNameVerify(string,uint256,indexed bool,indexed address)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue