534 lines
16 KiB
TypeScript
534 lines
16 KiB
TypeScript
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,
|
|
ChangeAccessPointScore as ChangeAccessPointCreationScoreEvent,
|
|
NewAccessPoint as NewAccessPointEvent,
|
|
ChangeAccessPointNameVerify as ChangeAccessPointNameVerifyEvent,
|
|
ChangeAccessPointContentVerify as ChangeAccessPointContentVerifyEvent,
|
|
} from '../generated/FleekNFA/FleekNFA';
|
|
|
|
// Entity Imports [based on the schema]
|
|
import {
|
|
AccessPoint,
|
|
Approval,
|
|
ApprovalForAll,
|
|
Owner,
|
|
GitRepository as GitRepositoryEntity,
|
|
MetadataUpdate,
|
|
NewMint,
|
|
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())
|
|
);
|
|
entity.owner = event.params.owner;
|
|
entity.approved = event.params.approved;
|
|
entity.tokenId = event.params.tokenId;
|
|
|
|
entity.blockNumber = event.block.number;
|
|
entity.blockTimestamp = event.block.timestamp;
|
|
entity.transactionHash = event.transaction.hash;
|
|
|
|
entity.save();
|
|
}
|
|
|
|
export function handleApprovalForAll(event: ApprovalForAllEvent): void {
|
|
let entity = new ApprovalForAll(
|
|
event.transaction.hash.concatI32(event.logIndex.toI32())
|
|
);
|
|
entity.owner = event.params.owner;
|
|
entity.operator = event.params.operator;
|
|
entity.approved = event.params.approved;
|
|
|
|
entity.blockNumber = event.block.number;
|
|
entity.blockTimestamp = event.block.timestamp;
|
|
entity.transactionHash = event.transaction.hash;
|
|
|
|
entity.save();
|
|
}
|
|
|
|
export function handleNewMint(event: NewMintEvent): void {
|
|
let newMintEntity = new NewMint(
|
|
event.transaction.hash.concatI32(event.logIndex.toI32())
|
|
);
|
|
|
|
let name = event.params.name;
|
|
let description = event.params.description;
|
|
let externalURL = event.params.externalURL;
|
|
let ENS = event.params.ENS;
|
|
let gitRepository = event.params.gitRepository;
|
|
let commitHash = event.params.commitHash;
|
|
let logo = event.params.logo;
|
|
let color = event.params.color;
|
|
let accessPointAutoApproval = event.params.accessPointAutoApproval;
|
|
let tokenId = event.params.tokenId;
|
|
let ownerAddress = event.params.owner;
|
|
|
|
newMintEntity.tokenId = tokenId;
|
|
newMintEntity.name = name;
|
|
newMintEntity.description = description;
|
|
newMintEntity.externalURL = externalURL;
|
|
newMintEntity.ENS = ENS;
|
|
newMintEntity.commitHash = commitHash;
|
|
newMintEntity.gitRepository = gitRepository;
|
|
newMintEntity.logo = logo;
|
|
newMintEntity.color = color;
|
|
newMintEntity.accessPointAutoApproval = accessPointAutoApproval;
|
|
newMintEntity.triggeredBy = event.params.minter;
|
|
newMintEntity.owner = ownerAddress;
|
|
newMintEntity.blockNumber = event.block.number;
|
|
newMintEntity.blockTimestamp = event.block.timestamp;
|
|
newMintEntity.transactionHash = event.transaction.hash;
|
|
newMintEntity.save();
|
|
log.error('{}', [tokenId.toString()]);
|
|
|
|
// Create Token, Owner, and Controller entities
|
|
|
|
let owner = Owner.load(ownerAddress);
|
|
let gitRepositoryEntity = GitRepositoryEntity.load(gitRepository);
|
|
let token = new Token(Bytes.fromByteArray(Bytes.fromBigInt(tokenId)));
|
|
|
|
if (!owner) {
|
|
// Create a new owner entity
|
|
owner = new Owner(ownerAddress);
|
|
}
|
|
|
|
if (!gitRepositoryEntity) {
|
|
// Create a new gitRepository entity
|
|
gitRepositoryEntity = new GitRepositoryEntity(gitRepository);
|
|
}
|
|
|
|
// Populate Token with data from the event
|
|
token.tokenId = tokenId;
|
|
token.name = name;
|
|
token.description = description;
|
|
token.externalURL = externalURL;
|
|
token.ENS = ENS;
|
|
token.gitRepository = gitRepository;
|
|
token.commitHash = commitHash;
|
|
token.logo = logo;
|
|
token.color = color;
|
|
token.accessPointAutoApproval = accessPointAutoApproval;
|
|
token.owner = ownerAddress;
|
|
token.mintTransaction = event.transaction.hash.concatI32(
|
|
event.logIndex.toI32()
|
|
);
|
|
token.mintedBy = event.params.minter;
|
|
token.controllers = [ownerAddress];
|
|
|
|
// Save entities
|
|
owner.save();
|
|
gitRepositoryEntity.save();
|
|
token.save();
|
|
}
|
|
|
|
export function handleMetadataUpdateWithStringValue(
|
|
event: MetadataUpdateEvent
|
|
): void {
|
|
/**
|
|
* Metadata handled here:
|
|
* setTokenExternalURL
|
|
* setTokenENS
|
|
* setTokenName
|
|
* setTokenDescription
|
|
* setTokenLogo
|
|
* */
|
|
let entity = new MetadataUpdate(
|
|
event.transaction.hash.concatI32(event.logIndex.toI32())
|
|
);
|
|
|
|
entity.tokenId = event.params._tokenId;
|
|
entity.key = event.params.key;
|
|
entity.stringValue = event.params.value;
|
|
entity.blockNumber = event.block.number;
|
|
entity.blockTimestamp = event.block.timestamp;
|
|
entity.transactionHash = event.transaction.hash;
|
|
|
|
entity.save();
|
|
|
|
// UPDATE TOKEN
|
|
let token = Token.load(
|
|
Bytes.fromByteArray(Bytes.fromBigInt(event.params._tokenId))
|
|
);
|
|
|
|
if (token) {
|
|
if (event.params.key == 'externalURL') {
|
|
token.externalURL = event.params.value;
|
|
} else if (event.params.key == 'ENS') {
|
|
token.ENS = event.params.value;
|
|
} else if (event.params.key == 'name') {
|
|
token.name = event.params.value;
|
|
} else if (event.params.key == 'description') {
|
|
token.description = event.params.value;
|
|
} else {
|
|
// logo
|
|
token.logo = event.params.value;
|
|
}
|
|
token.save();
|
|
}
|
|
}
|
|
|
|
export function handleMetadataUpdateWithDoubleStringValue(
|
|
event: MetadataUpdateEvent2
|
|
): void {
|
|
/**
|
|
* setTokenBuild
|
|
*/
|
|
let entity = new MetadataUpdate(
|
|
event.transaction.hash.concatI32(event.logIndex.toI32())
|
|
);
|
|
|
|
entity.key = event.params.key;
|
|
entity.tokenId = event.params._tokenId;
|
|
entity.doubleStringValue = event.params.value;
|
|
entity.blockNumber = event.block.number;
|
|
entity.blockTimestamp = event.block.timestamp;
|
|
entity.transactionHash = event.transaction.hash;
|
|
|
|
entity.save();
|
|
|
|
// UPDATE TOKEN
|
|
let token = Token.load(
|
|
Bytes.fromByteArray(Bytes.fromBigInt(event.params._tokenId))
|
|
);
|
|
|
|
if (token) {
|
|
if (event.params.key == 'build') {
|
|
let gitRepositoryEntity = GitRepositoryEntity.load(event.params.value[1]);
|
|
if (!gitRepositoryEntity) {
|
|
// Create a new gitRepository entity
|
|
gitRepositoryEntity = new GitRepositoryEntity(event.params.value[1]);
|
|
}
|
|
token.commitHash = event.params.value[0];
|
|
token.gitRepository = event.params.value[1];
|
|
token.save();
|
|
gitRepositoryEntity.save();
|
|
}
|
|
}
|
|
}
|
|
|
|
export function handleMetadataUpdateWithIntValue(
|
|
event: MetadataUpdateEvent1
|
|
): void {
|
|
/**
|
|
* setTokenColor
|
|
*/
|
|
let entity = new MetadataUpdate(
|
|
event.transaction.hash.concatI32(event.logIndex.toI32())
|
|
);
|
|
|
|
entity.key = event.params.key;
|
|
entity.tokenId = event.params._tokenId;
|
|
entity.uint24Value = event.params.value;
|
|
entity.blockNumber = event.block.number;
|
|
entity.blockTimestamp = event.block.timestamp;
|
|
entity.transactionHash = event.transaction.hash;
|
|
|
|
entity.save();
|
|
|
|
let token = Token.load(
|
|
Bytes.fromByteArray(Bytes.fromBigInt(event.params._tokenId))
|
|
);
|
|
|
|
if (token) {
|
|
if (event.params.key == 'color') {
|
|
token.color = event.params.value;
|
|
}
|
|
token.save();
|
|
}
|
|
}
|
|
|
|
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
|
|
*/
|
|
let entity = new MetadataUpdate(
|
|
event.transaction.hash.concatI32(event.logIndex.toI32())
|
|
);
|
|
|
|
entity.key = event.params.key;
|
|
entity.tokenId = event.params._tokenId;
|
|
entity.booleanValue = event.params.value;
|
|
entity.blockNumber = event.block.number;
|
|
entity.blockTimestamp = event.block.timestamp;
|
|
entity.transactionHash = event.transaction.hash;
|
|
|
|
entity.save();
|
|
|
|
let token = Token.load(Bytes.fromByteArray(Bytes.fromBigInt(event.params._tokenId)));
|
|
|
|
if (token) {
|
|
if (event.params.key == 'accessPointAutoApproval') {
|
|
token.accessPointAutoApproval = event.params.value;
|
|
}
|
|
token.save();
|
|
}
|
|
}
|
|
|
|
export function handleTransfer(event: TransferEvent): void {
|
|
let entity = new Transfer(
|
|
event.transaction.hash.concatI32(event.logIndex.toI32())
|
|
);
|
|
entity.from = event.params.from;
|
|
entity.to = event.params.to;
|
|
entity.tokenId = event.params.tokenId;
|
|
|
|
entity.blockNumber = event.block.number;
|
|
entity.blockTimestamp = event.block.timestamp;
|
|
entity.transactionHash = event.transaction.hash;
|
|
|
|
entity.save();
|
|
|
|
let token: Token | null;
|
|
|
|
let owner_address = event.params.to;
|
|
let owner = Owner.load(owner_address);
|
|
|
|
if (!owner) {
|
|
// Create a new owner entity
|
|
owner = new Owner(owner_address);
|
|
}
|
|
|
|
if (parseInt(event.params.from.toHexString()) !== 0) {
|
|
// Transfer
|
|
|
|
// Load the Token by using its TokenId
|
|
token = Token.load(
|
|
Bytes.fromByteArray(Bytes.fromBigInt(event.params.tokenId))
|
|
);
|
|
|
|
if (token) {
|
|
// Entity exists
|
|
token.owner = owner_address;
|
|
|
|
// Save both entities
|
|
owner.save();
|
|
token.save();
|
|
} else {
|
|
// Entity does not exist
|
|
log.error('Unknown token was transferred.', []);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* This handler will create and load entities in the following order:
|
|
* - AccessPoint [create]
|
|
* - Owner [load / create]
|
|
* Note to discuss later: Should a `NewAccessPoint` entity be also created and defined?
|
|
*/
|
|
export function handleNewAccessPoint(event: NewAccessPointEvent): void {
|
|
// Create an AccessPoint entity
|
|
let accessPointEntity = new AccessPoint(event.params.apName);
|
|
accessPointEntity.score = BigInt.fromU32(0);
|
|
accessPointEntity.contentVerified = false;
|
|
accessPointEntity.nameVerified = false;
|
|
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));
|
|
|
|
// Load / Create an Owner entity
|
|
let ownerEntity = Owner.load(event.params.owner);
|
|
|
|
if (!ownerEntity) {
|
|
// Create a new owner entity
|
|
ownerEntity = new Owner(event.params.owner);
|
|
}
|
|
|
|
// Save entities.
|
|
accessPointEntity.save();
|
|
ownerEntity.save();
|
|
}
|
|
|
|
/**
|
|
* This handler will update the status of an access point entity.
|
|
*/
|
|
export function handleChangeAccessPointCreationStatus(event: ChangeAccessPointCreationStatusEvent): void {
|
|
// Load the AccessPoint entity
|
|
let accessPointEntity = AccessPoint.load(event.params.apName);
|
|
let status = event.params.status;
|
|
|
|
if (accessPointEntity) {
|
|
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
|
|
log.error('Unable to handle ChangeAccessPointCreationStatus. Unknown access point. Status: {}, AccessPoint: {}', [status.toString(), event.params.apName]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This handler will update the score of an access point entity.
|
|
*/
|
|
export function handleChangeAccessPointScore(event: ChangeAccessPointCreationScoreEvent): void {
|
|
// Load the AccessPoint entity
|
|
let accessPointEntity = AccessPoint.load(event.params.apName);
|
|
|
|
if (accessPointEntity) {
|
|
accessPointEntity.score = event.params.score;
|
|
accessPointEntity.save();
|
|
} else {
|
|
// Unknown access point
|
|
log.error('Unable to handle ChangeAccessPointScore. Unknown access point. Score: {}, AccessPoint: {}', [event.params.score.toString(), event.params.apName]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This handler will update the nameVerified field of an access point entity.
|
|
*/
|
|
export function handleChangeAccessPointNameVerify(event: ChangeAccessPointNameVerifyEvent): void {
|
|
// Load the AccessPoint entity
|
|
let accessPointEntity = AccessPoint.load(event.params.apName);
|
|
|
|
if (accessPointEntity) {
|
|
accessPointEntity.nameVerified = event.params.verified;
|
|
accessPointEntity.save();
|
|
} else {
|
|
// Unknown access point
|
|
log.error('Unable to handle ChangeAccessPointNameVerify. Unknown access point. Verified: {}, AccessPoint: {}', [event.params.verified.toString(), event.params.apName]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This handler will update the contentVerified field of an access point entity.
|
|
*/
|
|
export function handleChangeAccessPointContentVerify(event: ChangeAccessPointContentVerifyEvent): void {
|
|
// Load the AccessPoint entity
|
|
let accessPointEntity = AccessPoint.load(event.params.apName);
|
|
|
|
if (accessPointEntity) {
|
|
accessPointEntity.contentVerified = event.params.verified;
|
|
accessPointEntity.save();
|
|
} else {
|
|
// Unknown access point
|
|
log.error('Unable to handle ChangeAccessPointContentVerify. Unknown access point. Verified: {}, AccessPoint: {}', [event.params.verified.toString(), event.params.apName]);
|
|
}
|
|
}
|