1234567891011121314151617import {createCollectionExpectSuccess, createItemExpectSuccess} from '../../util/helpers';18import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents} from '../util/helpers';19import nonFungibleAbi from '../nonFungibleAbi.json';20import {expect} from 'chai';21import {submitTransactionAsync} from '../../substrate/substrate-api';22import Web3 from 'web3';23import {readFile} from 'fs/promises';24import {ApiPromise} from '@polkadot/api';2526async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any) {27 28 const owner = await createEthAccountWithBalance(api, web3);29 const proxyContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueNFTProxy.abi`)).toString()), undefined, {30 from: owner,31 ...GAS_ARGS,32 });33 const proxy = await proxyContract.deploy({data: (await readFile(`${__dirname}/UniqueNFTProxy.bin`)).toString(), arguments: [wrapped.options.address]}).send({from: owner});34 return proxy;35}3637describe('NFT (Via EVM proxy): Information getting', () => {38 itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => {39 const collection = await createCollectionExpectSuccess({40 mode: {type: 'NFT'},41 });42 const alice = privateKeyWrapper('//Alice');43 const caller = await createEthAccountWithBalance(api, web3);4445 await createItemExpectSuccess(alice, collection, 'NFT', {Substrate: alice.address});4647 const address = collectionIdToAddress(collection);48 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));49 const totalSupply = await contract.methods.totalSupply().call();5051 expect(totalSupply).to.equal('1');52 });5354 itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => {55 const collection = await createCollectionExpectSuccess({56 mode: {type: 'NFT'},57 });58 const alice = privateKeyWrapper('//Alice');5960 const caller = await createEthAccountWithBalance(api, web3);61 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});62 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});63 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});6465 const address = collectionIdToAddress(collection);66 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));67 const balance = await contract.methods.balanceOf(caller).call();6869 expect(balance).to.equal('3');70 });7172 itWeb3('ownerOf', async ({api, web3, privateKeyWrapper}) => {73 const collection = await createCollectionExpectSuccess({74 mode: {type: 'NFT'},75 });76 const alice = privateKeyWrapper('//Alice');7778 const caller = await createEthAccountWithBalance(api, web3);79 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});8081 const address = collectionIdToAddress(collection);82 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));83 const owner = await contract.methods.ownerOf(tokenId).call();8485 expect(owner).to.equal(caller);86 });87});8889describe('NFT (Via EVM proxy): Plain calls', () => {90 itWeb3('Can perform mint()', async ({web3, api}) => {91 const owner = await createEthAccountWithBalance(api, web3);92 const collectionHelper = evmCollectionHelpers(web3, owner);93 const result = await collectionHelper.methods94 .createNonfungibleCollection('A', 'A', 'A')95 .send();96 const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);97 const caller = await createEthAccountWithBalance(api, web3);98 const receiver = createEthAccount(web3);99 const collectionEvmOwned = evmCollection(web3, owner, collectionIdAddress);100 const collectionEvm = evmCollection(web3, caller, collectionIdAddress);101 const contract = await proxyWrap(api, web3, collectionEvm);102 await collectionEvmOwned.methods.addAdmin(contract.options.address).send();103104 {105 const nextTokenId = await contract.methods.nextTokenId().call();106 expect(nextTokenId).to.be.equal('1');107 const result = await contract.methods.mintWithTokenURI(108 receiver,109 nextTokenId,110 'Test URI',111 ).send({from: caller});112 const events = normalizeEvents(result.events);113 events[0].address = events[0].address.toLocaleLowerCase();114115 expect(events).to.be.deep.equal([116 {117 address: collectionIdAddress.toLocaleLowerCase(),118 event: 'Transfer',119 args: {120 from: '0x0000000000000000000000000000000000000000',121 to: receiver,122 tokenId: nextTokenId,123 },124 },125 ]);126127 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');128 }129 });130 131 132 itWeb3.skip('Can perform mintBulk()', async ({web3, api, privateKeyWrapper}) => {133 const collection = await createCollectionExpectSuccess({134 mode: {type: 'NFT'},135 });136 const alice = privateKeyWrapper('//Alice');137138 const caller = await createEthAccountWithBalance(api, web3);139 const receiver = createEthAccount(web3);140141 const address = collectionIdToAddress(collection);142 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));143 const changeAdminTx = api.tx.unique.addCollectionAdmin(collection, {Ethereum: contract.options.address});144 await submitTransactionAsync(alice, changeAdminTx);145146 {147 const nextTokenId = await contract.methods.nextTokenId().call();148 expect(nextTokenId).to.be.equal('1');149 const result = await contract.methods.mintBulkWithTokenURI(150 receiver,151 [152 [nextTokenId, 'Test URI 0'],153 [+nextTokenId + 1, 'Test URI 1'],154 [+nextTokenId + 2, 'Test URI 2'],155 ],156 ).send({from: caller});157 const events = normalizeEvents(result.events);158159 expect(events).to.be.deep.equal([160 {161 address,162 event: 'Transfer',163 args: {164 from: '0x0000000000000000000000000000000000000000',165 to: receiver,166 tokenId: nextTokenId,167 },168 },169 {170 address,171 event: 'Transfer',172 args: {173 from: '0x0000000000000000000000000000000000000000',174 to: receiver,175 tokenId: String(+nextTokenId + 1),176 },177 },178 {179 address,180 event: 'Transfer',181 args: {182 from: '0x0000000000000000000000000000000000000000',183 to: receiver,184 tokenId: String(+nextTokenId + 2),185 },186 },187 ]);188189 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI 0');190 expect(await contract.methods.tokenURI(+nextTokenId + 1).call()).to.be.equal('Test URI 1');191 expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');192 }193 });194195 itWeb3('Can perform burn()', async ({web3, api, privateKeyWrapper}) => {196 const collection = await createCollectionExpectSuccess({197 mode: {type: 'NFT'},198 });199 const alice = privateKeyWrapper('//Alice');200 const caller = await createEthAccountWithBalance(api, web3);201202 const address = collectionIdToAddress(collection);203 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));204 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});205206 const changeAdminTx = api.tx.unique.addCollectionAdmin(collection, {Ethereum: contract.options.address});207 await submitTransactionAsync(alice, changeAdminTx);208209 {210 const result = await contract.methods.burn(tokenId).send({from: caller});211 const events = normalizeEvents(result.events);212213 expect(events).to.be.deep.equal([214 {215 address,216 event: 'Transfer',217 args: {218 from: contract.options.address,219 to: '0x0000000000000000000000000000000000000000',220 tokenId: tokenId.toString(),221 },222 },223 ]);224 }225 });226227 itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => {228 const collection = await createCollectionExpectSuccess({229 mode: {type: 'NFT'},230 });231 const alice = privateKeyWrapper('//Alice');232 const caller = await createEthAccountWithBalance(api, web3);233 const spender = createEthAccount(web3);234235 const address = collectionIdToAddress(collection);236 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address));237 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});238239 {240 const result = await contract.methods.approve(spender, tokenId).send({from: caller, ...GAS_ARGS});241 const events = normalizeEvents(result.events);242243 expect(events).to.be.deep.equal([244 {245 address,246 event: 'Approval',247 args: {248 owner: contract.options.address,249 approved: spender,250 tokenId: tokenId.toString(),251 },252 },253 ]);254 }255 });256257 itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => {258 const collection = await createCollectionExpectSuccess({259 mode: {type: 'NFT'},260 });261 const alice = privateKeyWrapper('//Alice');262 const caller = await createEthAccountWithBalance(api, web3);263 const owner = await createEthAccountWithBalance(api, web3);264265 const receiver = createEthAccount(web3);266267 const address = collectionIdToAddress(collection);268 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});269 const contract = await proxyWrap(api, web3, evmCollection);270 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});271272 await evmCollection.methods.approve(contract.options.address, tokenId).send({from: owner});273274 {275 const result = await contract.methods.transferFrom(owner, receiver, tokenId).send({from: caller});276 const events = normalizeEvents(result.events);277 expect(events).to.be.deep.equal([278 {279 address,280 event: 'Transfer',281 args: {282 from: owner,283 to: receiver,284 tokenId: tokenId.toString(),285 },286 },287 ]);288 }289290 {291 const balance = await contract.methods.balanceOf(receiver).call();292 expect(+balance).to.equal(1);293 }294295 {296 const balance = await contract.methods.balanceOf(contract.options.address).call();297 expect(+balance).to.equal(0);298 }299 });300301 itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => {302 const collection = await createCollectionExpectSuccess({303 mode: {type: 'NFT'},304 });305 const alice = privateKeyWrapper('//Alice');306 const caller = await createEthAccountWithBalance(api, web3);307 const receiver = createEthAccount(web3);308309 const address = collectionIdToAddress(collection);310 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));311 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});312313 {314 const result = await contract.methods.transfer(receiver, tokenId).send({from: caller});315 const events = normalizeEvents(result.events);316 expect(events).to.be.deep.equal([317 {318 address,319 event: 'Transfer',320 args: {321 from: contract.options.address,322 to: receiver,323 tokenId: tokenId.toString(),324 },325 },326 ]);327 }328329 {330 const balance = await contract.methods.balanceOf(contract.options.address).call();331 expect(+balance).to.equal(0);332 }333334 {335 const balance = await contract.methods.balanceOf(receiver).call();336 expect(+balance).to.equal(1);337 }338 });339});