difftreelog
Merge pull request #744 from UniqueNetwork/tests/eth-helpers
in: master
Tests/eth helpers
5 files changed
tests/src/eth/allowlist.test.tsdiffbeforeafterboth--- a/tests/src/eth/allowlist.test.ts
+++ b/tests/src/eth/allowlist.test.ts
@@ -92,21 +92,47 @@
});
itEth('Collection allowlist can be added and removed by [cross] address', async ({helper}) => {
- const owner = await helper.eth.createAccountWithBalance(donor);
- const user = donor;
+ const owner = (await helper.eth.createAccountWithBalance(donor)).toLowerCase();
+ const [userSub] = await helper.arrange.createAccounts([10n], donor);
+ const userEth = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
- const userCross = helper.ethCrossAccount.fromKeyringPair(user);
+ const userCrossSub = helper.ethCrossAccount.fromKeyringPair(userSub);
+ const userCrossEth = helper.ethCrossAccount.fromAddress(userEth);
+ const ownerCrossEth = helper.ethCrossAccount.fromAddress(owner);
+
+ // Can addToCollectionAllowListCross:
+ expect(await helper.collection.allowed(collectionId, {Substrate: userSub.address})).to.be.false;
+ await collectionEvm.methods.addToCollectionAllowListCross(userCrossSub).send({from: owner});
+ await collectionEvm.methods.addToCollectionAllowListCross(userCrossEth).send({from: owner});
+ await collectionEvm.methods.addToCollectionAllowListCross(ownerCrossEth).send({from: owner});
+ expect(await helper.collection.allowed(collectionId, {Substrate: userSub.address})).to.be.true;
+ expect(await helper.collection.allowed(collectionId, {Ethereum: userEth})).to.be.true;
+ expect(await collectionEvm.methods.allowlistedCross(userCrossSub).call({from: owner})).to.be.true;
+ expect(await collectionEvm.methods.allowlistedCross(userCrossEth).call({from: owner})).to.be.true;
+
+ await collectionEvm.methods.mint(userEth).send(); // token #1
+ await collectionEvm.methods.mint(userEth).send(); // token #2
+ await collectionEvm.methods.setCollectionAccess(1).send();
- expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
- await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});
- expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true;
- expect(await collectionEvm.methods.allowlistedCross(userCross).call({from: owner})).to.be.true;
+ // allowlisted account can transfer and transferCross:
+ await collectionEvm.methods.transfer(owner, 1).send({from: userEth});
+ await collectionEvm.methods.transferCross(userCrossSub, 2).send({from: userEth});
+ expect(await helper.nft.getTokenOwner(collectionId, 1)).to.deep.eq({Ethereum: owner});
+ expect(await helper.nft.getTokenOwner(collectionId, 2)).to.deep.eq({Substrate: userSub.address});
- await collectionEvm.methods.removeFromCollectionAllowListCross(userCross).send({from: owner});
- expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false;
- expect(await collectionEvm.methods.allowlistedCross(userCross).call({from: owner})).to.be.false;
+ // can removeFromCollectionAllowListCross:
+ await collectionEvm.methods.removeFromCollectionAllowListCross(userCrossSub).send({from: owner});
+ await collectionEvm.methods.removeFromCollectionAllowListCross(userCrossEth).send({from: owner});
+ expect(await helper.collection.allowed(collectionId, {Substrate: userSub.address})).to.be.false;
+ expect(await helper.collection.allowed(collectionId, {Ethereum: userEth})).to.be.false;
+ expect(await collectionEvm.methods.allowlistedCross(userCrossSub).call({from: owner})).to.be.false;
+ expect(await collectionEvm.methods.allowlistedCross(userCrossEth).call({from: owner})).to.be.false;
+
+ // cannot transfer anymore
+ await collectionEvm.methods.mint(userEth).send();
+ await expect(collectionEvm.methods.transfer(owner, 2).send({from: userEth})).to.be.rejectedWith(/Transaction has been reverted/);
});
// Soft-deprecated
tests/src/eth/collectionAdmin.test.tsdiffbeforeafterboth--- a/tests/src/eth/collectionAdmin.test.ts
+++ b/tests/src/eth/collectionAdmin.test.ts
@@ -39,80 +39,98 @@
});
});
- // Soft-deprecated
- itEth('Add admin by owner', async ({helper}) => {
+ itEth('can add account admin by owner', async ({helper, privateKey}) => {
+ // arrange
const owner = await helper.eth.createAccountWithBalance(donor);
+ const adminSub = await privateKey('//admin2');
+ const adminEth = helper.eth.createAccount().toLowerCase();
+
+ const adminDeprecated = helper.eth.createAccount().toLowerCase();
+ const adminCrossSub = helper.ethCrossAccount.fromKeyringPair(adminSub);
+ const adminCrossEth = helper.ethCrossAccount.fromAddress(adminEth);
+
const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner, true);
- const newAdmin = helper.eth.createAccount();
+ // Soft-deprecated: can addCollectionAdmin
+ await collectionEvm.methods.addCollectionAdmin(adminDeprecated).send();
+ // Can addCollectionAdminCross for substrate and ethereum address
+ await collectionEvm.methods.addCollectionAdminCross(adminCrossSub).send();
+ await collectionEvm.methods.addCollectionAdminCross(adminCrossEth).send();
- await collectionEvm.methods.addCollectionAdmin(newAdmin).send();
- const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]);
- expect(adminList[0].asEthereum.toString().toLocaleLowerCase())
- .to.be.eq(newAdmin.toLocaleLowerCase());
+ // 1. Expect api.rpc.unique.adminlist returns admins:
+ const adminListRpc = await helper.collection.getAdmins(collectionId);
+ expect(adminListRpc).to.has.length(3);
+ expect(adminListRpc).to.be.deep.contain.members([{Substrate: adminSub.address}, {Ethereum: adminEth}, {Ethereum: adminDeprecated}]);
+
+ // 2. Expect methods.collectionAdmins == api.rpc.unique.adminlist
+ let adminListEth = await collectionEvm.methods.collectionAdmins().call();
+ adminListEth = adminListEth.map((element: IEthCrossAccountId) => {
+ return helper.address.convertCrossAccountFromEthCrossAccount(element);
+ });
+ expect(adminListRpc).to.be.like(adminListEth);
});
- itEth('Add cross account admin by owner', async ({helper, privateKey}) => {
+ itEth('cross account admin can mint', async ({helper}) => {
+ // arrange: create collection and accounts
const owner = await helper.eth.createAccountWithBalance(donor);
-
- const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
- const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+ 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.rejected;
+ await expect(helper.nft.mintToken(adminSub, {collectionId, owner: {Ethereum: owner}})).to.be.rejectedWith(/common.PublicMintingNotAllowed/);
- const newAdmin = await privateKey('//Bob');
- const newAdminCross = helper.ethCrossAccount.fromKeyringPair(newAdmin);
- await collectionEvm.methods.addCollectionAdminCross(newAdminCross).send();
+ // 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}});
- const adminList = await helper.collection.getAdmins(collectionId);
- expect(adminList).to.be.like([{Substrate: newAdmin.address}]);
+ expect(await helper.collection.getLastTokenId(collectionId)).to.eq(2);
});
- itEth('Check adminlist', async ({helper, privateKey}) => {
+ itEth('cannot add invalid cross account admin', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
-
- const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
- const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner, true);
+ const [admin] = await helper.arrange.createAccounts([100n, 100n], donor);
- const admin1 = helper.eth.createAccount();
- const admin2 = await privateKey('admin');
- const admin2Cross = helper.ethCrossAccount.fromKeyringPair(admin2);
-
- // Soft-deprecated
- await collectionEvm.methods.addCollectionAdmin(admin1).send();
- await collectionEvm.methods.addCollectionAdminCross(admin2Cross).send();
+ const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
- const adminListRpc = await helper.collection.getAdmins(collectionId);
- let adminListEth = await collectionEvm.methods.collectionAdmins().call();
- adminListEth = adminListEth.map((element: IEthCrossAccountId) => {
- return helper.address.convertCrossAccountFromEthCrossAcoount(element);
- });
- expect(adminListRpc).to.be.like(adminListEth);
+ const adminCross = {
+ eth: helper.address.substrateToEth(admin.address),
+ sub: admin.addressRaw,
+ };
+ await expect(collectionEvm.methods.addCollectionAdminCross(adminCross).send()).to.be.rejected;
});
- // Soft-deprecated
- itEth('Verify owner or admin', async ({helper}) => {
+ itEth('can verify owner with methods.isOwnerOrAdmin[Cross]', async ({helper, privateKey}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
- const newAdmin = helper.eth.createAccount();
+ const adminDeprecated = helper.eth.createAccount();
+ const admin1Cross = helper.ethCrossAccount.fromKeyringPair(await privateKey('admin'));
+ const admin2Cross = helper.ethCrossAccount.fromAddress(helper.address.substrateToEth((await privateKey('admin3')).address));
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner, true);
- expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.false;
- await collectionEvm.methods.addCollectionAdmin(newAdmin).send();
- expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.true;
- });
+ // Soft-deprecated:
+ expect(await collectionEvm.methods.isOwnerOrAdmin(adminDeprecated).call()).to.be.false;
+ expect(await collectionEvm.methods.isOwnerOrAdminCross(admin1Cross).call()).to.be.false;
+ expect(await collectionEvm.methods.isOwnerOrAdminCross(admin2Cross).call()).to.be.false;
- itEth('Verify owner or admin cross', async ({helper, privateKey}) => {
- const owner = await helper.eth.createAccountWithBalance(donor);
- const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
+ await collectionEvm.methods.addCollectionAdmin(adminDeprecated).send();
+ await collectionEvm.methods.addCollectionAdminCross(admin1Cross).send();
+ await collectionEvm.methods.addCollectionAdminCross(admin2Cross).send();
- const newAdmin = await privateKey('admin');
- const newAdminCross = helper.ethCrossAccount.fromKeyringPair(newAdmin);
- const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
-
- expect(await collectionEvm.methods.isOwnerOrAdminCross(newAdminCross).call()).to.be.false;
- await collectionEvm.methods.addCollectionAdminCross(newAdminCross).send();
- expect(await collectionEvm.methods.isOwnerOrAdminCross(newAdminCross).call()).to.be.true;
+ // Soft-deprecated: isOwnerOrAdmin returns true
+ expect(await collectionEvm.methods.isOwnerOrAdmin(adminDeprecated).call()).to.be.true;
+ // Expect isOwnerOrAdminCross return true
+ expect(await collectionEvm.methods.isOwnerOrAdminCross(admin1Cross).call()).to.be.true;
+ expect(await collectionEvm.methods.isOwnerOrAdminCross(admin2Cross).call()).to.be.true;
});
// Soft-deprecated
@@ -154,12 +172,11 @@
const owner = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');
- const [admin] = await helper.arrange.createAccounts([10n], donor);
+ const [admin, notAdmin] = await helper.arrange.createAccounts([10n, 10n], donor);
const adminCross = helper.ethCrossAccount.fromKeyringPair(admin);
const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
await collectionEvm.methods.addCollectionAdminCross(adminCross).send();
- const [notAdmin] = await helper.arrange.createAccounts([10n], donor);
const notAdminCross = helper.ethCrossAccount.fromKeyringPair(notAdmin);
await expect(collectionEvm.methods.addCollectionAdminCross(notAdminCross).call({from: adminCross.eth}))
.to.be.rejectedWith('NoPermission');
tests/src/eth/fungible.test.tsdiffbeforeafterboth--- a/tests/src/eth/fungible.test.ts
+++ b/tests/src/eth/fungible.test.ts
@@ -314,7 +314,7 @@
}
});
- itEth('Can perform transferFromCross()', async ({helper, privateKey}) => {
+ itEth('Can perform transferFromCross()', async ({helper}) => {
const sender = await helper.eth.createAccountWithBalance(donor, 100n);
const collection = await helper.ft.mintCollection(owner, {name: 'A', description: 'B', tokenPrefix: 'C'}, 0);
@@ -508,7 +508,7 @@
expect(event.returnValues.value).to.be.equal('51');
});
- itEth('Events emitted for transferFromCross()', async ({helper, privateKey}) => {
+ itEth('Events emitted for transferFromCross()', async ({helper}) => {
const sender = await helper.eth.createAccountWithBalance(donor, 100n);
const collection = await helper.ft.mintCollection(owner, {name: 'A', description: 'B', tokenPrefix: 'C'}, 0);
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';20import exp from 'constants';212223describe('NFT: Information getting', () => {24 let donor: IKeyringPair;25 let alice: IKeyringPair;2627 before(async function() {28 await usingEthPlaygrounds(async (helper, privateKey) => {29 donor = await privateKey({filename: __filename});30 [alice] = await helper.arrange.createAccounts([10n], donor);31 });32 });3334 itEth('totalSupply', async ({helper}) => {35 const collection = await helper.nft.mintCollection(alice, {});36 await collection.mintToken(alice);3738 const caller = await helper.eth.createAccountWithBalance(donor);3940 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);41 const totalSupply = await contract.methods.totalSupply().call();4243 expect(totalSupply).to.equal('1');44 });4546 itEth('balanceOf', async ({helper}) => {47 const collection = await helper.nft.mintCollection(alice, {});48 const caller = await helper.eth.createAccountWithBalance(donor);4950 await collection.mintToken(alice, {Ethereum: caller});51 await collection.mintToken(alice, {Ethereum: caller});52 await collection.mintToken(alice, {Ethereum: caller});5354 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);55 const balance = await contract.methods.balanceOf(caller).call();5657 expect(balance).to.equal('3');58 });5960 itEth('ownerOf', async ({helper}) => {61 const collection = await helper.nft.mintCollection(alice, {});62 const caller = await helper.eth.createAccountWithBalance(donor);6364 const token = await collection.mintToken(alice, {Ethereum: caller});6566 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);6768 const owner = await contract.methods.ownerOf(token.tokenId).call();6970 expect(owner).to.equal(caller);71 });7273 itEth('name/symbol is available regardless of ERC721Metadata support', async ({helper}) => {74 const collection = await helper.nft.mintCollection(alice, {name: 'test', tokenPrefix: 'TEST'});75 const caller = helper.eth.createAccount();7677 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);7879 expect(await contract.methods.name().call()).to.equal('test');80 expect(await contract.methods.symbol().call()).to.equal('TEST');81 });82});8384describe('Check ERC721 token URI for NFT', () => {85 let donor: IKeyringPair;8687 before(async function() {88 await usingEthPlaygrounds(async (_helper, privateKey) => {89 donor = await privateKey({filename: __filename});90 });91 });9293 async function setup(helper: EthUniqueHelper, baseUri: string, propertyKey?: string, propertyValue?: string): Promise<{contract: Contract, nextTokenId: string}> {94 const owner = await helper.eth.createAccountWithBalance(donor);95 const receiver = helper.eth.createAccount();9697 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Mint collection', 'a', 'b', baseUri);98 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);99100 const result = await contract.methods.mint(receiver).send();101 const tokenId = result.events.Transfer.returnValues.tokenId;102 expect(tokenId).to.be.equal('1');103104 if (propertyKey && propertyValue) {105 // Set URL or suffix106 await contract.methods.setProperties(tokenId, [{key: propertyKey, value: Buffer.from(propertyValue)}]).send();107 }108109 const event = result.events.Transfer;110 expect(event.address).to.be.equal(collectionAddress);111 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');112 expect(event.returnValues.to).to.be.equal(receiver);113 expect(event.returnValues.tokenId).to.be.equal(tokenId);114115 return {contract, nextTokenId: tokenId};116 }117118 itEth('Empty tokenURI', async ({helper}) => {119 const {contract, nextTokenId} = await setup(helper, '');120 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('');121 });122123 itEth('TokenURI from url', async ({helper}) => {124 const {contract, nextTokenId} = await setup(helper, 'BaseURI_', 'URI', 'Token URI');125 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Token URI');126 });127128 itEth('TokenURI from baseURI', async ({helper}) => {129 const {contract, nextTokenId} = await setup(helper, 'BaseURI_');130 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_');131 });132133 itEth('TokenURI from baseURI + suffix', async ({helper}) => {134 const suffix = '/some/suffix';135 const {contract, nextTokenId} = await setup(helper, 'BaseURI_', 'URISuffix', suffix);136 expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('BaseURI_' + suffix);137 });138});139140describe('NFT: Plain calls', () => {141 let donor: IKeyringPair;142 let minter: IKeyringPair;143 let bob: IKeyringPair;144 let charlie: IKeyringPair;145146 before(async function() {147 await usingEthPlaygrounds(async (helper, privateKey) => {148 donor = await privateKey({filename: __filename});149 [minter, bob, charlie] = await helper.arrange.createAccounts([100n, 100n, 100n], donor);150 });151 });152153 itEth('Can perform mint() & get crossOwner()', async ({helper}) => {154 const owner = await helper.eth.createAccountWithBalance(donor);155 const receiver = helper.eth.createAccount();156157 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Mint collection', '6', '6', '');158 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);159160 const result = await contract.methods.mintWithTokenURI(receiver, 'Test URI').send();161 const tokenId = result.events.Transfer.returnValues.tokenId;162 expect(tokenId).to.be.equal('1');163164 const event = result.events.Transfer;165 expect(event.address).to.be.equal(collectionAddress);166 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');167 expect(event.returnValues.to).to.be.equal(receiver);168169 expect(await contract.methods.tokenURI(tokenId).call()).to.be.equal('Test URI');170 console.log(await contract.methods.crossOwnerOf(tokenId).call());171 expect(await contract.methods.crossOwnerOf(tokenId).call()).to.be.like([receiver, '0']);172 // TODO: this wont work right now, need release 919000 first173 // await helper.methods.setOffchainSchema(collectionIdAddress, 'https://offchain-service.local/token-info/{id}').send();174 // const tokenUri = await contract.methods.tokenURI(nextTokenId).call();175 // expect(tokenUri).to.be.equal(`https://offchain-service.local/token-info/${nextTokenId}`);176 });177178 //TODO: CORE-302 add eth methods179 itEth.skip('Can perform mintBulk()', async ({helper}) => {180 const caller = await helper.eth.createAccountWithBalance(donor);181 const receiver = helper.eth.createAccount();182183 const collection = await helper.nft.mintCollection(minter);184 await collection.addAdmin(minter, {Ethereum: caller});185186 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);187 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', caller);188 {189 const bulkSize = 3;190 const nextTokenId = await contract.methods.nextTokenId().call();191 expect(nextTokenId).to.be.equal('1');192 const result = await contract.methods.mintBulkWithTokenURI(193 receiver,194 Array.from({length: bulkSize}, (_, i) => (195 [+nextTokenId + i, `Test URI ${i}`]196 )),197 ).send({from: caller});198199 const events = result.events.Transfer.sort((a: any, b: any) => +a.returnValues.tokenId - b.returnValues.tokenId);200 for (let i = 0; i < bulkSize; i++) {201 const event = events[i];202 expect(event.address).to.equal(collectionAddress);203 expect(event.returnValues.from).to.equal('0x0000000000000000000000000000000000000000');204 expect(event.returnValues.to).to.equal(receiver);205 expect(event.returnValues.tokenId).to.equal(`${+nextTokenId+i}`);206207 expect(await contract.methods.tokenURI(+nextTokenId + i).call()).to.be.equal(`Test URI ${i}`);208 }209 }210 });211212 itEth('Can perform burn()', async ({helper}) => {213 const caller = await helper.eth.createAccountWithBalance(donor);214215 const collection = await helper.nft.mintCollection(minter, {});216 const {tokenId} = await collection.mintToken(minter, {Ethereum: caller});217218 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);219 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', caller);220221 {222 const result = await contract.methods.burn(tokenId).send({from: caller});223224 const event = result.events.Transfer;225 expect(event.address).to.be.equal(collectionAddress);226 expect(event.returnValues.from).to.be.equal(caller);227 expect(event.returnValues.to).to.be.equal('0x0000000000000000000000000000000000000000');228 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);229 }230 });231232 itEth('Can perform approve()', async ({helper}) => {233 const owner = await helper.eth.createAccountWithBalance(donor);234 const spender = helper.eth.createAccount();235236 const collection = await helper.nft.mintCollection(minter, {});237 const {tokenId} = await collection.mintToken(minter, {Ethereum: owner});238239 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);240 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);241242 {243 const result = await contract.methods.approve(spender, tokenId).send({from: owner});244245 const event = result.events.Approval;246 expect(event.address).to.be.equal(collectionAddress);247 expect(event.returnValues.owner).to.be.equal(owner);248 expect(event.returnValues.approved).to.be.equal(spender);249 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);250 }251 });252253 itEth('Can perform burnFromCross()', async ({helper}) => {254 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});255256 const owner = bob;257 const spender = await helper.eth.createAccountWithBalance(donor, 100n);258259 const token = await collection.mintToken(minter, {Substrate: owner.address});260261 const address = helper.ethAddress.fromCollectionId(collection.collectionId);262 const contract = helper.ethNativeContract.collection(address, 'nft');263264 {265 await token.approve(owner, {Ethereum: spender});266 const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);267 const result = await contract.methods.burnFromCross(ownerCross, token.tokenId).send({from: spender});268 const events = result.events.Transfer;269270 expect(events).to.be.like({271 address,272 event: 'Transfer',273 returnValues: {274 from: helper.address.substrateToEth(owner.address),275 to: '0x0000000000000000000000000000000000000000',276 tokenId: token.tokenId.toString(),277 },278 });279 }280 });281282 itEth('Can perform approveCross()', async ({helper}) => {283 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});284285 const owner = await helper.eth.createAccountWithBalance(donor, 100n);286 const receiver = charlie;287288 const token = await collection.mintToken(minter, {Ethereum: owner});289290 const address = helper.ethAddress.fromCollectionId(collection.collectionId);291 const contract = helper.ethNativeContract.collection(address, 'nft');292293 {294 const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);295 const result = await contract.methods.approveCross(recieverCross, token.tokenId).send({from: owner});296 const event = result.events.Approval;297 expect(event).to.be.like({298 address: helper.ethAddress.fromCollectionId(collection.collectionId),299 event: 'Approval',300 returnValues: {301 owner,302 approved: helper.address.substrateToEth(receiver.address),303 tokenId: token.tokenId.toString(),304 },305 });306 }307 });308309 itEth('Can perform transferFrom()', async ({helper}) => {310 const owner = await helper.eth.createAccountWithBalance(donor);311 const spender = await helper.eth.createAccountWithBalance(donor);312 const receiver = helper.eth.createAccount();313314 const collection = await helper.nft.mintCollection(minter, {});315 const {tokenId} = await collection.mintToken(minter, {Ethereum: owner});316317 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);318 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);319320 await contract.methods.approve(spender, tokenId).send({from: owner});321322 {323 const result = await contract.methods.transferFrom(owner, receiver, tokenId).send({from: spender});324325 const event = result.events.Transfer;326 expect(event.address).to.be.equal(collectionAddress);327 expect(event.returnValues.from).to.be.equal(owner);328 expect(event.returnValues.to).to.be.equal(receiver);329 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);330 }331332 {333 const balance = await contract.methods.balanceOf(receiver).call();334 expect(+balance).to.equal(1);335 }336337 {338 const balance = await contract.methods.balanceOf(owner).call();339 expect(+balance).to.equal(0);340 }341 });342343 itEth('Can perform transferFromCross()', async ({helper, privateKey}) => {344 const minter = await privateKey('//Alice');345 const collection = await helper.nft.mintCollection(minter, {name: 'A', description: 'B', tokenPrefix: 'C'});346347 const owner = await privateKey('//Bob');348 const spender = await helper.eth.createAccountWithBalance(donor);349 const receiver = await privateKey('//Charlie');350351 const token = await collection.mintToken(minter, {Substrate: owner.address});352353 const address = helper.ethAddress.fromCollectionId(collection.collectionId);354 const contract = helper.ethNativeContract.collection(address, 'nft');355356 await token.approve(owner, {Ethereum: spender});357358 {359 const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);360 const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);361 const result = await contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: spender});362 const event = result.events.Transfer;363 expect(event).to.be.like({364 address: helper.ethAddress.fromCollectionId(collection.collectionId),365 event: 'Transfer',366 returnValues: {367 from: helper.address.substrateToEth(owner.address),368 to: helper.address.substrateToEth(receiver.address),369 tokenId: token.tokenId.toString(),370 },371 });372 }373374 expect(await token.getOwner()).to.be.like({Substrate: receiver.address});375 });376377 itEth('Can perform transfer()', async ({helper}) => {378 const collection = await helper.nft.mintCollection(minter, {});379 const owner = await helper.eth.createAccountWithBalance(donor);380 const receiver = helper.eth.createAccount();381382 const {tokenId} = await collection.mintToken(minter, {Ethereum: owner});383384 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);385 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);386387 {388 const result = await contract.methods.transfer(receiver, tokenId).send({from: owner});389390 const event = result.events.Transfer;391 expect(event.address).to.be.equal(collectionAddress);392 expect(event.returnValues.from).to.be.equal(owner);393 expect(event.returnValues.to).to.be.equal(receiver);394 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);395 }396397 {398 const balance = await contract.methods.balanceOf(owner).call();399 expect(+balance).to.equal(0);400 }401402 {403 const balance = await contract.methods.balanceOf(receiver).call();404 expect(+balance).to.equal(1);405 }406 });407 408 itEth('Can perform transferCross()', async ({helper}) => {409 const collection = await helper.nft.mintCollection(minter, {});410 const owner = await helper.eth.createAccountWithBalance(donor);411 const receiver = await helper.eth.createAccountWithBalance(donor);412 const to = helper.ethCrossAccount.fromAddress(receiver);413 const toSubstrate = helper.ethCrossAccount.fromKeyringPair(minter);414 415 const {tokenId} = await collection.mintToken(minter, {Ethereum: owner});416417 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);418 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);419420 {421 const result = await contract.methods.transferCross(to, tokenId).send({from: owner});422423 const event = result.events.Transfer;424 expect(event.address).to.be.equal(collectionAddress);425 expect(event.returnValues.from).to.be.equal(owner);426 expect(event.returnValues.to).to.be.equal(receiver);427 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);428 }429430 {431 const balance = await contract.methods.balanceOf(owner).call();432 expect(+balance).to.equal(0);433 }434435 {436 const balance = await contract.methods.balanceOf(receiver).call();437 expect(+balance).to.equal(1);438 }439 440 {441 const substrateResult = await contract.methods.transferCross(toSubstrate, tokenId).send({from: receiver});442 443444 const event = substrateResult.events.Transfer;445 expect(event.address).to.be.equal(collectionAddress);446 expect(event.returnValues.from).to.be.equal(receiver);447 expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(minter.address));448 expect(event.returnValues.tokenId).to.be.equal(`${tokenId}`);449 }450451 {452 const balance = await contract.methods.balanceOf(receiver).call();453 expect(+balance).to.equal(0);454 }455456 {457 const balance = await helper.nft.getTokensByAddress(collection.collectionId, {Substrate: minter.address});458 expect(balance).to.be.contain(tokenId);459 }460 });461});462463describe('NFT: Fees', () => {464 let donor: IKeyringPair;465 let alice: IKeyringPair;466 let bob: IKeyringPair;467 let charlie: IKeyringPair;468469 before(async function() {470 await usingEthPlaygrounds(async (helper, privateKey) => {471 donor = await privateKey({filename: __filename});472 [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);473 });474 });475476 itEth('approve() call fee is less than 0.2UNQ', async ({helper}) => {477 const owner = await helper.eth.createAccountWithBalance(donor);478 const spender = helper.eth.createAccount();479480 const collection = await helper.nft.mintCollection(alice, {});481 const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});482483 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', owner);484485 const cost = await helper.eth.recordCallFee(owner, () => contract.methods.approve(spender, tokenId).send({from: owner}));486 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));487 });488489 itEth('transferFrom() call fee is less than 0.2UNQ', async ({helper}) => {490 const owner = await helper.eth.createAccountWithBalance(donor);491 const spender = await helper.eth.createAccountWithBalance(donor);492493 const collection = await helper.nft.mintCollection(alice, {});494 const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});495496 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', owner);497498 await contract.methods.approve(spender, tokenId).send({from: owner});499500 const cost = await helper.eth.recordCallFee(spender, () => contract.methods.transferFrom(owner, spender, tokenId).send({from: spender}));501 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));502 });503504 itEth('Can perform transferFromCross()', async ({helper, privateKey}) => {505 const collectionMinter = alice;506 const owner = bob;507 const receiver = charlie;508 const collection = await helper.nft.mintCollection(collectionMinter, {name: 'A', description: 'B', tokenPrefix: 'C'});509510 const spender = await helper.eth.createAccountWithBalance(donor, 100n);511512 const token = await collection.mintToken(collectionMinter, {Substrate: owner.address});513514 const address = helper.ethAddress.fromCollectionId(collection.collectionId);515 const contract = helper.ethNativeContract.collection(address, 'nft');516517 await token.approve(owner, {Ethereum: spender});518519 {520 const ownerCross = helper.ethCrossAccount.fromKeyringPair(owner);521 const recieverCross = helper.ethCrossAccount.fromKeyringPair(receiver);522 const result = await contract.methods.transferFromCross(ownerCross, recieverCross, token.tokenId).send({from: spender});523 const event = result.events.Transfer;524 expect(event).to.be.like({525 address: helper.ethAddress.fromCollectionId(collection.collectionId),526 event: 'Transfer',527 returnValues: {528 from: helper.address.substrateToEth(owner.address),529 to: helper.address.substrateToEth(receiver.address),530 tokenId: token.tokenId.toString(),531 },532 });533 }534535 expect(await token.getOwner()).to.be.like({Substrate: receiver.address});536 });537538 itEth('transfer() call fee is less than 0.2UNQ', async ({helper}) => {539 const owner = await helper.eth.createAccountWithBalance(donor);540 const receiver = helper.eth.createAccount();541542 const collection = await helper.nft.mintCollection(alice, {});543 const {tokenId} = await collection.mintToken(alice, {Ethereum: owner});544545 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', owner);546547 const cost = await helper.eth.recordCallFee(owner, () => contract.methods.transfer(receiver, tokenId).send({from: owner}));548 expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal())));549 });550});551552describe('NFT: Substrate calls', () => {553 let donor: IKeyringPair;554 let alice: IKeyringPair;555556 before(async function() {557 await usingEthPlaygrounds(async (helper, privateKey) => {558 donor = await privateKey({filename: __filename});559 [alice] = await helper.arrange.createAccounts([20n], donor);560 });561 });562563 itEth('Events emitted for mint()', async ({helper}) => {564 const collection = await helper.nft.mintCollection(alice, {});565 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);566 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');567568 const events: any = [];569 contract.events.allEvents((_: any, event: any) => {570 events.push(event);571 });572573 const {tokenId} = await collection.mintToken(alice);574 if (events.length == 0) await helper.wait.newBlocks(1);575 const event = events[0];576577 expect(event.event).to.be.equal('Transfer');578 expect(event.address).to.be.equal(collectionAddress);579 expect(event.returnValues.from).to.be.equal('0x0000000000000000000000000000000000000000');580 expect(event.returnValues.to).to.be.equal(helper.address.substrateToEth(alice.address));581 expect(event.returnValues.tokenId).to.be.equal(tokenId.toString());582 });583584 itEth('Events emitted for burn()', async ({helper}) => {585 const collection = await helper.nft.mintCollection(alice, {});586 const token = await collection.mintToken(alice);587588 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);589 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');590591 const events: any = [];592 contract.events.allEvents((_: any, event: any) => {593 events.push(event);594 });595596 await token.burn(alice);597 if (events.length == 0) await helper.wait.newBlocks(1);598 const event = events[0];599600 expect(event.event).to.be.equal('Transfer');601 expect(event.address).to.be.equal(collectionAddress);602 expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));603 expect(event.returnValues.to).to.be.equal('0x0000000000000000000000000000000000000000');604 expect(event.returnValues.tokenId).to.be.equal(token.tokenId.toString());605 });606607 itEth('Events emitted for approve()', async ({helper}) => {608 const receiver = helper.eth.createAccount();609610 const collection = await helper.nft.mintCollection(alice, {});611 const token = await collection.mintToken(alice);612613 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);614 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');615616 const events: any = [];617 contract.events.allEvents((_: any, event: any) => {618 events.push(event);619 });620621 await token.approve(alice, {Ethereum: receiver});622 if (events.length == 0) await helper.wait.newBlocks(1);623 const event = events[0];624625 expect(event.event).to.be.equal('Approval');626 expect(event.address).to.be.equal(collectionAddress);627 expect(event.returnValues.owner).to.be.equal(helper.address.substrateToEth(alice.address));628 expect(event.returnValues.approved).to.be.equal(receiver);629 expect(event.returnValues.tokenId).to.be.equal(token.tokenId.toString());630 });631632 itEth('Events emitted for transferFrom()', async ({helper}) => {633 const [bob] = await helper.arrange.createAccounts([10n], donor);634 const receiver = helper.eth.createAccount();635636 const collection = await helper.nft.mintCollection(alice, {});637 const token = await collection.mintToken(alice);638 await token.approve(alice, {Substrate: bob.address});639640 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);641 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');642643 const events: any = [];644 contract.events.allEvents((_: any, event: any) => {645 events.push(event);646 });647648 await token.transferFrom(bob, {Substrate: alice.address}, {Ethereum: receiver});649650 if (events.length == 0) await helper.wait.newBlocks(1);651 const event = events[0];652653 expect(event.address).to.be.equal(collectionAddress);654 expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));655 expect(event.returnValues.to).to.be.equal(receiver);656 expect(event.returnValues.tokenId).to.be.equal(`${token.tokenId}`);657 });658659 itEth('Events emitted for transfer()', async ({helper}) => {660 const receiver = helper.eth.createAccount();661662 const collection = await helper.nft.mintCollection(alice, {});663 const token = await collection.mintToken(alice);664665 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);666 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');667668 const events: any = [];669 contract.events.allEvents((_: any, event: any) => {670 events.push(event);671 });672673 await token.transfer(alice, {Ethereum: receiver});674675 if (events.length == 0) await helper.wait.newBlocks(1);676 const event = events[0];677678 expect(event.address).to.be.equal(collectionAddress);679 expect(event.returnValues.from).to.be.equal(helper.address.substrateToEth(alice.address));680 expect(event.returnValues.to).to.be.equal(receiver);681 expect(event.returnValues.tokenId).to.be.equal(`${token.tokenId}`);682 });683});684685describe('Common metadata', () => {686 let donor: IKeyringPair;687 let alice: IKeyringPair;688689 before(async function() {690 await usingEthPlaygrounds(async (helper, privateKey) => {691 donor = await privateKey({filename: __filename});692 [alice] = await helper.arrange.createAccounts([20n], donor);693 });694 });695696 itEth('Returns collection name', async ({helper}) => {697 const caller = await helper.eth.createAccountWithBalance(donor);698 const tokenPropertyPermissions = [{699 key: 'URI',700 permission: {701 mutable: true,702 collectionAdmin: true,703 tokenOwner: false,704 },705 }];706 const collection = await helper.nft.mintCollection(707 alice,708 {709 name: 'oh River',710 tokenPrefix: 'CHANGE',711 properties: [{key: 'ERC721Metadata', value: '1'}],712 tokenPropertyPermissions,713 },714 );715716 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);717 const name = await contract.methods.name().call();718 expect(name).to.equal('oh River');719 });720721 itEth('Returns symbol name', async ({helper}) => {722 const caller = await helper.eth.createAccountWithBalance(donor);723 const tokenPropertyPermissions = [{724 key: 'URI',725 permission: {726 mutable: true,727 collectionAdmin: true,728 tokenOwner: false,729 },730 }];731 const collection = await helper.nft.mintCollection(732 alice,733 {734 name: 'oh River',735 tokenPrefix: 'CHANGE',736 properties: [{key: 'ERC721Metadata', value: '1'}],737 tokenPropertyPermissions,738 },739 );740741 const contract = helper.ethNativeContract.collectionById(collection.collectionId, 'nft', caller);742 const symbol = await contract.methods.symbol().call();743 expect(symbol).to.equal('CHANGE');744 });745});tests/src/util/playgrounds/unique.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -2429,7 +2429,7 @@
* @param ethCrossAccount etherium cross account
* @returns substrate cross account id
*/
- convertCrossAccountFromEthCrossAcoount(ethCrossAccount: IEthCrossAccountId): ICrossAccountId {
+ convertCrossAccountFromEthCrossAccount(ethCrossAccount: IEthCrossAccountId): ICrossAccountId {
if (ethCrossAccount.sub === '0') {
return {Ethereum: ethCrossAccount.eth.toLocaleLowerCase()};
}