From 2eca4be8f03b29c12ad9754597628986e2d24fc2 Mon Sep 17 00:00:00 2001 From: Shredder <110225819+EmperorOrokuSaki@users.noreply.github.com> Date: Fri, 17 Mar 2023 19:08:17 +0330 Subject: [PATCH] feat: update subgraph and its new mint handler + test refactor (#186) * feat: update newMint and add verifier and apAutoApproval, update subgraph accordingly. * remove: bugged tests. --- contracts/contracts/FleekERC721.sol | 8 +- subgraph/schema.graphql | 8 ++ subgraph/src/access-point.ts | 2 + subgraph/src/mint.ts | 12 +- subgraph/src/transfer.ts | 1 + subgraph/subgraph.yaml | 2 +- subgraph/tests/matchstick/.latest.json | 4 +- .../CollectionRoleChanged.test.ts | 80 ----------- .../access-control/TokenRoleChanged.test.ts | 124 ------------------ .../access-points/newAccessPoint.test.ts | 100 -------------- subgraph/tests/matchstick/helpers/utils.ts | 37 +----- 11 files changed, 28 insertions(+), 350 deletions(-) delete mode 100644 subgraph/tests/matchstick/access-control/CollectionRoleChanged.test.ts delete mode 100644 subgraph/tests/matchstick/access-control/TokenRoleChanged.test.ts delete mode 100644 subgraph/tests/matchstick/access-points/newAccessPoint.test.ts diff --git a/contracts/contracts/FleekERC721.sol b/contracts/contracts/FleekERC721.sol index f9b2d04..df1df5a 100644 --- a/contracts/contracts/FleekERC721.sol +++ b/contracts/contracts/FleekERC721.sol @@ -40,8 +40,10 @@ contract FleekERC721 is string gitRepository, string logo, uint24 color, + bool accessPointAutoApproval, address indexed minter, - address indexed owner + address indexed owner, + address verifier ); event MetadataUpdate(uint256 indexed _tokenId, string key, address value, address indexed triggeredBy); @@ -124,8 +126,10 @@ contract FleekERC721 is gitRepository, logo, color, + accessPointAutoApproval, msg.sender, - to + to, + verifier ); _tokenVerifier[tokenId] = verifier; diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index e3528cc..11292c6 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -32,6 +32,7 @@ type NewMint @entity(immutable: true) { accessPointAutoApproval: Boolean! triggeredBy: Bytes! # address owner: Owner! # address + verifier: Bytes! blockNumber: BigInt! blockTimestamp: BigInt! transactionHash: Bytes! @@ -78,6 +79,7 @@ type Token @entity { gitRepository: GitRepository! commitHash: String! accessPoints: [AccessPoint!] @derivedFrom(field: "token") + verifier: Verifier! # Address } # Owner entity for collection, access points, and tokens @@ -94,6 +96,12 @@ type Controller @entity { tokens: [Token!] @derivedFrom(field: "controllers") } +# Verifier entity for tokens +type Verifier @entity { + id: Bytes! # address + tokens: [Token!] @derivedFrom(field: "verifier") +} + type GitRepository @entity { id: String! # transaction hash of the first transaction this repository appeared in tokens: [Token!] @derivedFrom(field: "gitRepository") diff --git a/subgraph/src/access-point.ts b/subgraph/src/access-point.ts index 02816b7..7d598cc 100644 --- a/subgraph/src/access-point.ts +++ b/subgraph/src/access-point.ts @@ -46,6 +46,8 @@ export function handleNewAccessPoint(event: NewAccessPointEvent): void { if (!ownerEntity) { // Create a new owner entity ownerEntity = new Owner(event.params.owner); + // Since no CollectionRoleChanged event was emitted before for this address, we can set `collection` to false. + ownerEntity.collection = false; } // Save entities. diff --git a/subgraph/src/mint.ts b/subgraph/src/mint.ts index 71b9105..e3e01d4 100644 --- a/subgraph/src/mint.ts +++ b/subgraph/src/mint.ts @@ -32,6 +32,7 @@ export function handleNewMint(event: NewMintEvent): void { let accessPointAutoApproval = event.params.accessPointAutoApproval; let tokenId = event.params.tokenId; let ownerAddress = event.params.owner; + let verifierAddress = event.params.verifier; newMintEntity.tokenId = tokenId; newMintEntity.name = name; @@ -45,6 +46,7 @@ export function handleNewMint(event: NewMintEvent): void { newMintEntity.accessPointAutoApproval = accessPointAutoApproval; newMintEntity.triggeredBy = event.params.minter; newMintEntity.owner = ownerAddress; + newMintEntity.verifier = verifierAddress; newMintEntity.blockNumber = event.block.number; newMintEntity.blockTimestamp = event.block.timestamp; newMintEntity.transactionHash = event.transaction.hash; @@ -54,17 +56,13 @@ export function handleNewMint(event: NewMintEvent): void { // 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); + // Since no CollectionRoleChanged event was emitted before for this address, we can set `collection` to false. + owner.collection = false; } // Populate Token with data from the event @@ -79,6 +77,7 @@ export function handleNewMint(event: NewMintEvent): void { token.color = color; token.accessPointAutoApproval = accessPointAutoApproval; token.owner = ownerAddress; + token.verifier = verifierAddress; token.mintTransaction = event.transaction.hash.concatI32( event.logIndex.toI32() ); @@ -87,6 +86,5 @@ export function handleNewMint(event: NewMintEvent): void { // Save entities owner.save(); - gitRepositoryEntity.save(); token.save(); } \ No newline at end of file diff --git a/subgraph/src/transfer.ts b/subgraph/src/transfer.ts index 6dea3d2..faa64a4 100644 --- a/subgraph/src/transfer.ts +++ b/subgraph/src/transfer.ts @@ -1,6 +1,7 @@ import { Bytes, log, + store } from '@graphprotocol/graph-ts'; // Event Imports [based on the yaml config] diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml index 27b3d76..d64b7c7 100644 --- a/subgraph/subgraph.yaml +++ b/subgraph/subgraph.yaml @@ -47,7 +47,7 @@ dataSources: handler: handleMetadataUpdateWithIntValue - event: MetadataUpdate(indexed uint256,string,bool,indexed address) handler: handleMetadataUpdateWithBooleanValue - - event: NewMint(indexed uint256,string,string,string,string,string,string,string,uint24,bool,indexed address,indexed address) + - event: NewMint(indexed uint256,string,string,string,string,string,string,string,uint24,bool,indexed address,indexed address,address) handler: handleNewMint - event: Transfer(indexed address,indexed address,indexed uint256) handler: handleTransfer diff --git a/subgraph/tests/matchstick/.latest.json b/subgraph/tests/matchstick/.latest.json index 1d88be3..870c04b 100644 --- a/subgraph/tests/matchstick/.latest.json +++ b/subgraph/tests/matchstick/.latest.json @@ -1,4 +1,4 @@ { "version": "0.5.4", - "timestamp": 1678390993500 -} + "timestamp": 1679061942846 +} \ No newline at end of file diff --git a/subgraph/tests/matchstick/access-control/CollectionRoleChanged.test.ts b/subgraph/tests/matchstick/access-control/CollectionRoleChanged.test.ts deleted file mode 100644 index ef4ba96..0000000 --- a/subgraph/tests/matchstick/access-control/CollectionRoleChanged.test.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll, -} from 'matchstick-as/assembly/index'; -import { BigInt, Bytes } from '@graphprotocol/graph-ts'; -import { - createNewCollectionRoleChanged, - handleCollectionRoleChangedList, - makeEventId, - USER_ONE, - USER_TWO, -} from '../helpers/utils'; -import { CollectionRoleChanged } from '../../../generated/FleekNFA/FleekNFA'; - -describe('Collection Role Changed tests', () => { - beforeAll(() => { - // Collection Role Changed - let collectionRoleChangedList: CollectionRoleChanged[] = []; - - collectionRoleChangedList.push( - createNewCollectionRoleChanged(0, 0, USER_ONE, true, USER_TWO) // User Two grants collection owner access to User One - ); - - collectionRoleChangedList.push( - createNewCollectionRoleChanged(2, 0, USER_ONE, false, USER_TWO) // User Two revokes the owner access of User One to the collection - ); - - handleCollectionRoleChangedList(collectionRoleChangedList); - }); - - afterAll(() => { - clearStore(); - }); - - describe('Assertions', () => { - test('Check the `role` field of each CollectionRoleChanged event entity', () => { - assert.fieldEquals('CollectionRoleChanged', makeEventId(0), 'role', '0'); - assert.fieldEquals('CollectionRoleChanged', makeEventId(2), 'role', '0'); - }); - - test('Check the `toAddress` field of each CollectionRoleChanged event entity', () => { - assert.fieldEquals( - 'CollectionRoleChanged', - makeEventId(0), - 'toAddress', - USER_ONE.toString() - ); - assert.fieldEquals( - 'CollectionRoleChanged', - makeEventId(2), - 'toAddress', - USER_ONE.toString() - ); - }); - - test('Check the `byAddress` field of each CollectionRoleChanged event entity', () => { - assert.fieldEquals( - 'CollectionRoleChanged', - makeEventId(0), - 'byAddress', - USER_TWO.toString() - ); - assert.fieldEquals( - 'CollectionRoleChanged', - makeEventId(2), - 'byAddress', - USER_TWO.toString() - ); - }); - - test('Check the `status` field of each CollectionRoleChanged event entity', () => { - assert.fieldEquals('TokenRoleChanged', makeEventId(0), 'status', 'true'); - assert.fieldEquals('TokenRoleChanged', makeEventId(2), 'status', 'false'); - }); - }); -}); diff --git a/subgraph/tests/matchstick/access-control/TokenRoleChanged.test.ts b/subgraph/tests/matchstick/access-control/TokenRoleChanged.test.ts deleted file mode 100644 index e0e6fdd..0000000 --- a/subgraph/tests/matchstick/access-control/TokenRoleChanged.test.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll, -} from 'matchstick-as/assembly/index'; -import { BigInt, Bytes } from '@graphprotocol/graph-ts'; -import { - createNewTokenRoleChanged, - handleTokenRoleChangedList, - makeEventId, - USER_ONE, - USER_TWO, -} from '../helpers/utils'; -import { TokenRoleChanged } from '../../../generated/FleekNFA/FleekNFA'; - -describe('Token Role Changed tests', () => { - beforeAll(() => { - // Token Role Changed - let tokenRoleChangedList: TokenRoleChanged[] = []; - - tokenRoleChangedList.push( - createNewTokenRoleChanged( - 0, - BigInt.fromI32(0), - 0, - USER_ONE, - true, - USER_TWO - ) // User Two gives User One controller access to TokenId 0 - ); - - tokenRoleChangedList.push( - createNewTokenRoleChanged( - 1, - BigInt.fromI32(1), - 0, - USER_TWO, - true, - USER_ONE - ) // User One gives User Two controller access to TokenId 1 - ); - - tokenRoleChangedList.push( - createNewTokenRoleChanged( - 2, - BigInt.fromI32(0), - 0, - USER_ONE, - false, - USER_TWO - ) // User Two revokes the controller access of User One to tokenId 0 - ); - - handleTokenRoleChangedList(tokenRoleChangedList); - }); - - afterAll(() => { - clearStore(); - }); - - describe('Assertions', () => { - test('Check the `tokenId` field of each TokenRoleChanged event entity', () => { - assert.fieldEquals('TokenRoleChanged', makeEventId(0), 'tokenId', '0'); - assert.fieldEquals('TokenRoleChanged', makeEventId(1), 'tokenId', '1'); - assert.fieldEquals('TokenRoleChanged', makeEventId(2), 'tokenId', '0'); - }); - test('Check the `role` field of each TokenRoleChanged event entity', () => { - assert.fieldEquals('TokenRoleChanged', makeEventId(0), 'role', '0'); - assert.fieldEquals('TokenRoleChanged', makeEventId(1), 'role', '0'); - assert.fieldEquals('TokenRoleChanged', makeEventId(2), 'role', '0'); - }); - - test('Check the `toAddress` field of each TokenRoleChanged event entity', () => { - assert.fieldEquals( - 'TokenRoleChanged', - makeEventId(0), - 'toAddress', - USER_ONE.toString() - ); - assert.fieldEquals( - 'TokenRoleChanged', - makeEventId(1), - 'toAddress', - USER_TWO.toString() - ); - assert.fieldEquals( - 'TokenRoleChanged', - makeEventId(2), - 'toAddress', - USER_ONE.toString() - ); - }); - - test('Check the `byAddress` field of each TokenRoleChanged event entity', () => { - assert.fieldEquals( - 'TokenRoleChanged', - makeEventId(0), - 'byAddress', - USER_TWO.toString() - ); - assert.fieldEquals( - 'TokenRoleChanged', - makeEventId(1), - 'byAddress', - USER_ONE.toString() - ); - assert.fieldEquals( - 'TokenRoleChanged', - makeEventId(2), - 'byAddress', - USER_TWO.toString() - ); - }); - - test('Check the `status` field of each TokenRoleChanged event entity', () => { - assert.fieldEquals('TokenRoleChanged', makeEventId(0), 'status', 'true'); - assert.fieldEquals('TokenRoleChanged', makeEventId(1), 'status', 'true'); - assert.fieldEquals('TokenRoleChanged', makeEventId(2), 'status', 'false'); - }); - }); -}); diff --git a/subgraph/tests/matchstick/access-points/newAccessPoint.test.ts b/subgraph/tests/matchstick/access-points/newAccessPoint.test.ts deleted file mode 100644 index aaaf06c..0000000 --- a/subgraph/tests/matchstick/access-points/newAccessPoint.test.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { - assert, - describe, - test, - clearStore, - beforeAll, - afterAll, -} from 'matchstick-as/assembly/index'; -import { BigInt, Bytes } from '@graphprotocol/graph-ts'; -import { - createNewAccessPointEvent, - handleNewAccessPoints, - makeEventId, - USER_ONE, - USER_TWO, -} from '../helpers/utils'; -import { NewAccessPoint } from '../../../generated/FleekNFA/FleekNFA'; - -describe('New Access Point tests', () => { - beforeAll(() => { - // New Access Points - let newAccessPoints: NewAccessPoint[] = []; - - // User One has two access points: one for tokenId 0 and one for tokenId 1 - newAccessPoints.push( - createNewAccessPointEvent(0, 'firstAP', BigInt.fromI32(0), USER_ONE) - ); - newAccessPoints.push( - createNewAccessPointEvent(1, 'secondAP', BigInt.fromI32(1), USER_ONE) - ); - - // User Two has one access point for tokenId 0 - newAccessPoints.push( - createNewAccessPointEvent(2, 'thirdAP', BigInt.fromI32(0), USER_TWO) - ); - handleNewAccessPoints(newAccessPoints); - }); - - afterAll(() => { - clearStore(); - }); - - describe('Assertions', () => { - test('Check the number of `NewAccessPoint` events to be valid', () => { - assert.entityCount('NewAccessPoint', 3); - }); - - test('Check the `apName` field of each event', () => { - assert.fieldEquals( - 'NewAccessPoint', - makeEventId(0), - 'apName', - 'firstAP'.toString() - ); - assert.fieldEquals( - 'NewAccessPoint', - makeEventId(1), - 'apName', - 'secondAP'.toString() - ); - assert.fieldEquals( - 'NewAccessPoint', - makeEventId(2), - 'apName', - 'thirdAP'.toString() - ); - }); - - test('Check the `tokenId` field of each event', () => { - assert.fieldEquals('NewAccessPoint', makeEventId(0), 'tokenId', '0'); - assert.fieldEquals('NewAccessPoint', makeEventId(1), 'tokenId', '1'); - assert.fieldEquals('NewAccessPoint', makeEventId(2), 'tokenId', '0'); - }); - - test('Check the `owner` field of each event', () => { - assert.fieldEquals( - 'NewAccessPoint', - makeEventId(0), - 'owner', - USER_ONE.toString() - ); - assert.fieldEquals( - 'NewAccessPoint', - makeEventId(1), - 'owner', - USER_ONE.toString() - ); - assert.fieldEquals( - 'NewAccessPoint', - makeEventId(2), - 'owner', - USER_TWO.toString() - ); - }); - - test('check the existence of a nonexistent event in the database', () => { - assert.notInStore('NewAccessPoint', makeEventId(3)); - }); - }); -}); diff --git a/subgraph/tests/matchstick/helpers/utils.ts b/subgraph/tests/matchstick/helpers/utils.ts index 18aaf06..0388d41 100644 --- a/subgraph/tests/matchstick/helpers/utils.ts +++ b/subgraph/tests/matchstick/helpers/utils.ts @@ -10,7 +10,6 @@ import { ChangeAccessPointNameVerify, TokenRoleChanged, CollectionRoleChanged, - TokenRolesCleared, } from '../../../generated/FleekNFA/FleekNFA'; import { handleApproval, @@ -22,7 +21,6 @@ import { handleTransfer, handleTokenRoleChanged, handleCollectionRoleChanged, - handleTokenRolesCleared, } from '../../../src/fleek-nfa'; export function createApprovalEvent( @@ -166,6 +164,9 @@ export function createNewMintEvent( newMintEvent.parameters.push( new ethereum.EventParam('owner', ethereum.Value.fromAddress(to)) ); + newMintEvent.parameters.push( + new ethereum.EventParam('verifier', ethereum.Value.fromAddress(to)) + ); newMintEvent.transaction.hash = Bytes.fromI32(event_count); newMintEvent.logIndex = new BigInt(event_count); @@ -368,32 +369,6 @@ export function createNewCollectionRoleChanged( return collectionRoleChanged; } -export function createNewTokenRolesCleared( - event_count: i32, - tokenId: BigInt, - byAddress: Address -): TokenRolesCleared { - let tokenRolesCleared = changetype(newMockEvent()); - - tokenRolesCleared.parameters = new Array(); - - tokenRolesCleared.parameters.push( - new ethereum.EventParam( - 'tokenId', - ethereum.Value.fromUnsignedBigInt(tokenId) - ) - ); - - tokenRolesCleared.parameters.push( - new ethereum.EventParam('byAddress', ethereum.Value.fromAddress(byAddress)) - ); - - tokenRolesCleared.transaction.hash = Bytes.fromI32(event_count); - tokenRolesCleared.logIndex = new BigInt(event_count); - - return tokenRolesCleared; -} - export const CONTRACT: Address = Address.fromString( '0x0000000000000000000000000000000000000000' ); @@ -467,12 +442,6 @@ export function handleCollectionRoleChangedList( }); } -export function handleTokenRolesClearedList(events: TokenRolesCleared[]): void { - events.forEach((event) => { - handleTokenRolesCleared(event); - }); -} - export function makeEventId(id: i32): string { return Bytes.fromI32(id).toHexString() + '00000000'; }