1234567891011121314151617import privateKey from '../../substrate/privateKey';18import {createCollectionExpectSuccess, createItemExpectSuccess} from '../../util/helpers';19import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents} from '../util/helpers';20import nonFungibleAbi from '../nonFungibleAbi.json';21import {expect} from 'chai';22import {submitTransactionAsync} from '../../substrate/substrate-api';23import Web3 from 'web3';24import {readFile} from 'fs/promises';25import {ApiPromise} from '@polkadot/api';2627async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any) {28 29 const owner = await createEthAccountWithBalance(api, web3);30 const proxyContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueNFTProxy.abi`)).toString()), undefined, {31 from: owner,32 ...GAS_ARGS,33 });34 const proxy = await proxyContract.deploy({data: (await readFile(`${__dirname}/UniqueNFTProxy.bin`)).toString(), arguments: [wrapped.options.address]}).send({from: owner});35 return proxy;36}3738describe('NFT (Via EVM proxy): Information getting', () => {39 itWeb3('totalSupply', async ({api, web3}) => {40 const collection = await createCollectionExpectSuccess({41 mode: {type: 'NFT'},42 });43 const alice = privateKey('//Alice');44 const caller = await createEthAccountWithBalance(api, web3);4546 await createItemExpectSuccess(alice, collection, 'NFT', {Substrate: alice.address});4748 const address = collectionIdToAddress(collection);49 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));50 const totalSupply = await contract.methods.totalSupply().call();5152 expect(totalSupply).to.equal('1');53 });5455 itWeb3('balanceOf', async ({api, web3}) => {56 const collection = await createCollectionExpectSuccess({57 mode: {type: 'NFT'},58 });59 const alice = privateKey('//Alice');6061 const caller = await createEthAccountWithBalance(api, web3);62 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});63 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});64 await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});6566 const address = collectionIdToAddress(collection);67 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));68 const balance = await contract.methods.balanceOf(caller).call();6970 expect(balance).to.equal('3');71 });7273 itWeb3('ownerOf', async ({api, web3}) => {74 const collection = await createCollectionExpectSuccess({75 mode: {type: 'NFT'},76 });77 const alice = privateKey('//Alice');7879 const caller = await createEthAccountWithBalance(api, web3);80 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller});8182 const address = collectionIdToAddress(collection);83 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));84 const owner = await contract.methods.ownerOf(tokenId).call();8586 expect(owner).to.equal(caller);87 });88});8990describe('NFT (Via EVM proxy): Plain calls', () => {91 itWeb3('Can perform mint()', async ({web3, api}) => {92 const collection = await createCollectionExpectSuccess({93 mode: {type: 'NFT'},94 });95 const alice = privateKey('//Alice');96 const caller = await createEthAccountWithBalance(api, web3);97 const receiver = createEthAccount(web3);9899 const address = collectionIdToAddress(collection);100 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));101102 const changeAdminTx = api.tx.unique.addCollectionAdmin(collection, {Ethereum: contract.options.address});103 await submitTransactionAsync(alice, changeAdminTx);104105 {106 const nextTokenId = await contract.methods.nextTokenId().call();107 expect(nextTokenId).to.be.equal('1');108 const result = await contract.methods.mintWithTokenURI(109 receiver,110 nextTokenId,111 'Test URI',112 ).send({from: caller});113 const events = normalizeEvents(result.events);114115 expect(events).to.be.deep.equal([116 {117 address,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 itWeb3('Can perform mintBulk()', async ({web3, api}) => {131 const collection = await createCollectionExpectSuccess({132 mode: {type: 'NFT'},133 });134 const alice = privateKey('//Alice');135136 const caller = await createEthAccountWithBalance(api, web3);137 const receiver = createEthAccount(web3);138139 const address = collectionIdToAddress(collection);140 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));141 const changeAdminTx = api.tx.unique.addCollectionAdmin(collection, {Ethereum: contract.options.address});142 await submitTransactionAsync(alice, changeAdminTx);143144 {145 const nextTokenId = await contract.methods.nextTokenId().call();146 expect(nextTokenId).to.be.equal('1');147 const result = await contract.methods.mintBulkWithTokenURI(148 receiver,149 [150 [nextTokenId, 'Test URI 0'],151 [+nextTokenId + 1, 'Test URI 1'],152 [+nextTokenId + 2, 'Test URI 2'],153 ],154 ).send({from: caller});155 const events = normalizeEvents(result.events);156157 expect(events).to.be.deep.equal([158 {159 address,160 event: 'Transfer',161 args: {162 from: '0x0000000000000000000000000000000000000000',163 to: receiver,164 tokenId: nextTokenId,165 },166 },167 {168 address,169 event: 'Transfer',170 args: {171 from: '0x0000000000000000000000000000000000000000',172 to: receiver,173 tokenId: String(+nextTokenId + 1),174 },175 },176 {177 address,178 event: 'Transfer',179 args: {180 from: '0x0000000000000000000000000000000000000000',181 to: receiver,182 tokenId: String(+nextTokenId + 2),183 },184 },185 ]);186187 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI 0');188 expect(await contract.methods.tokenURI(+nextTokenId + 1).call()).to.be.equal('Test URI 1');189 expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2');190 }191 });192193 itWeb3('Can perform burn()', async ({web3, api}) => {194 const collection = await createCollectionExpectSuccess({195 mode: {type: 'NFT'},196 });197 const alice = privateKey('//Alice');198 const caller = await createEthAccountWithBalance(api, web3);199200 const address = collectionIdToAddress(collection);201 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));202 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});203204 const changeAdminTx = api.tx.unique.addCollectionAdmin(collection, {Ethereum: contract.options.address});205 await submitTransactionAsync(alice, changeAdminTx);206207 {208 const result = await contract.methods.burn(tokenId).send({from: caller});209 const events = normalizeEvents(result.events);210211 expect(events).to.be.deep.equal([212 {213 address,214 event: 'Transfer',215 args: {216 from: contract.options.address,217 to: '0x0000000000000000000000000000000000000000',218 tokenId: tokenId.toString(),219 },220 },221 ]);222 }223 });224225 itWeb3('Can perform approve()', async ({web3, api}) => {226 const collection = await createCollectionExpectSuccess({227 mode: {type: 'NFT'},228 });229 const alice = privateKey('//Alice');230 const caller = await createEthAccountWithBalance(api, web3);231 const spender = createEthAccount(web3);232233 const address = collectionIdToAddress(collection);234 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address));235 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});236237 {238 const result = await contract.methods.approve(spender, tokenId).send({from: caller, ...GAS_ARGS});239 const events = normalizeEvents(result.events);240241 expect(events).to.be.deep.equal([242 {243 address,244 event: 'Approval',245 args: {246 owner: contract.options.address,247 approved: spender,248 tokenId: tokenId.toString(),249 },250 },251 ]);252 }253 });254255 itWeb3('Can perform transferFrom()', async ({web3, api}) => {256 const collection = await createCollectionExpectSuccess({257 mode: {type: 'NFT'},258 });259 const alice = privateKey('//Alice');260 const caller = await createEthAccountWithBalance(api, web3);261 const owner = await createEthAccountWithBalance(api, web3);262263 const receiver = createEthAccount(web3);264265 const address = collectionIdToAddress(collection);266 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});267 const contract = await proxyWrap(api, web3, evmCollection);268 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});269270 await evmCollection.methods.approve(contract.options.address, tokenId).send({from: owner});271272 {273 const result = await contract.methods.transferFrom(owner, receiver, tokenId).send({from: caller});274 const events = normalizeEvents(result.events);275 expect(events).to.be.deep.equal([276 {277 address,278 event: 'Transfer',279 args: {280 from: owner,281 to: receiver,282 tokenId: tokenId.toString(),283 },284 },285 ]);286 }287288 {289 const balance = await contract.methods.balanceOf(receiver).call();290 expect(+balance).to.equal(1);291 }292293 {294 const balance = await contract.methods.balanceOf(contract.options.address).call();295 expect(+balance).to.equal(0);296 }297 });298299 itWeb3('Can perform transfer()', async ({web3, api}) => {300 const collection = await createCollectionExpectSuccess({301 mode: {type: 'NFT'},302 });303 const alice = privateKey('//Alice');304 const caller = await createEthAccountWithBalance(api, web3);305 const receiver = createEthAccount(web3);306307 const address = collectionIdToAddress(collection);308 const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));309 const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});310311 {312 const result = await contract.methods.transfer(receiver, tokenId).send({from: caller});313 const events = normalizeEvents(result.events);314 expect(events).to.be.deep.equal([315 {316 address,317 event: 'Transfer',318 args: {319 from: contract.options.address,320 to: receiver,321 tokenId: tokenId.toString(),322 },323 },324 ]);325 }326327 {328 const balance = await contract.methods.balanceOf(contract.options.address).call();329 expect(+balance).to.equal(0);330 }331332 {333 const balance = await contract.methods.balanceOf(receiver).call();334 expect(+balance).to.equal(1);335 }336 });337});