123456import privateKey from '../../substrate/privateKey';7import { createCollectionExpectSuccess, createItemExpectSuccess } from '../../util/helpers';8import { collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents } from '../util/helpers';9import nonFungibleAbi from '../nonFungibleAbi.json';10import { expect } from 'chai';11import waitNewBlocks from '../../substrate/wait-new-blocks';12import { submitTransactionAsync } from '../../substrate/substrate-api';13import Web3 from 'web3';14import { readFile } from 'fs/promises';15import { ApiPromise } from '@polkadot/api';1617async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any) {18 19 const owner = await createEthAccountWithBalance(api, web3);20 const Proxy = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueNFTProxy.abi`)).toString()), undefined, {21 from: owner,22 ...GAS_ARGS,23 });24 const proxy = await Proxy.deploy({ data: (await readFile(`${__dirname}/UniqueNFTProxy.bin`)).toString(), arguments: [wrapped.options.address] }).send({ from: owner });25 return proxy;26}2728describe('NFT (Via EVM proxy): Information getting', () => {29 itWeb3('totalSupply', async ({ api, web3 }) => {30 const collection = await createCollectionExpectSuccess({31 mode: { type: 'NFT' },32 });33 const alice = privateKey('//Alice');34 const caller = await createEthAccountWithBalance(api, web3);3536 await createItemExpectSuccess(alice, collection, 'NFT', { substrate: alice.address });3738 const address = collectionIdToAddress(collection);39 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));40 const totalSupply = await contract.methods.totalSupply().call();4142 43 expect(totalSupply).to.equal('0');44 });4546 itWeb3('balanceOf', async ({ api, web3 }) => {47 const collection = await createCollectionExpectSuccess({48 mode: { type: 'NFT' },49 });50 const alice = privateKey('//Alice');5152 const caller = await createEthAccountWithBalance(api, web3);53 await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });54 await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });55 await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });5657 const address = collectionIdToAddress(collection);58 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));59 const balance = await contract.methods.balanceOf(caller).call();6061 expect(balance).to.equal('3');62 });6364 itWeb3('ownerOf', async ({ api, web3 }) => {65 const collection = await createCollectionExpectSuccess({66 mode: { type: 'NFT' },67 });68 const alice = privateKey('//Alice');6970 const caller = await createEthAccountWithBalance(api, web3);71 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: caller });7273 const address = collectionIdToAddress(collection);74 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));75 const owner = await contract.methods.ownerOf(tokenId).call();7677 expect(owner).to.equal(caller);78 });79});8081describe('NFT (Via EVM proxy): Plain calls', () => {82 itWeb3('Can perform mint()', async ({ web3, api }) => {83 const collection = await createCollectionExpectSuccess({84 mode: { type: 'NFT' },85 });86 const alice = privateKey('//Alice');87 const caller = await createEthAccountWithBalance(api, web3);88 const receiver = createEthAccount(web3);8990 const address = collectionIdToAddress(collection);91 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, { from: caller, ...GAS_ARGS }));9293 const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, { ethereum: contract.options.address });94 await submitTransactionAsync(alice, changeAdminTx);9596 {97 const nextTokenId = await contract.methods.nextTokenId().call();98 expect(nextTokenId).to.be.equal('1');99 console.log('Before mint');100 const result = await contract.methods.mintWithTokenURI(101 receiver,102 nextTokenId,103 'Test URI',104 ).send({ from: caller });105 console.log('After mint');106 const events = normalizeEvents(result.events);107108 expect(events).to.be.deep.equal([109 {110 address,111 event: 'Transfer',112 args: {113 from: '0x0000000000000000000000000000000000000000',114 to: receiver,115 tokenId: nextTokenId,116 },117 },118 ]);119120 await waitNewBlocks(api, 1);121 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');122 }123 });124125 itWeb3('Can perform burn()', async ({ web3, api }) => {126 const collection = await createCollectionExpectSuccess({127 mode: {type: 'NFT'},128 });129 const alice = privateKey('//Alice');130 const caller = await createEthAccountWithBalance(api, web3);131 132 const address = collectionIdToAddress(collection);133 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));134 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: contract.options.address });135136 const changeAdminTx = api.tx.nft.addCollectionAdmin(collection, { ethereum: contract.options.address });137 await submitTransactionAsync(alice, changeAdminTx);138139 {140 const result = await contract.methods.burn(tokenId).send({ from: caller });141 const events = normalizeEvents(result.events);142 143 expect(events).to.be.deep.equal([144 {145 address,146 event: 'Transfer',147 args: {148 from: contract.options.address,149 to: '0x0000000000000000000000000000000000000000',150 tokenId: tokenId.toString(),151 },152 },153 ]);154 }155 });156157 itWeb3('Can perform approve()', async ({ web3, api }) => {158 const collection = await createCollectionExpectSuccess({159 mode: { type: 'NFT' },160 });161 const alice = privateKey('//Alice');162 const caller = await createEthAccountWithBalance(api, web3);163 const spender = createEthAccount(web3);164165 const address = collectionIdToAddress(collection);166 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address));167 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: contract.options.address });168169 {170 const result = await contract.methods.approve(spender, tokenId).send({ from: caller, gas: '0x1000000', gasPrice: '0x01' });171 const events = normalizeEvents(result.events);172173 expect(events).to.be.deep.equal([174 {175 address,176 event: 'Approval',177 args: {178 owner: contract.options.address,179 approved: spender,180 tokenId: tokenId.toString(),181 },182 },183 ]);184 }185 });186187 itWeb3('Can perform transferFrom()', async ({ web3, api }) => {188 const collection = await createCollectionExpectSuccess({189 mode: { type: 'NFT' },190 });191 const alice = privateKey('//Alice');192 const caller = await createEthAccountWithBalance(api, web3);193 const owner = await createEthAccountWithBalance(api, web3);194195 const receiver = createEthAccount(web3);196197 const address = collectionIdToAddress(collection);198 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, address, { from: caller, ...GAS_ARGS });199 const contract = await proxyWrap(api, web3, evmCollection);200 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: owner });201202 await evmCollection.methods.approve(contract.options.address, tokenId).send({ from: owner });203204 {205 const result = await contract.methods.transferFrom(owner, receiver, tokenId).send({ from: caller });206 const events = normalizeEvents(result.events);207 expect(events).to.be.deep.equal([208 {209 address,210 event: 'Transfer',211 args: {212 from: owner,213 to: receiver,214 tokenId: tokenId.toString(),215 },216 },217 ]);218 }219220 {221 const balance = await contract.methods.balanceOf(receiver).call();222 expect(+balance).to.equal(1);223 }224225 {226 const balance = await contract.methods.balanceOf(contract.options.address).call();227 expect(+balance).to.equal(0);228 }229 });230231 itWeb3('Can perform transfer()', async ({ web3, api }) => {232 const collection = await createCollectionExpectSuccess({233 mode: { type: 'NFT' },234 });235 const alice = privateKey('//Alice');236 const caller = await createEthAccountWithBalance(api, web3);237 const receiver = createEthAccount(web3);238239 const address = collectionIdToAddress(collection);240 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));241 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', { ethereum: contract.options.address });242243 {244 const result = await contract.methods.transfer(receiver, tokenId).send({ from: caller });245 await waitNewBlocks(api, 1);246 const events = normalizeEvents(result.events);247 expect(events).to.be.deep.equal([248 {249 address,250 event: 'Transfer',251 args: {252 from: contract.options.address,253 to: receiver,254 tokenId: tokenId.toString(),255 },256 },257 ]);258 }259260 {261 const balance = await contract.methods.balanceOf(contract.options.address).call();262 expect(+balance).to.equal(0);263 }264265 {266 const balance = await contract.methods.balanceOf(receiver).call();267 expect(+balance).to.equal(1);268 }269 });270});