difftreelog
Fix admin test and remove //Alice
in: master
2 files changed
tests/src/eth/collectionAdmin.test.tsdiffbeforeafterboth--- a/tests/src/eth/collectionAdmin.test.ts
+++ b/tests/src/eth/collectionAdmin.test.ts
@@ -77,16 +77,21 @@
const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Mint collection', 'a', 'b', 'uri');
const adminEth = (await helper.eth.createAccountWithBalance(donor)).toLowerCase();
const adminCrossEth = helper.ethCrossAccount.fromAddress(adminEth);
+ const [adminSub] = await helper.arrange.createAccounts([100n], donor);
+ const adminCrossSub = helper.ethCrossAccount.fromKeyringPair(adminSub);
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner, true);
// cannot mint while not admin
- await expect(collectionEvm.methods.mint(owner).send({from: adminEth})).to.be.rejectedWith('PublicMintingNotAllowed');
+ await expect(collectionEvm.methods.mint(owner).send({from: adminEth})).to.be.rejected;
+ await expect(helper.nft.mintToken(adminSub, {collectionId, owner: {Ethereum: owner}})).to.be.rejectedWith(/common.PublicMintingNotAllowed/);
- // admin can mint token:
+ // admin (sub and eth) can mint token:
await collectionEvm.methods.addCollectionAdminCross(adminCrossEth).send();
+ await collectionEvm.methods.addCollectionAdminCross(adminCrossSub).send();
await collectionEvm.methods.mint(owner).send({from: adminEth});
+ await helper.nft.mintToken(adminSub, {collectionId, owner: {Ethereum: owner}});
- expect(await helper.collection.getLastTokenId(collectionId)).to.eq(1);
+ expect(await helper.collection.getLastTokenId(collectionId)).to.eq(2);
});
itEth('cannot add invalid cross account admin', async ({helper}) => {
tests/src/eth/nonFungible.test.tsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {itEth, usingEthPlaygrounds, expect, EthUniqueHelper} from './util';18import {IKeyringPair} from '@polkadot/types/types';19import {Contract} from 'web3-eth-contract';202122describe('NFT: Information getting', () => {23 let donor: IKeyringPair;24 let alice: IKeyringPair;2526 before(async function() {27 await usingEthPlaygrounds(async (helper, privateKey) => {28 donor = await privateKey({filename: __filename});29 [alice] = await helper.arrange.createAccounts([10n], donor);30 });31 });3233 itEth('totalSupply', async ({helper}) => {34 const collection = await helper.nft.mintCollection(alice, {});35 await collection.mintToken(alice);3637 const caller = await helper.eth.createAccountWithBalance(donor);3839 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);40 const totalSupply = await contract.methods.totalSupply().call();4142 expect(totalSupply).to.equal('1');43 });4445 itEth('balanceOf', async ({helper}) => {46 const collection = await helper.nft.mintCollection(alice, {});47 const caller = await helper.eth.createAccountWithBalance(donor);4849 await collection.mintToken(alice, {Ethereum: caller});50 await collection.mintToken(alice, {Ethereum: caller});51 await collection.mintToken(alice, {Ethereum: caller});5253 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);54 const balance = await contract.methods.balanceOf(caller).call();5556 expect(balance).to.equal('3');57 });5859 itEth('ownerOf', async ({helper}) => {60 const collection = await helper.nft.mintCollection(alice, {});61 const caller = await helper.eth.createAccountWithBalance(donor);6263 const token = await collection.mintToken(alice, {Ethereum: caller});6465 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);6667 const owner = await contract.methods.ownerOf(token.tokenId).call();6869 expect(owner).to.equal(caller);70 });7172 itEth('name/symbol is available regardless of ERC721Metadata support', async ({helper}) => {73 const collection = await helper.nft.mintCollection(alice, {name: 'test', tokenPrefix: 'TEST'});74 const caller = helper.eth.createAccount();7576 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);7778 expect(await contract.methods.name().call()).to.equal('test');79 expect(await contract.methods.symbol().call()).to.equal('TEST');80 });81});8283describe('Check ERC721 token URI for NFT', () => {84 let donor: IKeyringPair;8586 before(async function() {87 await usingEthPlaygrounds(async (_helper, privateKey) => {88 donor = await privateKey({filename: __filename});89 });90 });9192 async function setup(helper: EthUniqueHelper, baseUri: string, propertyKey?: string, propertyValue?: string): Promise<{contract: Contract, nextTokenId: string}> {93 const owner = await helper.eth.createAccountWithBalance(donor);94 const receiver = helper.eth.createAccount();9596 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Mint collection', 'a', 'b', baseUri);97 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);9899 const result = await contract.methods.mint(receiver).send();100 const tokenId = result.events.Transfer.returnValues.tokenId;101 expect(tokenId).to.be.equal('1');102103 if (propertyKey && propertyValue) {104 // Set URL or suffix105 await contract.methods.setProperties(tokenId, [{key: propertyKey, value: Buffer.from(propertyValue)}]).send();106 }107108 const event = result.events.Transfer;109 expect(event.address).to.be.equal(collectionAddress);110 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');111 expect(event.returnValues.to).to.be.equal(receiver);112 expect(event.returnValues.tokenId).to.be.equal(tokenId);113114 return {contract, nextTokenId: tokenId};115 }116117 itEth('Empty tokenURI', async ({helper}) => {118 const {contract, nextTokenId} = await setup(helper, '');119 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('');120 });121122 itEth('TokenURI from url', async ({helper}) => {123 const {contract, nextTokenId} = await setup(helper, 'BaseURI_', 'URI', 'Token URI');124 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Token URI');125 });126127 itEth('TokenURI from baseURI', async ({helper}) => {128 const {contract, nextTokenId} = await setup(helper, 'BaseURI_');129 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_');130 });131132 itEth('TokenURI from baseURI + suffix', async ({helper}) => {133 const suffix = '/some/suffix';134 const {contract, nextTokenId} = await setup(helper, 'BaseURI_', 'URISuffix', suffix);135 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + suffix);136 });137});138139describe('NFT: Plain calls', () => {140 let donor: IKeyringPair;141 let minter: IKeyringPair;142 let bob: IKeyringPair;143 let charlie: IKeyringPair;144145 before(async function() {146 await usingEthPlaygrounds(async (helper, privateKey) => {147 donor = await privateKey({filename: __filename});148 [minter, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);149 });150 });151152 itEth('Can perform mint() & get crossOwner()', async ({helper}) => {153 const owner = await helper.eth.createAccountWithBalance(donor);154 const receiver = helper.eth.createAccount();155156 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Mint collection', '6', '6', '');157 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);158159 const result = await contract.methods.mintWithTokenURI(receiver, 'Test URI').send();160 const tokenId = result.events.Transfer.returnValues.tokenId;161 expect(tokenId).to.be.equal('1');162163 const event = result.events.Transfer;164 expect(event.address).to.be.equal(collectionAddress);165 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');166 expect(event.returnValues.to).to.be.equal(receiver);167168 expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');169 console.log(await contract.methods.crossOwnerOf(tokenId).call());170 expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);171 // TODO: this wont work right now, need release 919000 first172 // await helper.methods.setOffchainSchema(collectionIdAddress, 'https://offchain-service.local/token-info/{id}').send();173 // const tokenUri = await contract.methods.tokenURI(nextTokenId).call();174 // expect(tokenUri).to.be.equal(`https://offchain-service.local/token-info/${nextTokenId}`);175 });176177 //TODO: CORE-302 add eth methods178 itEth.skip('Can perform mintBulk()', async ({helper}) => {179 const caller = await helper.eth.createAccountWithBalance(donor);180 const receiver = helper.eth.createAccount();181182 const collection = await helper.nft.mintCollection(minter);183 await collection.addAdmin(minter, {Ethereum: caller});184185 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);186 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', caller);187 {188 const bulkSize = 3;189 const nextTokenId = await contract.methods.nextTokenId().call();190 expect(nextTokenId).to.be.equal('1');191 const result = await contract.methods.mintBulkWithTokenURI(192 receiver,193 Array.from({length: bulkSize}, (_, i) => (194 [+nextTokenId + i, `Test URI ${i}`]195 )),196 ).send({from: caller});197198 const events = result.events.Transfer.sort((a: any, b: any) => +a.returnValues.tokenId - b.returnValues.tokenId);199 for (let i = 0; i < bulkSize; i++) {200 const event = events[i];201 expect(event.address).to.equal(collectionAddress);202 expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');203 expect(event.returnValues.to).to.equal(receiver);204 expect(event.returnValues.tokenId).to.equal(`${+nextTokenId+i}`);205206 expect(await contract.methods.tokenURI(+nextTokenId + i).call()).to.be.equal(`Test URI ${i}`);207 }208 }209 });210211 itEth('Can perform burn()', async ({helper}) => {212 const caller = await helper.eth.createAccountWithBalance(donor);213214 const collection = await helper.nft.mintCollection(minter, {});215 const {tokenId} = await collection.mintToken(minter, {Ethereum: caller});216217 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);218 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', caller);219220 {221 const result = await contract.methods.burn(tokenId).send({from: caller});222223 const event = result.events.Transfer;224 expect(event.address).to.be.equal(collectionAddress);225 expect(event.returnValues.from).to.be.equal(caller);226 expect(event.returnValues.to).to.be.equal('0x0000000000000000000000000000000000000000');227 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);228 }229 });230231 itEth('Can perform approve()', async ({helper}) => {232 const owner = await helper.eth.createAccountWithBalance(donor);233 const spender = helper.eth.createAccount();234235 const collection = await helper.nft.mintCollection(minter, {});236 const {tokenId} = await collection.mintToken(minter, {Ethereum: owner});237238 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);239 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);240241 {242 const result = await contract.methods.approve(spender, tokenId).send({from: owner});243244 const event = result.events.Approval;245 expect(event.address).to.be.equal(collectionAddress);246 expect(event.returnValues.owner).to.be.equal(owner);247 expect(event.returnValues.approved).to.be.equal(spender);248 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);249 }250 });251252 itEth('Can perform burnFromCross()', async ({helper}) => {253 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});254255 const owner = bob;256 const spender = await helper.eth.createAccountWithBalance(donor, 100n);257258 const token = await collection.mintToken(minter, {Substrate: owner.address});259260 const address = helper.ethAddress.fromCollectionId(collection.collectionId);261 const contract = helper.ethNativeContract.collection(address, 'nft');262263 {264 await token.approve(owner, {Ethereum: spender});265 const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);266 const result = await contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: spender});267 const events = result.events.Transfer;268269 expect(events).to.be.like({270 address,271 event: 'Transfer',272 returnValues: {273 from: helper.address.substrateToEth(owner.address),274 to: '0x0000000000000000000000000000000000000000',275 tokenId: token.tokenId.toString(),276 },277 });278 }279 });280281 itEth('Can perform approveCross()', async ({helper}) => {282 // arrange: create accounts283 const owner = await helper.eth.createAccountWithBalance(donor, 100n);284 const ownerCross = helper.ethCrossAccount.fromAddress(owner);285 const receiverSub = charlie;286 const recieverCrossSub = helper.ethCrossAccount.fromKeyringPair(receiverSub);287 const receiverEth = await helper.eth.createAccountWithBalance(donor, 100n);288 const receiverCrossEth = helper.ethCrossAccount.fromAddress(receiverEth);289290 // arrange: create collection and tokens:291 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});292 const token1 = await collection.mintToken(minter, {Ethereum: owner});293 const token2 = await collection.mintToken(minter, {Ethereum: owner});294295 const collectionEvm = helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(collection.collectionId), 'nft');296297 // Can approveCross substrate and ethereum address:298 const resultSub = await collectionEvm.methods.approveCross(recieverCrossSub, token1.tokenId).send({from: owner});299 const resultEth = await collectionEvm.methods.approveCross(receiverCrossEth, token2.tokenId).send({from: owner});300 const eventSub = resultSub.events.Approval;301 const eventEth = resultEth.events.Approval;302 expect(eventSub).to.be.like({303 address: helper.ethAddress.fromCollectionId(collection.collectionId),304 event: 'Approval',305 returnValues: {306 owner,307 approved: helper.address.substrateToEth(receiverSub.address),308 tokenId: token1.tokenId.toString(),309 },310 });311 expect(eventEth).to.be.like({312 address: helper.ethAddress.fromCollectionId(collection.collectionId),313 event: 'Approval',314 returnValues: {315 owner,316 approved: receiverEth,317 tokenId: token2.tokenId.toString(),318 },319 });320321 // Substrate address can transferFrom approved tokens:322 await helper.nft.transferTokenFrom(receiverSub, collection.collectionId, token1.tokenId, {Ethereum: owner}, {Substrate: receiverSub.address});323 expect(await helper.nft.getTokenOwner(collection.collectionId, token1.tokenId)).to.deep.eq({Substrate: receiverSub.address});324 // Ethereum address can transferFromCross approved tokens:325 await collectionEvm.methods.transferFromCross(ownerCross, receiverCrossEth, token2.tokenId).send({from: receiverEth});326 expect(await helper.nft.getTokenOwner(collection.collectionId, token2.tokenId)).to.deep.eq({Ethereum: receiverEth.toLowerCase()});327 });328329 itEth('Can perform transferFrom()', async ({helper}) => {330 const owner = await helper.eth.createAccountWithBalance(donor);331 const spender = await helper.eth.createAccountWithBalance(donor);332 const receiver = helper.eth.createAccount();333334 const collection = await helper.nft.mintCollection(minter, {});335 const {tokenId} = await collection.mintToken(minter, {Ethereum: owner});336337 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);338 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);339340 await contract.methods.approve(spender, tokenId).send({from: owner});341342 {343 const result = await contract.methods.transferFrom(owner, receiver, tokenId).send({from: spender});344345 const event = result.events.Transfer;346 expect(event.address).to.be.equal(collectionAddress);347 expect(event.returnValues.from).to.be.equal(owner);348 expect(event.returnValues.to).to.be.equal(receiver);349 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);350 }351352 {353 const balance = await contract.methods.balanceOf(receiver).call();354 expect(+balance).to.equal(1);355 }356357 {358 const balance = await contract.methods.balanceOf(owner).call();359 expect(+balance).to.equal(0);360 }361 });362363 itEth('Can perform transferFromCross()', async ({helper, privateKey}) => {364 const minter = await privateKey('//Alice');365 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});366367 const owner = await privateKey('//Bob');368 const spender = await helper.eth.createAccountWithBalance(donor);369 const receiver = await privateKey('//Charlie');370371 const token = await collection.mintToken(minter, {Substrate: owner.address});372373 const address = helper.ethAddress.fromCollectionId(collection.collectionId);374 const contract = helper.ethNativeContract.collection(address, 'nft');375376 await token.approve(owner, {Ethereum: spender});377378 {379 const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);380 const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);381 const result = await contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: spender});382 const event = result.events.Transfer;383 expect(event).to.be.like({384 address: helper.ethAddress.fromCollectionId(collection.collectionId),385 event: 'Transfer',386 returnValues: {387 from: helper.address.substrateToEth(owner.address),388 to: helper.address.substrateToEth(receiver.address),389 tokenId: token.tokenId.toString(),390 },391 });392 }393394 expect(await token.getOwner()).to.be.like({Substrate: receiver.address});395 });396397 itEth('Can perform transfer()', async ({helper}) => {398 const collection = await helper.nft.mintCollection(minter, {});399 const owner = await helper.eth.createAccountWithBalance(donor);400 const receiver = helper.eth.createAccount();401402 const {tokenId} = await collection.mintToken(minter, {Ethereum: owner});403404 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);405 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);406407 {408 const result = await contract.methods.transfer(receiver, tokenId).send({from: owner});409410 const event = result.events.Transfer;411 expect(event.address).to.be.equal(collectionAddress);412 expect(event.returnValues.from).to.be.equal(owner);413 expect(event.returnValues.to).to.be.equal(receiver);414 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);415 }416417 {418 const balance = await contract.methods.balanceOf(owner).call();419 expect(+balance).to.equal(0);420 }421422 {423 const balance = await contract.methods.balanceOf(receiver).call();424 expect(+balance).to.equal(1);425 }426 });427 428 itEth('Can perform transferCross()', async ({helper}) => {429 const collection = await helper.nft.mintCollection(minter, {});430 const owner = await helper.eth.createAccountWithBalance(donor);431 const receiver = await helper.eth.createAccountWithBalance(donor);432 const to = helper.ethCrossAccount.fromAddress(receiver);433 const toSubstrate = helper.ethCrossAccount.fromKeyringPair(minter);434 435 const {tokenId} = await collection.mintToken(minter, {Ethereum: owner});436437 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);438 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);439440 {441 const result = await contract.methods.transferCross(to, tokenId).send({from: owner});442443 const event = result.events.Transfer;444 expect(event.address).to.be.equal(collectionAddress);445 expect(event.returnValues.from).to.be.equal(owner);446 expect(event.returnValues.to).to.be.equal(receiver);447 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);448 }449450 {451 const balance = await contract.methods.balanceOf(owner).call();452 expect(+balance).to.equal(0);453 }454455 {456 const balance = await contract.methods.balanceOf(receiver).call();457 expect(+balance).to.equal(1);458 }459 460 {461 const substrateResult = await contract.methods.transferCross(toSubstrate, tokenId).send({from: receiver});462 463464 const event = substrateResult.events.Transfer;465 expect(event.address).to.be.equal(collectionAddress);466 expect(event.returnValues.from).to.be.equal(receiver);467 expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(minter.address));468 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);469 }470471 {472 const balance = await contract.methods.balanceOf(receiver).call();473 expect(+balance).to.equal(0);474 }475476 {477 const balance = await helper.nft.getTokensByAddress(collection.collectionId, {Substrate: minter.address});478 expect(balance).to.be.contain(tokenId);479 }480 });481});482483describe('NFT: Fees', () => {484 let donor: IKeyringPair;485 let alice: IKeyringPair;486 let bob: IKeyringPair;487 let charlie: IKeyringPair;488489 before(async function() {490 await usingEthPlaygrounds(async (helper, privateKey) => {491 donor = await privateKey({filename: __filename});492 [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);493 });494 });495496 itEth('approve() call fee is less than 0.2UNQ', async ({helper}) => {497 const owner = await helper.eth.createAccountWithBalance(donor);498 const spender = helper.eth.createAccount();499500 const collection = await helper.nft.mintCollection(alice, {});501 const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});502503 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', owner);504505 const cost = await helper.eth.recordCallFee(owner, () => contract.methods.approve(spender, tokenId).send({from: owner}));506 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));507 });508509 itEth('transferFrom() call fee is less than 0.2UNQ', async ({helper}) => {510 const owner = await helper.eth.createAccountWithBalance(donor);511 const spender = await helper.eth.createAccountWithBalance(donor);512513 const collection = await helper.nft.mintCollection(alice, {});514 const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});515516 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', owner);517518 await contract.methods.approve(spender, tokenId).send({from: owner});519520 const cost = await helper.eth.recordCallFee(spender, () => contract.methods.transferFrom(owner, spender, tokenId).send({from: spender}));521 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));522 });523524 itEth('Can perform transferFromCross()', async ({helper}) => {525 const collectionMinter = alice;526 const owner = bob;527 const receiver = charlie;528 const collection = await helper.nft.mintCollection(collectionMinter, {name: 'A', description: 'B', tokenPrefix: 'C'});529530 const spender = await helper.eth.createAccountWithBalance(donor, 100n);531532 const token = await collection.mintToken(collectionMinter, {Substrate: owner.address});533534 const address = helper.ethAddress.fromCollectionId(collection.collectionId);535 const contract = helper.ethNativeContract.collection(address, 'nft');536537 await token.approve(owner, {Ethereum: spender});538539 {540 const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);541 const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);542 const result = await contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: spender});543 const event = result.events.Transfer;544 expect(event).to.be.like({545 address: helper.ethAddress.fromCollectionId(collection.collectionId),546 event: 'Transfer',547 returnValues: {548 from: helper.address.substrateToEth(owner.address),549 to: helper.address.substrateToEth(receiver.address),550 tokenId: token.tokenId.toString(),551 },552 });553 }554555 expect(await token.getOwner()).to.be.like({Substrate: receiver.address});556 });557558 itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {559 const owner = await helper.eth.createAccountWithBalance(donor);560 const receiver = helper.eth.createAccount();561562 const collection = await helper.nft.mintCollection(alice, {});563 const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});564565 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', owner);566567 const cost = await helper.eth.recordCallFee(owner, () => contract.methods.transfer(receiver, tokenId).send({from: owner}));568 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));569 });570});571572describe('NFT: Substrate calls', () => {573 let donor: IKeyringPair;574 let alice: IKeyringPair;575576 before(async function() {577 await usingEthPlaygrounds(async (helper, privateKey) => {578 donor = await privateKey({filename: __filename});579 [alice] = await helper.arrange.createAccounts([20n], donor);580 });581 });582583 itEth('Events emitted for mint()', async ({helper}) => {584 const collection = await helper.nft.mintCollection(alice, {});585 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);586 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');587588 const events: any = [];589 contract.events.allEvents((_: any, event: any) => {590 events.push(event);591 });592593 const {tokenId} = await collection.mintToken(alice);594 if (events.length == 0) await helper.wait.newBlocks(1);595 const event = events[0];596597 expect(event.event).to.be.equal('Transfer');598 expect(event.address).to.be.equal(collectionAddress);599 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');600 expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(alice.address));601 expect(event.returnValues.tokenId).to.be.equal(tokenId.toString());602 });603604 itEth('Events emitted for burn()', async ({helper}) => {605 const collection = await helper.nft.mintCollection(alice, {});606 const token = await collection.mintToken(alice);607608 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);609 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');610611 const events: any = [];612 contract.events.allEvents((_: any, event: any) => {613 events.push(event);614 });615616 await token.burn(alice);617 if (events.length == 0) await helper.wait.newBlocks(1);618 const event = events[0];619620 expect(event.event).to.be.equal('Transfer');621 expect(event.address).to.be.equal(collectionAddress);622 expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));623 expect(event.returnValues.to).to.be.equal('0x0000000000000000000000000000000000000000');624 expect(event.returnValues.tokenId).to.be.equal(token.tokenId.toString());625 });626627 itEth('Events emitted for approve()', async ({helper}) => {628 const receiver = helper.eth.createAccount();629630 const collection = await helper.nft.mintCollection(alice, {});631 const token = await collection.mintToken(alice);632633 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);634 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');635636 const events: any = [];637 contract.events.allEvents((_: any, event: any) => {638 events.push(event);639 });640641 await token.approve(alice, {Ethereum: receiver});642 if (events.length == 0) await helper.wait.newBlocks(1);643 const event = events[0];644645 expect(event.event).to.be.equal('Approval');646 expect(event.address).to.be.equal(collectionAddress);647 expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));648 expect(event.returnValues.approved).to.be.equal(receiver);649 expect(event.returnValues.tokenId).to.be.equal(token.tokenId.toString());650 });651652 itEth('Events emitted for transferFrom()', async ({helper}) => {653 const [bob] = await helper.arrange.createAccounts([10n], donor);654 const receiver = helper.eth.createAccount();655656 const collection = await helper.nft.mintCollection(alice, {});657 const token = await collection.mintToken(alice);658 await token.approve(alice, {Substrate: bob.address});659660 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);661 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');662663 const events: any = [];664 contract.events.allEvents((_: any, event: any) => {665 events.push(event);666 });667668 await token.transferFrom(bob, {Substrate: alice.address}, {Ethereum: receiver});669670 if (events.length == 0) await helper.wait.newBlocks(1);671 const event = events[0];672673 expect(event.address).to.be.equal(collectionAddress);674 expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));675 expect(event.returnValues.to).to.be.equal(receiver);676 expect(event.returnValues.tokenId).to.be.equal(`${token.tokenId}`);677 });678679 itEth('Events emitted for transfer()', async ({helper}) => {680 const receiver = helper.eth.createAccount();681682 const collection = await helper.nft.mintCollection(alice, {});683 const token = await collection.mintToken(alice);684685 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);686 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');687688 const events: any = [];689 contract.events.allEvents((_: any, event: any) => {690 events.push(event);691 });692693 await token.transfer(alice, {Ethereum: receiver});694695 if (events.length == 0) await helper.wait.newBlocks(1);696 const event = events[0];697698 expect(event.address).to.be.equal(collectionAddress);699 expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));700 expect(event.returnValues.to).to.be.equal(receiver);701 expect(event.returnValues.tokenId).to.be.equal(`${token.tokenId}`);702 });703});704705describe('Common metadata', () => {706 let donor: IKeyringPair;707 let alice: IKeyringPair;708709 before(async function() {710 await usingEthPlaygrounds(async (helper, privateKey) => {711 donor = await privateKey({filename: __filename});712 [alice] = await helper.arrange.createAccounts([20n], donor);713 });714 });715716 itEth('Returns collection name', async ({helper}) => {717 const caller = await helper.eth.createAccountWithBalance(donor);718 const tokenPropertyPermissions = [{719 key: 'URI',720 permission: {721 mutable: true,722 collectionAdmin: true,723 tokenOwner: false,724 },725 }];726 const collection = await helper.nft.mintCollection(727 alice,728 {729 name: 'oh River',730 tokenPrefix: 'CHANGE',731 properties: [{key: 'ERC721Metadata', value: '1'}],732 tokenPropertyPermissions,733 },734 );735736 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);737 const name = await contract.methods.name().call();738 expect(name).to.equal('oh River');739 });740741 itEth('Returns symbol name', async ({helper}) => {742 const caller = await helper.eth.createAccountWithBalance(donor);743 const tokenPropertyPermissions = [{744 key: 'URI',745 permission: {746 mutable: true,747 collectionAdmin: true,748 tokenOwner: false,749 },750 }];751 const collection = await helper.nft.mintCollection(752 alice,753 {754 name: 'oh River',755 tokenPrefix: 'CHANGE',756 properties: [{key: 'ERC721Metadata', value: '1'}],757 tokenPropertyPermissions,758 },759 );760761 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);762 const symbol = await contract.methods.symbol().call();763 expect(symbol).to.equal('CHANGE');764 });765});