diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index 8f756cc..70d9bc0 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -131,13 +131,20 @@ type Transfer @entity(immutable: true) { } type Token @entity { - id: Bytes! #transaction hash + id: Bytes! # Token ID + mint_transaction_hash: Bytes! tokenId: BigInt! # uint256 owner: Holder! minted_by: Bytes! + controllers: [Controller!] } type Holder @entity { id: Bytes! #address tokens: [Token!] @derivedFrom(field: "owner") } + +type Controller @entity { + id: Bytes! #address + tokens: [Token!] @derivedFrom(field: "controllers") +} diff --git a/subgraph/src/fleek-nfa.ts b/subgraph/src/fleek-nfa.ts index 85931f8..2c31f96 100644 --- a/subgraph/src/fleek-nfa.ts +++ b/subgraph/src/fleek-nfa.ts @@ -1,4 +1,4 @@ -import { Address, log } from '@graphprotocol/graph-ts'; +import { Address, Bytes, log } from '@graphprotocol/graph-ts'; import { Approval as ApprovalEvent, ApprovalForAll as ApprovalForAllEvent, @@ -20,12 +20,15 @@ import { ApprovalForAll, CollectionRoleGranted, CollectionRoleRevoked, + Controller, + Holder, NewBuild, NewTokenDescription, NewTokenENS, NewTokenExternalURL, NewTokenImage, NewTokenName, + Token, TokenRoleGranted, TokenRoleRevoked, Transfer, @@ -203,6 +206,41 @@ export function handleTokenRoleGranted(event: TokenRoleGrantedEvent): void { entity.transactionHash = event.transaction.hash; entity.save(); + + if (event.params.role === 1) { + // This is a new controller being added to a token. + // First we add the controller to the token's list of controllers. + // Then we create a new controller entity. + + let token = Token.load( + Bytes.fromByteArray(Bytes.fromBigInt(event.params.tokenId)) + ); + let controller = Controller.load(event.params.toAddress); + + if (!controller) { + // Create a new controller entity + log.debug('CONTROLLER IS GOING TO BE CREATED HERE.', []); + controller = new Controller(event.params.toAddress); + } + + if (token !== null) { + let token_controllers = token.controllers; + if (!token_controllers) { + token_controllers = []; + } + token_controllers.push(event.params.toAddress); + token.controllers = token_controllers; + } else { + log.error( + 'Handling controller access granted event for tokenId {}. THE TOKEN DOES NOT EXIST. FAILED TO UPDATE THE TOKEN ENTITY.', + [event.params.tokenId.toHexString()] + ); + return; + } + + controller.save(); + token.save(); + } } export function handleTokenRoleRevoked(event: TokenRoleRevokedEvent): void { @@ -219,6 +257,43 @@ export function handleTokenRoleRevoked(event: TokenRoleRevokedEvent): void { entity.transactionHash = event.transaction.hash; entity.save(); + + if (event.params.role === 1) { + // This is a controller being removed from a token. + + // Load the token with the tokenId. + let token = Token.load( + Bytes.fromByteArray(Bytes.fromBigInt(event.params.tokenId)) + ); + + // Check if the token entity exists. + if (token !== null) { + // get the list of controllers. + let token_controllers = token.controllers; + if (!token_controllers) { + token_controllers = []; + } + + // remove address from the controllers list + const index = token_controllers.indexOf(event.params.toAddress, 0); + if (index > -1) { + token_controllers.splice(index, 1); + } + + // assign the new controllers list + token.controllers = token_controllers; + } else { + // the token does not exist + log.error( + 'Handling controller access revoked event for tokenId {}. THE TOKEN DOES NOT EXIST. FAILED TO UPDATE THE TOKEN ENTITY.', + [event.params.tokenId.toHexString()] + ); + return; + } + + // save the token data + token.save(); + } } export function handleTransfer(event: TransferEvent): void { diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml index f4cbebf..5bbec51 100644 --- a/subgraph/subgraph.yaml +++ b/subgraph/subgraph.yaml @@ -27,6 +27,9 @@ dataSources: - TokenRoleGranted - TokenRoleRevoked - Transfer + - Token + - Holder + - Controller abis: - name: FleekNFA file: ./abis/FleekNFA.json