nft transfer event (#573)

* 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 6f9aae3c40.

* Reverting removal of nftOwner Test + resolving conflicts
This commit is contained in:
Jamie Hewitt 2022-11-24 16:40:31 +03:00 committed by GitHub
parent 6c4fc1c346
commit 20c27cd521
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 91 additions and 30 deletions

View File

@ -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'",

View File

@ -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!
@ -115,6 +115,7 @@ type Nft @entity{
hasMetadata: Boolean!
nftData: [NftData!] @derivedFrom(field: "nft")
transferHistory: [NftTransferHistory!] @derivedFrom(field: "nft")
}
type NftData @entity{
@ -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)
@ -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!
}

View File

@ -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()

View File

@ -1,4 +1,4 @@
import { Nft, NftUpdate, NftData } from '../@types/schema'
import { Nft, NftUpdate, NftData, NftTransferHistory } from '../@types/schema'
import {
MetadataCreated,
MetadataState,
@ -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 {

View File

@ -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)
@ -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')
})
})

View File

@ -125,8 +125,8 @@ describe('Dispenser tests', async () => {
symbol,
name,
tokenUri,
owner,
creator,
owner{id},
creator{id},
address,
providerUrl,
assetState,
@ -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,

View File

@ -138,8 +138,8 @@ describe('Fixed Rate Exchange tests', async () => {
symbol,
name,
tokenUri,
owner,
creator,
owner{id},
creator{id},
address,
providerUrl,
assetState,
@ -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,

View File

@ -130,8 +130,8 @@ describe('NFT tests', async () => {
symbol,
name,
tokenUri,
owner,
creator,
owner{id},
creator{id},
address,
providerUrl,
assetState,
@ -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,
@ -219,8 +219,8 @@ describe('NFT tests', async () => {
symbol,
name,
tokenUri,
owner,
creator,
owner{id},
creator{id},
address,
providerUrl,
assetState,
@ -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'

View File

@ -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',
@ -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()
)
@ -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 () => {

View File

@ -31,6 +31,7 @@ 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)
@ -38,6 +39,8 @@ describe('Tests coverage without provider/aquarius', async () => {
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 () => {
@ -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')
})
})