123456import privateKey from '../substrate/privateKey';7import { approveExpectSuccess, burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess, transferExpectSuccess, transferFromExpectSuccess } from '../util/helpers';8import { collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents, recordEvents, subToEth, transferBalanceToEth } from './util/helpers';9import { evmToAddress } from '@polkadot/util-crypto';10import nonFungibleAbi from './nonFungibleAbi.json';11import { expect } from 'chai';12import waitNewBlocks from '../substrate/wait-new-blocks';13import { submitTransactionAsync } from '../substrate/substrate-api';1415describe('NFT: Information getting', () => {16 itWeb3('totalSupply', async ({ api, web3 }) => {17 const collection = await createCollectionExpectSuccess({18 mode: { type: 'NFT' },19 });20 const alice = privateKey('//Alice');21 const caller = await createEthAccountWithBalance(api, web3);2223 await createItemExpectSuccess(alice, collection, 'NFT', { substrate: alice.address });2425 const address = collectionIdToAddress(collection);26 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});27 const totalSupply = await contract.methods.totalSupply().call();2829 30 expect(totalSupply).to.equal('0');31 });3233 itWeb3('balanceOf', async ({ api, web3 }) => {34 const collection = await createCollectionExpectSuccess({35 mode: { type: 'NFT' },36 });37 const alice = privateKey('//Alice');3839 const caller = await createEthAccountWithBalance(api, web3);40 await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });41 await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });42 await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });4344 const address = collectionIdToAddress(collection);45 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});46 const balance = await contract.methods.balanceOf(caller).call();4748 expect(balance).to.equal('3');49 });5051 itWeb3('ownerOf', async ({ api, web3 }) => {52 const collection = await createCollectionExpectSuccess({53 mode: { type: 'NFT' },54 });55 const alice = privateKey('//Alice');5657 const caller = await createEthAccountWithBalance(api, web3);58 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });5960 const address = collectionIdToAddress(collection);61 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});62 const owner = await contract.methods.ownerOf(tokenId).call();6364 expect(owner).to.equal(caller);65 });66});6768describe('NFT: Plain calls', () => {69 itWeb3('Can perform mint()', async ({ web3, api }) => {70 const collection = await createCollectionExpectSuccess({71 mode: { type: 'NFT' },72 });73 const alice = privateKey('//Alice');7475 const caller = await createEthAccountWithBalance(api, web3);76 const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, { ethereum: caller });77 await submitTransactionAsync(alice, changeAdminTx);78 const receiver = createEthAccount(web3);7980 const address = collectionIdToAddress(collection);81 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});8283 {84 const nextTokenId = await contract.methods.nextTokenId().call();85 expect(nextTokenId).to.be.equal('1');86 const result = await contract.methods.mintWithTokenURI(87 receiver,88 nextTokenId,89 'Test URI',90 ).send({from: caller});91 const events = normalizeEvents(result.events);9293 expect(events).to.be.deep.equal([94 {95 address,96 event: 'Transfer',97 args: {98 from: '0x0000000000000000000000000000000000000000',99 to: receiver,100 tokenId: nextTokenId,101 },102 },103 ]);104105 await waitNewBlocks(api, 1);106 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');107 }108 });109110 itWeb3('Can perform burn()', async ({ web3, api }) => {111 const collection = await createCollectionExpectSuccess({112 mode: {type: 'NFT'},113 });114 const alice = privateKey('//Alice');115116 const owner = await createEthAccountWithBalance(api, web3);117118 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });119 120 const address = collectionIdToAddress(collection);121 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});122123 {124 const result = await contract.methods.burn(tokenId).send({ from: owner });125 const events = normalizeEvents(result.events);126 127 expect(events).to.be.deep.equal([128 {129 address,130 event: 'Transfer',131 args: {132 from: owner,133 to: '0x0000000000000000000000000000000000000000',134 tokenId: tokenId.toString(),135 },136 },137 ]);138 }139 });140141 itWeb3('Can perform approve()', async ({ web3, api }) => {142 const collection = await createCollectionExpectSuccess({143 mode: { type: 'NFT' },144 });145 const alice = privateKey('//Alice');146147 const owner = createEthAccount(web3);148 await transferBalanceToEth(api, alice, owner, 999999999999999);149150 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });151152 const spender = createEthAccount(web3);153154 const address = collectionIdToAddress(collection);155 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);156157 {158 const result = await contract.methods.approve(spender, tokenId).send({ from: owner, gas: '0x1000000', gasPrice: '0x01' });159 const events = normalizeEvents(result.events);160161 expect(events).to.be.deep.equal([162 {163 address,164 event: 'Approval',165 args: {166 owner,167 approved: spender,168 tokenId: tokenId.toString(),169 },170 },171 ]);172 }173 });174175 itWeb3('Can perform transferFrom()', async ({ web3, api }) => {176 const collection = await createCollectionExpectSuccess({177 mode: { type: 'NFT' },178 });179 const alice = privateKey('//Alice');180181 const owner = createEthAccount(web3);182 await transferBalanceToEth(api, alice, owner, 999999999999999);183184 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });185186 const spender = createEthAccount(web3);187 await transferBalanceToEth(api, alice, spender, 999999999999999);188189 const receiver = createEthAccount(web3);190191 const address = collectionIdToAddress(collection);192 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});193194 await contract.methods.approve(spender, tokenId).send({ from: owner });195196 {197 const result = await contract.methods.transferFrom(owner, receiver, tokenId).send({ from: spender });198 const events = normalizeEvents(result.events);199 expect(events).to.be.deep.equal([200 {201 address,202 event: 'Transfer',203 args: {204 from: owner,205 to: receiver,206 tokenId: tokenId.toString(),207 },208 },209 ]);210 }211212 {213 const balance = await contract.methods.balanceOf(receiver).call();214 expect(+balance).to.equal(1);215 }216217 {218 const balance = await contract.methods.balanceOf(owner).call();219 expect(+balance).to.equal(0);220 }221 });222223 itWeb3('Can perform transfer()', async ({ web3, api }) => {224 const collection = await createCollectionExpectSuccess({225 mode: { type: 'NFT' },226 });227 const alice = privateKey('//Alice');228229 const owner = createEthAccount(web3);230 await transferBalanceToEth(api, alice, owner, 999999999999999);231232 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });233234 const receiver = createEthAccount(web3);235 await transferBalanceToEth(api, alice, receiver, 999999999999999);236237 const address = collectionIdToAddress(collection);238 const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});239240 {241 const result = await contract.methods.transfer(receiver, tokenId).send({ from: owner });242 await waitNewBlocks(api, 1);243 const events = normalizeEvents(result.events);244 expect(events).to.be.deep.equal([245 {246 address,247 event: 'Transfer',248 args: {249 from: owner,250 to: receiver,251 tokenId: tokenId.toString(),252 },253 },254 ]);255 }256257 {258 const balance = await contract.methods.balanceOf(owner).call();259 expect(+balance).to.equal(0);260 }261262 {263 const balance = await contract.methods.balanceOf(receiver).call();264 expect(+balance).to.equal(1);265 }266 });267});268269describe('NFT: Substrate calls', () => {270 itWeb3('Events emitted for mint()', async ({ web3 }) => {271 const collection = await createCollectionExpectSuccess({272 mode: { type: 'NFT' },273 });274 const alice = privateKey('//Alice');275276 const address = collectionIdToAddress(collection);277 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);278279 let tokenId: number;280 const events = await recordEvents(contract, async () => {281 tokenId = await createItemExpectSuccess(alice, collection, 'NFT');282 });283284 expect(events).to.be.deep.equal([285 {286 address,287 event: 'Transfer',288 args: {289 from: '0x0000000000000000000000000000000000000000',290 to: subToEth(alice.address),291 tokenId: tokenId!.toString(),292 },293 },294 ]);295 });296297 itWeb3('Events emitted for burn()', async ({ web3 }) => {298 const collection = await createCollectionExpectSuccess({299 mode: { type: 'NFT' },300 });301 const alice = privateKey('//Alice');302303 const address = collectionIdToAddress(collection);304 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);305306 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');307 const events = await recordEvents(contract, async () => {308 await burnItemExpectSuccess(alice, collection, tokenId);309 });310311 expect(events).to.be.deep.equal([312 {313 address,314 event: 'Transfer',315 args: {316 from: subToEth(alice.address),317 to: '0x0000000000000000000000000000000000000000',318 tokenId: tokenId.toString(),319 },320 },321 ]);322 });323324 itWeb3('Events emitted for approve()', async ({ web3 }) => {325 const collection = await createCollectionExpectSuccess({326 mode: { type: 'NFT' },327 });328 const alice = privateKey('//Alice');329330 const receiver = createEthAccount(web3);331332 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');333334 const address = collectionIdToAddress(collection);335 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);336337 const events = await recordEvents(contract, async () => {338 await approveExpectSuccess(collection, tokenId, alice, { ethereum: receiver }, 1);339 });340341 expect(events).to.be.deep.equal([342 {343 address,344 event: 'Approval',345 args: {346 owner: subToEth(alice.address),347 approved: receiver,348 tokenId: tokenId.toString(),349 },350 },351 ]);352 });353354 itWeb3('Events emitted for transferFrom()', async ({ web3 }) => {355 const collection = await createCollectionExpectSuccess({356 mode: { type: 'NFT' },357 });358 const alice = privateKey('//Alice');359 const bob = privateKey('//Bob');360361 const receiver = createEthAccount(web3);362363 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');364 await approveExpectSuccess(collection, tokenId, alice, bob, 1);365366 const address = collectionIdToAddress(collection);367 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);368369 const events = await recordEvents(contract, async () => {370 await transferFromExpectSuccess(collection, tokenId, bob, alice, { ethereum: receiver }, 1, 'NFT');371 });372373 expect(events).to.be.deep.equal([374 {375 address,376 event: 'Transfer',377 args: {378 from: subToEth(alice.address),379 to: receiver,380 tokenId: tokenId.toString(),381 },382 },383 ]);384 });385386 itWeb3('Events emitted for transfer()', async ({ web3 }) => {387 const collection = await createCollectionExpectSuccess({388 mode: { type: 'NFT' },389 });390 const alice = privateKey('//Alice');391392 const receiver = createEthAccount(web3);393394 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT');395396 const address = collectionIdToAddress(collection);397 const contract = new web3.eth.Contract(nonFungibleAbi as any, address);398399 const events = await recordEvents(contract, async () => {400 await transferExpectSuccess(collection, tokenId, alice, { ethereum: receiver }, 1, 'NFT');401 });402403 expect(events).to.be.deep.equal([404 {405 address,406 event: 'Transfer',407 args: {408 from: subToEth(alice.address),409 to: receiver,410 tokenId: tokenId.toString(),411 },412 },413 ]);414 });415});