mirror of
https://github.com/oceanprotocol/ocean-subgraph.git
synced 2024-12-02 05:57:29 +01:00
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:
parent
6c4fc1c346
commit
20c27cd521
@ -26,7 +26,7 @@
|
|||||||
"test": "npm run codegen && npm run lint && npm run type-check",
|
"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-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-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-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-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'",
|
"test-ve": "TS_NODE_PROJECT='test/integration/tsconfig.json' mocha --config=test/integration/.mocharc.json --node-env=test --exit 'test/integration/VeOcean.test.ts'",
|
||||||
|
@ -76,9 +76,9 @@ type Nft @entity{
|
|||||||
tokenUri: String
|
tokenUri: String
|
||||||
|
|
||||||
"address of the owner of the nft"
|
"address of the owner of the nft"
|
||||||
owner: String!
|
owner: User!
|
||||||
"address of the creator of the nft"
|
"address of the creator of the nft"
|
||||||
creator: String!
|
creator: User!
|
||||||
|
|
||||||
"same as id, it's just for easy discoverability"
|
"same as id, it's just for easy discoverability"
|
||||||
address: String!
|
address: String!
|
||||||
@ -115,6 +115,7 @@ type Nft @entity{
|
|||||||
hasMetadata: Boolean!
|
hasMetadata: Boolean!
|
||||||
|
|
||||||
nftData: [NftData!] @derivedFrom(field: "nft")
|
nftData: [NftData!] @derivedFrom(field: "nft")
|
||||||
|
transferHistory: [NftTransferHistory!] @derivedFrom(field: "nft")
|
||||||
}
|
}
|
||||||
|
|
||||||
type NftData @entity{
|
type NftData @entity{
|
||||||
@ -148,6 +149,7 @@ type Order @entity {
|
|||||||
payer: User!
|
payer: User!
|
||||||
amount: BigDecimal!
|
amount: BigDecimal!
|
||||||
serviceIndex: Int!
|
serviceIndex: Int!
|
||||||
|
nftOwner: User!
|
||||||
|
|
||||||
|
|
||||||
# the fees will be updated from an event that will be created after (todo)
|
# the fees will be updated from an event that will be created after (todo)
|
||||||
@ -571,4 +573,16 @@ type DFReward @entity {
|
|||||||
receiver: User!
|
receiver: User!
|
||||||
availableClaims: [DFAvailableClaim!] @derivedFrom(field: "receiver")
|
availableClaims: [DFAvailableClaim!] @derivedFrom(field: "receiver")
|
||||||
history: [DFHistory!] @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!
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,12 @@ export function handleOrderStarted(event: OrderStarted): void {
|
|||||||
const consumer = getUser(event.params.consumer.toHex())
|
const consumer = getUser(event.params.consumer.toHex())
|
||||||
order.consumer = consumer.id
|
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())
|
const payer = getUser(event.params.payer.toHex())
|
||||||
payer.totalOrders = payer.totalOrders.plus(integer.ONE)
|
payer.totalOrders = payer.totalOrders.plus(integer.ONE)
|
||||||
payer.save()
|
payer.save()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Nft, NftUpdate, NftData } from '../@types/schema'
|
import { Nft, NftUpdate, NftData, NftTransferHistory } from '../@types/schema'
|
||||||
import {
|
import {
|
||||||
MetadataCreated,
|
MetadataCreated,
|
||||||
MetadataState,
|
MetadataState,
|
||||||
@ -256,9 +256,22 @@ export function handleCleanedPermissions(event: CleanedPermissions): void {
|
|||||||
export function handleNftTransferred(event: Transfer): void {
|
export function handleNftTransferred(event: Transfer): void {
|
||||||
const id = event.address.toHex()
|
const id = event.address.toHex()
|
||||||
const nft = getNftTokenWithID(id)
|
const nft = getNftTokenWithID(id)
|
||||||
|
const oldOwner = nft.owner
|
||||||
const newOwner = getUser(event.params.to.toHexString())
|
const newOwner = getUser(event.params.to.toHexString())
|
||||||
nft.owner = newOwner.id
|
nft.owner = newOwner.id
|
||||||
nft.save()
|
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 {
|
export function handleNftData(event: DataChanged): void {
|
||||||
|
@ -358,7 +358,7 @@ describe('Datatoken tests', async () => {
|
|||||||
assert(Number(user2balance) === 0, 'Invalid user2 balance')
|
assert(Number(user2balance) === 0, 'Invalid user2 balance')
|
||||||
|
|
||||||
const query = {
|
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)
|
await sleep(2000)
|
||||||
@ -419,5 +419,6 @@ describe('Datatoken tests', async () => {
|
|||||||
assert(token.orderCount === '1', 'Invalid orderCount after order')
|
assert(token.orderCount === '1', 'Invalid orderCount after order')
|
||||||
assert(token.orders[0].id === orderId)
|
assert(token.orders[0].id === orderId)
|
||||||
assert(token.orders[0].lastPriceToken.id === ZERO_ADDRESS)
|
assert(token.orders[0].lastPriceToken.id === ZERO_ADDRESS)
|
||||||
|
assert(token.orders[0].nftOwner.id === publisher, 'invalid nftOwner')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -125,8 +125,8 @@ describe('Dispenser tests', async () => {
|
|||||||
symbol,
|
symbol,
|
||||||
name,
|
name,
|
||||||
tokenUri,
|
tokenUri,
|
||||||
owner,
|
owner{id},
|
||||||
creator,
|
creator{id},
|
||||||
address,
|
address,
|
||||||
providerUrl,
|
providerUrl,
|
||||||
assetState,
|
assetState,
|
||||||
@ -153,8 +153,8 @@ describe('Dispenser tests', async () => {
|
|||||||
assert(nft.symbol === nftSymbol, 'incorrect value for: symbol')
|
assert(nft.symbol === nftSymbol, 'incorrect value for: symbol')
|
||||||
assert(nft.name === nftName, 'incorrect value for: name')
|
assert(nft.name === nftName, 'incorrect value for: name')
|
||||||
assert(nft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
|
assert(nft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
|
||||||
assert(nft.owner === publisher, 'incorrect value for: owner')
|
assert(nft.owner.id === publisher, 'incorrect value for: owner')
|
||||||
assert(nft.creator === publisher, 'incorrect value for: creator')
|
assert(nft.creator.id === publisher, 'incorrect value for: creator')
|
||||||
assert(nft.managerRole[0] === publisher, 'incorrect value for: managerRole')
|
assert(nft.managerRole[0] === publisher, 'incorrect value for: managerRole')
|
||||||
assert(
|
assert(
|
||||||
nft.erc20DeployerRole[0] === factoryAddress,
|
nft.erc20DeployerRole[0] === factoryAddress,
|
||||||
|
@ -138,8 +138,8 @@ describe('Fixed Rate Exchange tests', async () => {
|
|||||||
symbol,
|
symbol,
|
||||||
name,
|
name,
|
||||||
tokenUri,
|
tokenUri,
|
||||||
owner,
|
owner{id},
|
||||||
creator,
|
creator{id},
|
||||||
address,
|
address,
|
||||||
providerUrl,
|
providerUrl,
|
||||||
assetState,
|
assetState,
|
||||||
@ -166,8 +166,8 @@ describe('Fixed Rate Exchange tests', async () => {
|
|||||||
assert(nft.symbol === nftSymbol, 'incorrect value for: symbol')
|
assert(nft.symbol === nftSymbol, 'incorrect value for: symbol')
|
||||||
assert(nft.name === nftName, 'incorrect value for: name')
|
assert(nft.name === nftName, 'incorrect value for: name')
|
||||||
assert(nft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
|
assert(nft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
|
||||||
assert(nft.owner === publisher, 'incorrect value for: owner')
|
assert(nft.owner.id === publisher, 'incorrect value for: owner')
|
||||||
assert(nft.creator === publisher, 'incorrect value for: creator')
|
assert(nft.creator.id === publisher, 'incorrect value for: creator')
|
||||||
assert(nft.managerRole[0] === publisher, 'incorrect value for: managerRole')
|
assert(nft.managerRole[0] === publisher, 'incorrect value for: managerRole')
|
||||||
assert(
|
assert(
|
||||||
nft.erc20DeployerRole[0] === factoryAddress,
|
nft.erc20DeployerRole[0] === factoryAddress,
|
||||||
|
@ -130,8 +130,8 @@ describe('NFT tests', async () => {
|
|||||||
symbol,
|
symbol,
|
||||||
name,
|
name,
|
||||||
tokenUri,
|
tokenUri,
|
||||||
owner,
|
owner{id},
|
||||||
creator,
|
creator{id},
|
||||||
address,
|
address,
|
||||||
providerUrl,
|
providerUrl,
|
||||||
assetState,
|
assetState,
|
||||||
@ -157,8 +157,8 @@ describe('NFT tests', async () => {
|
|||||||
assert(nft.symbol === nftSymbol, 'incorrect value for: symbol')
|
assert(nft.symbol === nftSymbol, 'incorrect value for: symbol')
|
||||||
assert(nft.name === nftName, 'incorrect value for: name')
|
assert(nft.name === nftName, 'incorrect value for: name')
|
||||||
assert(nft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
|
assert(nft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
|
||||||
assert(nft.owner === publisher, 'incorrect value for: owner')
|
assert(nft.owner.id === publisher, 'incorrect value for: owner')
|
||||||
assert(nft.creator === publisher, 'incorrect value for: creator')
|
assert(nft.creator.id === publisher, 'incorrect value for: creator')
|
||||||
assert(nft.managerRole[0] === publisher, 'incorrect value for: managerRole')
|
assert(nft.managerRole[0] === publisher, 'incorrect value for: managerRole')
|
||||||
assert(
|
assert(
|
||||||
nft.erc20DeployerRole[0] === factoryAddress,
|
nft.erc20DeployerRole[0] === factoryAddress,
|
||||||
@ -219,8 +219,8 @@ describe('NFT tests', async () => {
|
|||||||
symbol,
|
symbol,
|
||||||
name,
|
name,
|
||||||
tokenUri,
|
tokenUri,
|
||||||
owner,
|
owner{id},
|
||||||
creator,
|
creator{id},
|
||||||
address,
|
address,
|
||||||
providerUrl,
|
providerUrl,
|
||||||
assetState,
|
assetState,
|
||||||
@ -247,8 +247,8 @@ describe('NFT tests', async () => {
|
|||||||
assert(updatedNft.symbol === nftSymbol, 'incorrect value for: symbol')
|
assert(updatedNft.symbol === nftSymbol, 'incorrect value for: symbol')
|
||||||
assert(updatedNft.name === nftName, 'incorrect value for: name')
|
assert(updatedNft.name === nftName, 'incorrect value for: name')
|
||||||
assert(updatedNft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
|
assert(updatedNft.tokenUri === tokenURI, 'incorrect value for: tokenUri')
|
||||||
assert(updatedNft.owner === publisher, 'incorrect value for: owner')
|
assert(updatedNft.owner.id === publisher, 'incorrect value for: owner')
|
||||||
assert(updatedNft.creator === publisher, 'incorrect value for: creator')
|
assert(updatedNft.creator.id === publisher, 'incorrect value for: creator')
|
||||||
assert(
|
assert(
|
||||||
updatedNft.managerRole[0] === publisher,
|
updatedNft.managerRole[0] === publisher,
|
||||||
'incorrect value for: managerRole'
|
'incorrect value for: managerRole'
|
||||||
|
@ -191,7 +191,7 @@ describe('Simple Publish & consume test', async () => {
|
|||||||
|
|
||||||
const queryOriginalOwner = {
|
const queryOriginalOwner = {
|
||||||
query: `query {
|
query: `query {
|
||||||
nft(id:"${graphNftToken}"){symbol,id,owner}}`
|
nft(id:"${graphNftToken}"){symbol,id,owner{id}}}`
|
||||||
}
|
}
|
||||||
const initialResponse = await fetch(subgraphUrl, {
|
const initialResponse = await fetch(subgraphUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -200,7 +200,7 @@ describe('Simple Publish & consume test', async () => {
|
|||||||
const initialResult = await initialResponse.json()
|
const initialResult = await initialResponse.json()
|
||||||
// Checking original owner account has been set correctly
|
// Checking original owner account has been set correctly
|
||||||
assert(
|
assert(
|
||||||
initialResult.data.nft.owner.toLowerCase() ===
|
initialResult.data.nft.owner.id.toLowerCase() ===
|
||||||
publisherAccount.toLowerCase()
|
publisherAccount.toLowerCase()
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -235,14 +235,14 @@ describe('Simple Publish & consume test', async () => {
|
|||||||
await sleep(2000)
|
await sleep(2000)
|
||||||
const query2 = {
|
const query2 = {
|
||||||
query: `query {
|
query: `query {
|
||||||
nft(id:"${graphNftToken}"){symbol,id,owner, transferable}}`
|
nft(id:"${graphNftToken}"){symbol,id,owner{id}, transferable}}`
|
||||||
}
|
}
|
||||||
const response = await fetch(subgraphUrl, {
|
const response = await fetch(subgraphUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(query2)
|
body: JSON.stringify(query2)
|
||||||
})
|
})
|
||||||
const queryResult = await response.json()
|
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 () => {
|
it('should save provider fees after startOrder is called', async () => {
|
||||||
|
@ -31,6 +31,7 @@ describe('Tests coverage without provider/aquarius', async () => {
|
|||||||
let accounts: string[]
|
let accounts: string[]
|
||||||
let publisherAccount: string
|
let publisherAccount: string
|
||||||
let newOwnerAccount: string
|
let newOwnerAccount: string
|
||||||
|
let time: number
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
nft = new Nft(web3)
|
nft = new Nft(web3)
|
||||||
@ -38,6 +39,8 @@ describe('Tests coverage without provider/aquarius', async () => {
|
|||||||
accounts = await web3.eth.getAccounts()
|
accounts = await web3.eth.getAccounts()
|
||||||
publisherAccount = accounts[0]
|
publisherAccount = accounts[0]
|
||||||
newOwnerAccount = accounts[1].toLowerCase()
|
newOwnerAccount = accounts[1].toLowerCase()
|
||||||
|
const date = new Date()
|
||||||
|
time = Math.floor(date.getTime() / 1000)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should publish a dataset (create NFT + ERC20)', async () => {
|
it('should publish a dataset (create NFT + ERC20)', async () => {
|
||||||
@ -105,20 +108,44 @@ describe('Tests coverage without provider/aquarius', async () => {
|
|||||||
)
|
)
|
||||||
await sleep(2000)
|
await sleep(2000)
|
||||||
const erc721Address = result.events.NFTCreated.returnValues[0]
|
const erc721Address = result.events.NFTCreated.returnValues[0]
|
||||||
const graphNftToken = erc721Address.toLowerCase()
|
const nftAddress = erc721Address.toLowerCase()
|
||||||
|
|
||||||
// Transfer the NFT
|
// Transfer the NFT
|
||||||
await nft.transferNft(graphNftToken, publisherAccount, newOwnerAccount)
|
const tx = await nft.transferNft(
|
||||||
|
nftAddress,
|
||||||
|
publisherAccount,
|
||||||
|
newOwnerAccount
|
||||||
|
)
|
||||||
|
|
||||||
await sleep(2000)
|
await sleep(2000)
|
||||||
const query2 = {
|
const query2 = {
|
||||||
query: `query {
|
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, {
|
const response = await fetch(subgraphUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify(query2)
|
body: JSON.stringify(query2)
|
||||||
})
|
})
|
||||||
const queryResult = await response.json()
|
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')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user