Skip to content

Commit

Permalink
nft transfer event (#573)
Browse files Browse the repository at this point in the history
* Updating schema

* updating nft.owner with newOwner

* Updating nftOwner in Order

* Fixing tests with nft.owner and nft.creator

* Tracking nft transferHistory

* removing nftOwner from order

* Removing nftOwner test from order

* Updating schema for nftTransferHistory

* Updating tests for transferHistory

* Updating test

* Fixing test

* Fixing timestamp test

* Revert "removing nftOwner from order"

This reverts commit 6f9aae3.

* Reverting removal of nftOwner Test + resolving conflicts
  • Loading branch information
jamiehewitt15 authored Nov 24, 2022
1 parent 6c4fc1c commit 20c27cd
Show file tree
Hide file tree
Showing 10 changed files with 91 additions and 30 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"test": "npm run codegen && npm run lint && npm run type-check",
"test-integration": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/**/*.test.ts'",
"test-dispenser": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/Dispenser.test.ts'",
"test-simple": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/SimplePublishConsume.test.ts'",
"test-simple": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/SimpleSubgraph.test.ts'",
"test-fixed": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/FixedRateExchange.test.ts'",
"test-users": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/users.test.ts'",
"test-ve": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/VeOcean.test.ts'",
Expand Down
20 changes: 17 additions & 3 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ type Nft @entity{
tokenUri: String

"address of the owner of the nft"
owner: String!
owner: User!
"address of the creator of the nft"
creator: String!
creator: User!

"same as id, it's just for easy discoverability"
address: String!
Expand Down Expand Up @@ -115,6 +115,7 @@ type Nft @entity{
hasMetadata: Boolean!

nftData: [NftData!] @derivedFrom(field: "nft")
transferHistory: [NftTransferHistory!] @derivedFrom(field: "nft")
}

type NftData @entity{
Expand Down Expand Up @@ -148,6 +149,7 @@ type Order @entity {
payer: User!
amount: BigDecimal!
serviceIndex: Int!
nftOwner: User!


# the fees will be updated from an event that will be created after (todo)
Expand Down Expand Up @@ -571,4 +573,16 @@ type DFReward @entity {
receiver: User!
availableClaims: [DFAvailableClaim!] @derivedFrom(field: "receiver")
history: [DFHistory!] @derivedFrom(field: "receiver")
}
}

type NftTransferHistory @entity {
# ID = hash(nftAddress+txId+eventNumber)
id: ID!
nft: Nft!
oldOwner: User!
newOwner: User!
txId: String
timestamp: Int!
block: Int!
}

6 changes: 6 additions & 0 deletions src/mappings/erc20Templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ export function handleOrderStarted(event: OrderStarted): void {
const consumer = getUser(event.params.consumer.toHex())
order.consumer = consumer.id

if (token.nft) {
const nft = Nft.load(token.nft as string) as Nft
const nftOwner = getUser(nft.owner)
order.nftOwner = nftOwner.id
}

const payer = getUser(event.params.payer.toHex())
payer.totalOrders = payer.totalOrders.plus(integer.ONE)
payer.save()
Expand Down
15 changes: 14 additions & 1 deletion src/mappings/nftUpdate.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Nft, NftUpdate, NftData } from '../@types/schema'
import { Nft, NftUpdate, NftData, NftTransferHistory } from '../@types/schema'
import {
MetadataCreated,
MetadataState,
Expand Down Expand Up @@ -256,9 +256,22 @@ export function handleCleanedPermissions(event: CleanedPermissions): void {
export function handleNftTransferred(event: Transfer): void {
const id = event.address.toHex()
const nft = getNftTokenWithID(id)
const oldOwner = nft.owner
const newOwner = getUser(event.params.to.toHexString())
nft.owner = newOwner.id
nft.save()

const transferId = `${nft.address}-${event.transaction.hash.toHex()}-${
event.logIndex
}`
const newTransfer = new NftTransferHistory(transferId)
newTransfer.oldOwner = oldOwner
newTransfer.nft = nft.id
newTransfer.newOwner = newOwner.id
newTransfer.txId = event.transaction.hash.toHex()
newTransfer.timestamp = event.block.timestamp.toI32()
newTransfer.block = event.block.number.toI32()
newTransfer.save()
}

export function handleNftData(event: DataChanged): void {
Expand Down
3 changes: 2 additions & 1 deletion test/integration/Datatoken.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ describe('Datatoken tests', async () => {
assert(Number(user2balance) === 0, 'Invalid user2 balance')

const query = {
query: `query {token(id: "${newDtAddress.toLowerCase()}"){id,orderCount,orders {id, lastPriceToken{id}}}}`
query: `query {token(id: "${newDtAddress.toLowerCase()}"){id,orderCount,orders {id, nftOwner{id}, lastPriceToken{id}}}}`
}

await sleep(2000)
Expand Down Expand Up @@ -419,5 +419,6 @@ describe('Datatoken tests', async () => {
assert(token.orderCount === '1', 'Invalid orderCount after order')
assert(token.orders[0].id === orderId)
assert(token.orders[0].lastPriceToken.id === ZERO_ADDRESS)
assert(token.orders[0].nftOwner.id === publisher, 'invalid nftOwner')
})
})
8 changes: 4 additions & 4 deletions test/integration/Dispenser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ describe('Dispenser tests', async () => {
symbol,
name,
tokenUri,
owner,
creator,
owner{id},
creator{id},
address,
providerUrl,
assetState,
Expand All @@ -153,8 +153,8 @@ describe('Dispenser tests', async () => {
assert(nft.symbol === nftSymbol, 'incorrect value for: symbol')
assert(nft.name === nftName, 'incorrect value for: name')
assert(nft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
assert(nft.owner === publisher, 'incorrect value for: owner')
assert(nft.creator === publisher, 'incorrect value for: creator')
assert(nft.owner.id === publisher, 'incorrect value for: owner')
assert(nft.creator.id === publisher, 'incorrect value for: creator')
assert(nft.managerRole[0] === publisher, 'incorrect value for: managerRole')
assert(
nft.erc20DeployerRole[0] === factoryAddress,
Expand Down
8 changes: 4 additions & 4 deletions test/integration/FixedRateExchange.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ describe('Fixed Rate Exchange tests', async () => {
symbol,
name,
tokenUri,
owner,
creator,
owner{id},
creator{id},
address,
providerUrl,
assetState,
Expand All @@ -166,8 +166,8 @@ describe('Fixed Rate Exchange tests', async () => {
assert(nft.symbol === nftSymbol, 'incorrect value for: symbol')
assert(nft.name === nftName, 'incorrect value for: name')
assert(nft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
assert(nft.owner === publisher, 'incorrect value for: owner')
assert(nft.creator === publisher, 'incorrect value for: creator')
assert(nft.owner.id === publisher, 'incorrect value for: owner')
assert(nft.creator.id === publisher, 'incorrect value for: creator')
assert(nft.managerRole[0] === publisher, 'incorrect value for: managerRole')
assert(
nft.erc20DeployerRole[0] === factoryAddress,
Expand Down
16 changes: 8 additions & 8 deletions test/integration/Nft.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ describe('NFT tests', async () => {
symbol,
name,
tokenUri,
owner,
creator,
owner{id},
creator{id},
address,
providerUrl,
assetState,
Expand All @@ -157,8 +157,8 @@ describe('NFT tests', async () => {
assert(nft.symbol === nftSymbol, 'incorrect value for: symbol')
assert(nft.name === nftName, 'incorrect value for: name')
assert(nft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
assert(nft.owner === publisher, 'incorrect value for: owner')
assert(nft.creator === publisher, 'incorrect value for: creator')
assert(nft.owner.id === publisher, 'incorrect value for: owner')
assert(nft.creator.id === publisher, 'incorrect value for: creator')
assert(nft.managerRole[0] === publisher, 'incorrect value for: managerRole')
assert(
nft.erc20DeployerRole[0] === factoryAddress,
Expand Down Expand Up @@ -219,8 +219,8 @@ describe('NFT tests', async () => {
symbol,
name,
tokenUri,
owner,
creator,
owner{id},
creator{id},
address,
providerUrl,
assetState,
Expand All @@ -247,8 +247,8 @@ describe('NFT tests', async () => {
assert(updatedNft.symbol === nftSymbol, 'incorrect value for: symbol')
assert(updatedNft.name === nftName, 'incorrect value for: name')
assert(updatedNft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
assert(updatedNft.owner === publisher, 'incorrect value for: owner')
assert(updatedNft.creator === publisher, 'incorrect value for: creator')
assert(updatedNft.owner.id === publisher, 'incorrect value for: owner')
assert(updatedNft.creator.id === publisher, 'incorrect value for: creator')
assert(
updatedNft.managerRole[0] === publisher,
'incorrect value for: managerRole'
Expand Down
8 changes: 4 additions & 4 deletions test/integration/SimplePublishConsume.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ describe('Simple Publish & consume test', async () => {

const queryOriginalOwner = {
query: `query {
nft(id:"${graphNftToken}"){symbol,id,owner}}`
nft(id:"${graphNftToken}"){symbol,id,owner{id}}}`
}
const initialResponse = await fetch(subgraphUrl, {
method: 'POST',
Expand All @@ -200,7 +200,7 @@ describe('Simple Publish & consume test', async () => {
const initialResult = await initialResponse.json()
// Checking original owner account has been set correctly
assert(
initialResult.data.nft.owner.toLowerCase() ===
initialResult.data.nft.owner.id.toLowerCase() ===
publisherAccount.toLowerCase()
)

Expand Down Expand Up @@ -235,14 +235,14 @@ describe('Simple Publish & consume test', async () => {
await sleep(2000)
const query2 = {
query: `query {
nft(id:"${graphNftToken}"){symbol,id,owner, transferable}}`
nft(id:"${graphNftToken}"){symbol,id,owner{id}, transferable}}`
}
const response = await fetch(subgraphUrl, {
method: 'POST',
body: JSON.stringify(query2)
})
const queryResult = await response.json()
assert(queryResult.data.nft.owner === newOwnerAccount)
assert(queryResult.data.nft.owner.id === newOwnerAccount)
})

it('should save provider fees after startOrder is called', async () => {
Expand Down
35 changes: 31 additions & 4 deletions test/integration/SimpleSubgraph.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,16 @@ describe('Tests coverage without provider/aquarius', async () => {
let accounts: string[]
let publisherAccount: string
let newOwnerAccount: string
let time: number

before(async () => {
nft = new Nft(web3)
Factory = new NftFactory(addresses.ERC721Factory, web3)
accounts = await web3.eth.getAccounts()
publisherAccount = accounts[0]
newOwnerAccount = accounts[1].toLowerCase()
const date = new Date()
time = Math.floor(date.getTime() / 1000)
})

it('should publish a dataset (create NFT + ERC20)', async () => {
Expand Down Expand Up @@ -105,20 +108,44 @@ describe('Tests coverage without provider/aquarius', async () => {
)
await sleep(2000)
const erc721Address = result.events.NFTCreated.returnValues[0]
const graphNftToken = erc721Address.toLowerCase()
const nftAddress = erc721Address.toLowerCase()

// Transfer the NFT
await nft.transferNft(graphNftToken, publisherAccount, newOwnerAccount)
const tx = await nft.transferNft(
nftAddress,
publisherAccount,
newOwnerAccount
)

await sleep(2000)
const query2 = {
query: `query {
nft(id:"${graphNftToken}"){symbol,id,owner, transferable}}`
nft(id:"${nftAddress}"){
symbol,
id,
owner{id},
transferable,
transferHistory(orderBy: timestamp, orderDirection: desc){id,nft,oldOwner,newOwner,txId,timestamp,block}
}}`
}
const response = await fetch(subgraphUrl, {
method: 'POST',
body: JSON.stringify(query2)
})
const queryResult = await response.json()
assert(queryResult.data.nft.owner === newOwnerAccount)
const transferHistory = queryResult.data.nft.transferHistory[0]

assert(queryResult.data.nft.owner.id === newOwnerAccount)
assert(
transferHistory.id ===
`${nftAddress}-${tx.transactionHash}-${tx.events.Transfer.logIndex}`,
'Invalid transferHistory Id'
)
assert(transferHistory.txId === tx.transactionHash, 'invalid txId')
assert(transferHistory.timestamp)

assert(transferHistory.timestamp >= time - 500, 'incorrect value timestamp')
assert(transferHistory.timestamp < time + 500, 'incorrect value timestamp')
assert(transferHistory.block === tx.blockNumber, 'blockNumber')
})
})

0 comments on commit 20c27cd

Please sign in to comment.