difftreelog
fix tests cleanup
in: master
10 files changed
tests/src/eth/collectionLimits.test.tsdiffbeforeafterboth--- a/tests/src/eth/collectionLimits.test.ts
+++ b/tests/src/eth/collectionLimits.test.ts
@@ -97,7 +97,7 @@
const owner = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress} = await helper.eth.createCollection(owner, new CreateCollectionData('Limits', 'absolutely anything', 'ISNI', testCase.case, 18)).send();
- const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, testCase.case, owner);
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, testCase.case, owner);
// Cannot set non-existing limit
await expect(collectionEvm.methods
tests/src/eth/createCollection.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.8//9// 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 {IKeyringPair} from '@polkadot/types/types';18import {evmToAddress} from '@polkadot/util-crypto';19import {Pallets, requirePalletsOrSkip} from '../util';20import {expect, itEth, usingEthPlaygrounds} from './util';21import {CREATE_COLLECTION_DATA_DEFAULTS, CollectionLimitField, CollectionMode, CreateCollectionData, TokenPermissionField, emptyAddress} from './util/playgrounds/types';22import {CollectionFlag, IEthCrossAccountId, TCollectionMode} from '../util/playgrounds/types';2324const DECIMALS = 18;25const CREATE_COLLECTION_DATA_DEFAULTS_ARRAY = [26 [],27 [],28 [],29 [false, false, []],30 [],31 [0],32];3334type ElementOf<A> = A extends readonly (infer T)[] ? T : never;35function* cartesian<T extends Array<Array<any>>, R extends Array<any>>(internalRest: [...R], ...args: [...T]): Generator<[...R, ...{[K in keyof T]: ElementOf<T[K]>}]> {36 if(args.length === 0) {37 yield internalRest as any;38 return;39 }40 for(const value of args[0]) {41 yield* cartesian([...internalRest, value], ...args.slice(1)) as any;42 }43}4445describe('Create collection from EVM', () => {46 let donor: IKeyringPair;47 let nominal: bigint;4849 before(async function() {50 await usingEthPlaygrounds(async (helper, privateKey) => {51 donor = await privateKey({url: import.meta.url});52 nominal = helper.balance.getOneTokenNominal();53 });54 });5556 describe('Fungible collection', () => {57 before(async function() {58 await usingEthPlaygrounds((helper) => {59 requirePalletsOrSkip(this, helper, [Pallets.Fungible]);60 return Promise.resolve();61 });62 });6364 itEth('Collection address exist', async ({helper}) => {65 const owner = await helper.eth.createAccountWithBalance(donor);66 const collectionAddressForNonexistentCollection = '0x17C4E6453CC49AAAAEACA894E6D9683E00112233';67 const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);6869 expect(await collectionHelpers70 .methods.isCollectionExist(collectionAddressForNonexistentCollection).call())71 .to.be.false;7273 const {collectionAddress} = await helper.eth.createCollection(owner, new CreateCollectionData('Exister', 'absolutely anything', 'WIWT', 'ft', DECIMALS)).send();74 expect(await collectionHelpers75 .methods.isCollectionExist(collectionAddress).call())76 .to.be.true;7778 // check collectionOwner:79 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);80 const collectionOwner = await collectionEvm.methods.collectionOwner().call();81 expect(helper.address.restoreCrossAccountFromBigInt(BigInt(collectionOwner.sub))).to.eq(helper.address.ethToSubstrate(owner, true));82 });8384 itEth('destroyCollection', async ({helper}) => {85 const owner = await helper.eth.createAccountWithBalance(donor);86 const {collectionAddress, collectionId} = await helper.eth.createCollection(owner, new CreateCollectionData('Exister', 'absolutely anything', 'WIWT', 'ft', DECIMALS)).send();87 const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);8889 const result = await collectionHelper.methods90 .destroyCollection(collectionAddress)91 .send({from: owner});9293 const events = helper.eth.normalizeEvents(result.events);9495 expect(events).to.be.deep.equal([96 {97 address: collectionHelper.options.address,98 event: 'CollectionDestroyed',99 args: {100 collectionId: collectionAddress,101 },102 },103 ]);104105 expect(await collectionHelper.methods106 .isCollectionExist(collectionAddress)107 .call()).to.be.false;108 expect(await helper.collection.getData(collectionId)).to.be.null;109 });110111 itEth('(!negative test!) Create collection (bad lengths)', async ({helper}) => {112 const owner = await helper.eth.createAccountWithBalance(donor);113 const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);114 {115 const MAX_NAME_LENGTH = 64;116 const collectionName = 'A'.repeat(MAX_NAME_LENGTH + 1);117 const description = 'A';118 const tokenPrefix = 'A';119120 await expect(collectionHelper.methods121 .createCollection([122 emptyAddress,123 collectionName,124 description,125 tokenPrefix,126 CollectionMode.Fungible,127 DECIMALS,128 ...CREATE_COLLECTION_DATA_DEFAULTS_ARRAY,129 ])130 .call({value: Number(2n * nominal)})).to.be.rejectedWith('name is too long. Max length is ' + MAX_NAME_LENGTH);131 }132 {133 const MAX_DESCRIPTION_LENGTH = 256;134 const collectionName = 'A';135 const description = 'A'.repeat(MAX_DESCRIPTION_LENGTH + 1);136 const tokenPrefix = 'A';137 await expect(collectionHelper.methods138 .createCollection([139 emptyAddress,140 collectionName,141 description,142 tokenPrefix,143 CollectionMode.Fungible,144 DECIMALS,145 ...CREATE_COLLECTION_DATA_DEFAULTS_ARRAY,146 ])147 .call({value: Number(2n * nominal)})).to.be.rejectedWith('description is too long. Max length is ' + MAX_DESCRIPTION_LENGTH);148 }149 {150 const MAX_TOKEN_PREFIX_LENGTH = 16;151 const collectionName = 'A';152 const description = 'A';153 const tokenPrefix = 'A'.repeat(MAX_TOKEN_PREFIX_LENGTH + 1);154 await expect(collectionHelper.methods155 .createCollection([156 emptyAddress,157 collectionName,158 description,159 tokenPrefix,160 CollectionMode.Fungible,161 DECIMALS,162 ...CREATE_COLLECTION_DATA_DEFAULTS_ARRAY,163 ])164 .call({value: Number(2n * nominal)})).to.be.rejectedWith('token_prefix is too long. Max length is ' + MAX_TOKEN_PREFIX_LENGTH);165 }166 });167168 itEth('(!negative test!) cannot create collection if value !== 2', async ({helper}) => {169 const owner = await helper.eth.createAccountWithBalance(donor);170 const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);171 const expects = [0n, 1n, 30n].map(async value => {172 await expect(collectionHelper.methods173 .createCollection([174 emptyAddress,175 'Peasantry',176 'absolutely anything',177 'TWIW',178 CollectionMode.Fungible,179 DECIMALS,180 ...CREATE_COLLECTION_DATA_DEFAULTS_ARRAY,181 ])182 .call({value: Number(value * nominal)})).to.be.rejectedWith('Sent amount not equals to collection creation price (2000000000000000000)');183 });184 await Promise.all(expects);185 });186 });187188 describe('Nonfungible collection', () => {189 before(async function() {190 await usingEthPlaygrounds((helper) => {191 requirePalletsOrSkip(this, helper, [Pallets.NFT]);192 return Promise.resolve();193 });194 });195196 itEth('Create collection', async ({helper}) => {197 const owner = await helper.eth.createAccountWithBalance(donor);198199 const name = 'CollectionEVM';200 const description = 'Some description';201 const prefix = 'token prefix';202203 // todo:playgrounds this might fail when in async environment.204 const collectionCountBefore = +(await helper.callRpc('api.rpc.unique.collectionStats')).created;205 const {collectionId, collectionAddress, events} = await helper.eth.createCollection(owner, new CreateCollectionData(name, description, prefix, 'nft')).send();206207 expect(events).to.be.deep.equal([208 {209 address: '0x6C4E9fE1AE37a41E93CEE429e8E1881aBdcbb54F',210 event: 'CollectionCreated',211 args: {212 owner: owner,213 collectionId: collectionAddress,214 },215 },216 ]);217218 const collectionCountAfter = +(await helper.callRpc('api.rpc.unique.collectionStats')).created;219220 const collection = helper.nft.getCollectionObject(collectionId);221 const data = (await collection.getData())!;222223 expect(collectionCountAfter - collectionCountBefore).to.be.eq(1);224 expect(collectionId).to.be.eq(collectionCountAfter);225 expect(data.name).to.be.eq(name);226 expect(data.description).to.be.eq(description);227 expect(data.raw.tokenPrefix).to.be.eq(prefix);228 expect(data.raw.mode).to.be.eq('NFT');229230 const options = await collection.getOptions();231232 expect(options.tokenPropertyPermissions).to.be.empty;233 });234235 // this test will occasionally fail when in async environment.236 itEth('Check collection address exist', async ({helper}) => {237 const owner = await helper.eth.createAccountWithBalance(donor);238239 const expectedCollectionId = +(await helper.callRpc('api.rpc.unique.collectionStats')).created + 1;240 const expectedCollectionAddress = helper.ethAddress.fromCollectionId(expectedCollectionId);241 const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);242243 expect(await collectionHelpers.methods244 .isCollectionExist(expectedCollectionAddress)245 .call()).to.be.false;246247 await collectionHelpers.methods248 .createCollection([249 emptyAddress,250 'A',251 'A',252 'A',253 CollectionMode.Nonfungible,254 0,255 ...CREATE_COLLECTION_DATA_DEFAULTS_ARRAY,256 ])257 .send({value: Number(2n * helper.balance.getOneTokenNominal())});258259 expect(await collectionHelpers.methods260 .isCollectionExist(expectedCollectionAddress)261 .call()).to.be.true;262 });263 });264265 describe('Create RFT collection from EVM', () => {266 before(async function() {267 await usingEthPlaygrounds((helper) => {268 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);269 return Promise.resolve();270 });271 });272273 itEth('Create collection', async ({helper}) => {274 const owner = await helper.eth.createAccountWithBalance(donor);275276 const name = 'CollectionEVM';277 const description = 'Some description';278 const prefix = 'token prefix';279280 const {collectionId} = await helper.eth.createCollection(owner, new CreateCollectionData(name, description, prefix, 'rft')).send();281 const data = (await helper.rft.getData(collectionId))!;282 const collection = helper.rft.getCollectionObject(collectionId);283284 expect(data.name).to.be.eq(name);285 expect(data.description).to.be.eq(description);286 expect(data.raw.tokenPrefix).to.be.eq(prefix);287 expect(data.raw.mode).to.be.eq('ReFungible');288289 const options = await collection.getOptions();290291 expect(options.tokenPropertyPermissions).to.be.empty;292 });293294 itEth('Create collection with properties & get description', async ({helper}) => {295 const owner = await helper.eth.createAccountWithBalance(donor);296297 const name = 'CollectionEVM';298 const description = 'Some description';299 const prefix = 'token prefix';300 const baseUri = 'BaseURI';301302 const {collectionId, collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, name, description, prefix, baseUri);303 const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');304305 const collection = helper.rft.getCollectionObject(collectionId);306 const data = (await collection.getData())!;307308 expect(data.name).to.be.eq(name);309 expect(data.description).to.be.eq(description);310 expect(data.raw.tokenPrefix).to.be.eq(prefix);311 expect(data.raw.mode).to.be.eq('ReFungible');312313 expect(await contract.methods.description().call()).to.deep.equal(description);314315 const options = await collection.getOptions();316 expect(options.tokenPropertyPermissions).to.be.deep.equal([317 {318 key: 'URI',319 permission: {mutable: true, collectionAdmin: true, tokenOwner: false},320 },321 {322 key: 'URISuffix',323 permission: {mutable: true, collectionAdmin: true, tokenOwner: false},324 },325 ]);326 });327328 itEth('Set sponsorship', async ({helper}) => {329 const owner = await helper.eth.createAccountWithBalance(donor);330 const sponsor = await helper.eth.createAccountWithBalance(donor);331 const ss58Format = helper.chain.getChainProperties().ss58Format;332 const {collectionId, collectionAddress} = await helper.eth.createCollection(owner, new CreateCollectionData('Sponsor', 'absolutely anything', 'ENVY', 'rft')).send();333334 const collection = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner);335 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);336 await collection.methods.setCollectionSponsorCross(sponsorCross).send();337338 let data = (await helper.rft.getData(collectionId))!;339 expect(data.raw.sponsorship.Unconfirmed).to.be.equal(evmToAddress(sponsor, Number(ss58Format)));340341 await expect(collection.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');342343 const sponsorCollection = await helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor);344 await sponsorCollection.methods.confirmCollectionSponsorship().send();345346 data = (await helper.rft.getData(collectionId))!;347 expect(data.raw.sponsorship.Confirmed).to.be.equal(evmToAddress(sponsor, Number(ss58Format)));348 });349350 itEth('Collection address exist', async ({helper}) => {351 const owner = await helper.eth.createAccountWithBalance(donor);352 const collectionAddressForNonexistentCollection = '0x17C4E6453CC49AAAAEACA894E6D9683E00112233';353 const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);354355 expect(await collectionHelpers356 .methods.isCollectionExist(collectionAddressForNonexistentCollection).call())357 .to.be.false;358359 const {collectionAddress} = await helper.eth.createCollection(owner, new CreateCollectionData('Exister', 'absolutely anything', 'WIWT', 'rft')).send();360 expect(await collectionHelpers361 .methods.isCollectionExist(collectionAddress).call())362 .to.be.true;363364 // check collectionOwner:365 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);366 const collectionOwner = await collectionEvm.methods.collectionOwner().call();367 expect(helper.address.restoreCrossAccountFromBigInt(BigInt(collectionOwner.sub))).to.eq(helper.address.ethToSubstrate(owner, true));368 });369370 itEth('destroyCollection', async ({helper}) => {371 const owner = await helper.eth.createAccountWithBalance(donor);372 const {collectionAddress, collectionId} = await helper.eth.createCollection(owner, new CreateCollectionData('Limits', 'absolutely anything', 'OLF', 'rft')).send();373 const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);374375 await expect(collectionHelper.methods376 .destroyCollection(collectionAddress)377 .send({from: owner})).to.be.fulfilled;378379 expect(await collectionHelper.methods380 .isCollectionExist(collectionAddress)381 .call()).to.be.false;382 expect(await helper.collection.getData(collectionId)).to.be.null;383 });384385 itEth('(!negative test!) Create collection (bad lengths)', async ({helper}) => {386 const owner = await helper.eth.createAccountWithBalance(donor);387 const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);388 {389 const MAX_NAME_LENGTH = 64;390 const collectionName = 'A'.repeat(MAX_NAME_LENGTH + 1);391 const description = 'A';392 const tokenPrefix = 'A';393394 await expect(collectionHelper.methods395 .createCollection([396 emptyAddress,397 collectionName,398 description,399 tokenPrefix,400 CollectionMode.Refungible,401 DECIMALS,402 ...CREATE_COLLECTION_DATA_DEFAULTS_ARRAY,403 ])404 .call({value: Number(2n * nominal)})).to.be.rejectedWith('name is too long. Max length is ' + MAX_NAME_LENGTH);405 }406 {407 const MAX_DESCRIPTION_LENGTH = 256;408 const collectionName = 'A';409 const description = 'A'.repeat(MAX_DESCRIPTION_LENGTH + 1);410 const tokenPrefix = 'A';411 await expect(collectionHelper.methods412 .createCollection([413 emptyAddress,414 collectionName,415 description,416 tokenPrefix,417 CollectionMode.Refungible,418 DECIMALS,419 ...CREATE_COLLECTION_DATA_DEFAULTS_ARRAY,420 ])421 .call({value: Number(2n * nominal)})).to.be.rejectedWith('description is too long. Max length is ' + MAX_DESCRIPTION_LENGTH);422 }423 {424 const MAX_TOKEN_PREFIX_LENGTH = 16;425 const collectionName = 'A';426 const description = 'A';427 const tokenPrefix = 'A'.repeat(MAX_TOKEN_PREFIX_LENGTH + 1);428 await expect(collectionHelper.methods429 .createCollection([430 emptyAddress,431 collectionName,432 description,433 tokenPrefix,434 CollectionMode.Refungible,435 DECIMALS,436 ...CREATE_COLLECTION_DATA_DEFAULTS_ARRAY,437 ])438 .call({value: Number(2n * nominal)})).to.be.rejectedWith('token_prefix is too long. Max length is ' + MAX_TOKEN_PREFIX_LENGTH);439 }440 });441442 itEth('(!negative test!) Create collection (no funds)', async ({helper}) => {443 const owner = await helper.eth.createAccountWithBalance(donor);444 const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);445 await expect(collectionHelper.methods446 .createCollection([447 emptyAddress,448 'Peasantry',449 'absolutely anything',450 'TWIW',451 CollectionMode.Refungible,452 0,453 ...CREATE_COLLECTION_DATA_DEFAULTS_ARRAY,454 ])455 .call({value: Number(1n * nominal)})).to.be.rejectedWith('Sent amount not equals to collection creation price (2000000000000000000)');456 });457 });458459 describe('Sponsoring', () => {460 itEth('Сan remove collection sponsor', async ({helper}) => {461 const owner = await helper.eth.createAccountWithBalance(donor);462 const sponsor = await helper.eth.createAccountWithBalance(donor);463 const sponsorCross = helper.ethCrossAccount.fromAddr(sponsor);464465 const {collectionAddress} = await helper.eth.createCollection(466 owner,467 {468 ...CREATE_COLLECTION_DATA_DEFAULTS,469 name: 'Sponsor collection',470 description: '1',471 tokenPrefix: '1',472 collectionMode: 'nft',473 pendingSponsor: sponsorCross,474 },475 ).send();476 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner);477478 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.true;479480 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});481 let sponsorStruct = await collectionEvm.methods.collectionSponsor().call({from: owner});482 expect(helper.address.restoreCrossAccountFromBigInt(BigInt(sponsorStruct.sub))).to.be.eq(helper.address.ethToSubstrate(sponsor, true));483 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;484485 await collectionEvm.methods.removeCollectionSponsor().send({from: owner});486487 sponsorStruct = await collectionEvm.methods.collectionSponsor().call({from: owner});488 expect(sponsorStruct.eth).to.be.eq('0x0000000000000000000000000000000000000000');489 });490491 itEth('Can sponsor from evm address via access list', async ({helper}) => {492 const owner = await helper.eth.createAccountWithBalance(donor);493 const sponsorEth = await helper.eth.createAccountWithBalance(donor);494 const sponsorCross = helper.ethCrossAccount.fromAddr(sponsorEth);495496 const {collectionId, collectionAddress} = await helper.eth.createERC721MetadataCompatibleCollection(497 owner,498 {499 ...CREATE_COLLECTION_DATA_DEFAULTS,500 name: 'Sponsor collection',501 description: '1',502 tokenPrefix: '1',503 collectionMode: 'nft',504 pendingSponsor: sponsorCross,505 limits: [{field: CollectionLimitField.SponsoredDataRateLimit, value: 30n}],506 tokenPropertyPermissions: [{key: 'key', permissions: [{code: TokenPermissionField.TokenOwner, value: true}]}],507 },508 '',509 );510511 const collectionSub = helper.nft.getCollectionObject(collectionId);512 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner);513514 let sponsorship = (await collectionSub.getData())!.raw.sponsorship;515 expect(sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsorEth, true));516 // Account cannot confirm sponsorship if it is not set as a sponsor517 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');518519 // Sponsor can confirm sponsorship:520 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsorEth});521 sponsorship = (await collectionSub.getData())!.raw.sponsorship;522 expect(sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsorEth, true));523524 // Create user with no balance:525 const user = helper.ethCrossAccount.createAccount();526 const nextTokenId = await collectionEvm.methods.nextTokenId().call();527 expect(nextTokenId).to.be.equal('1');528529 // Set collection permissions:530 const oldPermissions = (await collectionSub.getData())!.raw.permissions;531 expect(oldPermissions.mintMode).to.be.false;532 expect(oldPermissions.access).to.be.equal('Normal');533534 await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner});535 await collectionEvm.methods.addToCollectionAllowListCross(user).send({from: owner});536 await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});537538 const newPermissions = (await collectionSub.getData())!.raw.permissions;539 expect(newPermissions.mintMode).to.be.true;540 expect(newPermissions.access).to.be.equal('AllowList');541542 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));543 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));544 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user.eth));545546 // User can mint token without balance:547 {548 const result = await collectionEvm.methods.mintCross(user, [{key: 'key', value: Buffer.from('Value')}]).send({from: user.eth});549 const event = helper.eth.normalizeEvents(result.events)550 .find(event => event.event === 'Transfer');551552 expect(event).to.be.deep.equal({553 address: collectionAddress,554 event: 'Transfer',555 args: {556 from: '0x0000000000000000000000000000000000000000',557 to: user.eth,558 tokenId: '1',559 },560 });561562 // await collectionEvm.methods.setProperties(1, [{key: 'key', value: Buffer.from('Value1')}]).send({from: user.eth});563564 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));565 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));566 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user.eth));567568 expect(await collectionEvm.methods.properties(nextTokenId, []).call())569 .to.be.like([570 [571 'key',572 '0x' + Buffer.from('Value').toString('hex'),573 ],574 ]);575 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);576 expect(userBalanceAfter).to.be.eq(userBalanceBefore);577 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;578 }579 });580581 itEth('Check that transaction via EVM spend money from sponsor address', async ({helper}) => {582 const owner = await helper.eth.createAccountWithBalance(donor);583 const sponsor = await helper.eth.createAccountWithBalance(donor);584 const sponsorCross = helper.ethCrossAccount.fromAddr(sponsor);585 const user = helper.eth.createAccount();586 const userCross = helper.ethCrossAccount.fromAddress(user);587588 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleCollection(589 owner,590 {591 ...CREATE_COLLECTION_DATA_DEFAULTS,592 name: 'Sponsor collection',593 description: '1',594 tokenPrefix: '1',595 collectionMode: 'nft',596 pendingSponsor: sponsorCross,597 adminList: [userCross],598 },599 '',600 );601602 const collectionSub = helper.nft.getCollectionObject(collectionId);603 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner);604 // Set collection sponsor:605 let collectionData = (await collectionSub.getData())!;606 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));607 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');608609 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});610 collectionData = (await collectionSub.getData())!;611 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));612613 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));614 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));615616 const mintingResult = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});617 const tokenId = mintingResult.events.Transfer.returnValues.tokenId;618619 const event = helper.eth.normalizeEvents(mintingResult.events)620 .find(event => event.event === 'Transfer');621 const address = helper.ethAddress.fromCollectionId(collectionId);622623 expect(event).to.be.deep.equal({624 address,625 event: 'Transfer',626 args: {627 from: '0x0000000000000000000000000000000000000000',628 to: user,629 tokenId: '1',630 },631 });632 expect(await collectionEvm.methods.tokenURI(tokenId).call({from: user})).to.be.equal('Test URI');633634 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));635 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);636 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));637 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;638 });639640 itEth('Can reassign collection sponsor', async ({helper}) => {641 const owner = await helper.eth.createAccountWithBalance(donor);642 const sponsorEth = await helper.eth.createAccountWithBalance(donor);643 const sponsorCrossEth = helper.ethCrossAccount.fromAddr(sponsorEth);644 const [sponsorSub] = await helper.arrange.createAccounts([100n], donor);645 const sponsorCrossSub = helper.ethCrossAccount.fromKeyringPair(sponsorSub);646647 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleCollection(648 owner,649 {650 ...CREATE_COLLECTION_DATA_DEFAULTS,651 name: 'Sponsor collection',652 description: '1',653 tokenPrefix: '1',654 collectionMode: 'nft',655 pendingSponsor: sponsorCrossEth,656 },657 '',658 );659 const collectionSub = helper.nft.getCollectionObject(collectionId);660 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner);661662 // Set and confirm sponsor:663 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsorEth});664665 // Can reassign sponsor:666 await collectionEvm.methods.setCollectionSponsorCross(sponsorCrossSub).send({from: owner});667 const collectionSponsor = (await collectionSub.getData())?.raw.sponsorship;668 expect(collectionSponsor).to.deep.eq({Unconfirmed: sponsorSub.address});669 });670671 [672 'transfer',673 'transferCross',674 'transferFrom',675 'transferFromCross',676 ].map(testCase =>677 itEth(`[${testCase}] Check that transfer via EVM spend money from sponsor address`, async ({helper}) => {678 const owner = await helper.eth.createAccountWithBalance(donor);679 const sponsor = await helper.eth.createAccountWithBalance(donor);680 const sponsorCross = helper.ethCrossAccount.fromAddr(sponsor);681 const user = await helper.eth.createAccountWithBalance(donor);682 const userCross = helper.ethCrossAccount.fromAddress(user);683684 const {collectionAddress} = await helper.eth.createERC721MetadataCompatibleCollection(685 owner,686 {687 ...CREATE_COLLECTION_DATA_DEFAULTS,688 name: 'Sponsor collection',689 description: '1',690 tokenPrefix: '1',691 collectionMode: 'rft',692 pendingSponsor: sponsorCross,693 adminList: [userCross],694 },695 '',696 );697 const receiver = await helper.eth.createAccountWithBalance(donor);698 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner);699700 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});701702 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});703 const tokenId = result.events.Transfer.returnValues.tokenId;704705 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));706 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));707 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));708709 switch (testCase) {710 case 'transfer':711 await collectionEvm.methods.transfer(receiver, tokenId).send({from: user});712 break;713 case 'transferCross':714 await collectionEvm.methods.transferCross(helper.ethCrossAccount.fromAddress(receiver), tokenId).send({from: user});715 break;716 case 'transferFrom':717 await collectionEvm.methods.transferFrom(user, receiver, tokenId).send({from: user});718 break;719 case 'transferFromCross':720 await collectionEvm.methods.transferFromCross(helper.ethCrossAccount.fromAddress(user), helper.ethCrossAccount.fromAddress(receiver), tokenId).send({from: user});721 break;722 }723724 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));725 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);726 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));727 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;728 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));729 expect(userBalanceAfter).to.be.eq(userBalanceBefore);730 }));731 });732733 describe('Collection admins', () => {734 let donor: IKeyringPair;735736 before(async function() {737 await usingEthPlaygrounds(async (_helper, privateKey) => {738 donor = await privateKey({url: import.meta.url});739 });740 });741742 [743 {mode: 'nft' as const, requiredPallets: []},744 {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},745 {mode: 'ft' as const, requiredPallets: []},746 ].map(testCase => {747 itEth.ifWithPallets(`can add account admin by owner for ${testCase.mode}`, testCase.requiredPallets, async ({helper, privateKey}) => {748 // arrange749 const owner = await helper.eth.createAccountWithBalance(donor);750 const adminSub = await privateKey('//admin2');751 const adminEth = helper.eth.createAccount().toLowerCase();752753 const adminCrossSub = helper.ethCrossAccount.fromKeyringPair(adminSub);754 const adminCrossEth = helper.ethCrossAccount.fromAddress(adminEth);755756 const {collectionAddress, collectionId} = await helper.eth.createCollection(757 owner,758 {759 ...CREATE_COLLECTION_DATA_DEFAULTS,760 name: 'Mint collection',761 description: 'a',762 tokenPrefix: 'b',763 collectionMode: testCase.mode,764 adminList: [adminCrossSub, adminCrossEth],765 },766 ).send();767 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, testCase.mode, owner, true);768769 // 1. Expect api.rpc.unique.adminlist returns admins:770 const adminListRpc = await helper.collection.getAdmins(collectionId);771 expect(adminListRpc).to.has.length(2);772 expect(adminListRpc).to.be.deep.contain.members([{Substrate: adminSub.address}, {Ethereum: adminEth}]);773774 // 2. Expect methods.collectionAdmins == api.rpc.unique.adminlist775 let adminListEth = await collectionEvm.methods.collectionAdmins().call();776 adminListEth = adminListEth.map((element: IEthCrossAccountId) => helper.address.convertCrossAccountFromEthCrossAccount(element));777 expect(adminListRpc).to.be.like(adminListEth);778779 // 3. check isOwnerOrAdminCross returns true:780 expect(await collectionEvm.methods.isOwnerOrAdminCross(adminCrossSub).call()).to.be.true;781 expect(await collectionEvm.methods.isOwnerOrAdminCross(adminCrossEth).call()).to.be.true;782 });783 });784785 itEth('cross account admin can mint', async ({helper}) => {786 // arrange: create collection and accounts787 const owner = await helper.eth.createAccountWithBalance(donor);788 const adminEth = (await helper.eth.createAccountWithBalance(donor)).toLowerCase();789 const adminCrossEth = helper.ethCrossAccount.fromAddress(adminEth);790 const [adminSub] = await helper.arrange.createAccounts([100n], donor);791 const adminCrossSub = helper.ethCrossAccount.fromKeyringPair(adminSub);792 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleCollection(793 owner,794 {795 ...CREATE_COLLECTION_DATA_DEFAULTS,796 name: 'Mint collection',797 description: 'a',798 tokenPrefix: 'b',799 collectionMode: 'nft',800 adminList: [adminCrossSub, adminCrossEth],801 },802 'uri',803 );804 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner, true);805806 // admin (sub and eth) can mint token:807 await collectionEvm.methods.mint(owner).send({from: adminEth});808 await helper.nft.mintToken(adminSub, {collectionId, owner: {Ethereum: owner}});809810 expect(await helper.collection.getLastTokenId(collectionId)).to.eq(2);811 });812813 itEth('cannot add invalid cross account admin', async ({helper}) => {814 const owner = await helper.eth.createAccountWithBalance(donor);815 const [admin] = await helper.arrange.createAccounts([100n, 100n], donor);816817 const adminCross = {818 eth: helper.address.substrateToEth(admin.address),819 sub: admin.addressRaw,820 };821822 await expect(helper.eth.createCollection(823 owner,824 {825 ...CREATE_COLLECTION_DATA_DEFAULTS,826 name: 'A',827 description: 'B',828 tokenPrefix: 'C',829 collectionMode: 'nft',830 adminList: [adminCross],831 },832 ).call()).to.be.rejected;833 });834835 itEth('Remove [cross] admin by owner', async ({helper}) => {836 const owner = await helper.eth.createAccountWithBalance(donor);837838 const [adminSub] = await helper.arrange.createAccounts([10n], donor);839 const adminEth = (await helper.eth.createAccountWithBalance(donor)).toLowerCase();840 const adminCrossSub = helper.ethCrossAccount.fromKeyringPair(adminSub);841 const adminCrossEth = helper.ethCrossAccount.fromAddress(adminEth);842843 const {collectionAddress, collectionId} = await helper.eth.createCollection(844 owner,845 {846 ...CREATE_COLLECTION_DATA_DEFAULTS,847 name: 'A',848 description: 'B',849 tokenPrefix: 'C',850 collectionMode: 'nft',851 adminList: [adminCrossSub, adminCrossEth],852 },853 ).send();854855 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner);856857 {858 const adminList = await helper.collection.getAdmins(collectionId);859 expect(adminList).to.deep.include({Substrate: adminSub.address});860 expect(adminList).to.deep.include({Ethereum: adminEth});861 }862863 await collectionEvm.methods.removeCollectionAdminCross(adminCrossSub).send();864 await collectionEvm.methods.removeCollectionAdminCross(adminCrossEth).send();865 const adminList = await helper.collection.getAdmins(collectionId);866 expect(adminList.length).to.be.eq(0);867868 // Non admin cannot mint:869 await expect(helper.nft.mintToken(adminSub, {collectionId, owner: {Substrate: adminSub.address}})).to.be.rejectedWith(/common.PublicMintingNotAllowed/);870 await expect(collectionEvm.methods.mint(adminEth).send({from: adminEth})).to.be.rejected;871 });872 });873874 describe('Collection limits', () => {875 describe('Can set collection limits', () => {876 [877 {case: 'nft' as const},878 {case: 'rft' as const, requiredPallets: [Pallets.ReFungible]},879 {case: 'ft' as const},880 ].map(testCase =>881 itEth.ifWithPallets(`for ${testCase.case}`, testCase.requiredPallets || [], async ({helper}) => {882 const owner = await helper.eth.createAccountWithBalance(donor);883884 const limits = {885 accountTokenOwnershipLimit: 1000n,886 sponsoredDataSize: 1024n,887 sponsoredDataRateLimit: 30n,888 tokenLimit: 1000000n,889 sponsorTransferTimeout: 6n,890 sponsorApproveTimeout: 6n,891 ownerCanTransfer: 1n,892 ownerCanDestroy: 0n,893 transfersEnabled: 0n,894 };895896 const {collectionId, collectionAddress} = await helper.eth.createCollection(897 owner,898 {899 ...CREATE_COLLECTION_DATA_DEFAULTS,900 name: 'Limits',901 description: 'absolutely anything',902 tokenPrefix: 'FLO',903 collectionMode: testCase.case,904 limits: [905 {field: CollectionLimitField.AccountTokenOwnership, value: limits.accountTokenOwnershipLimit},906 {field: CollectionLimitField.SponsoredDataSize, value: limits.sponsoredDataSize},907 {field: CollectionLimitField.SponsoredDataRateLimit, value: limits.sponsoredDataRateLimit},908 {field: CollectionLimitField.TokenLimit, value: limits.tokenLimit},909 {field: CollectionLimitField.SponsorTransferTimeout, value: limits.sponsorTransferTimeout},910 {field: CollectionLimitField.SponsorApproveTimeout, value: limits.sponsorApproveTimeout},911 {field: CollectionLimitField.OwnerCanTransfer, value: limits.ownerCanTransfer},912 {field: CollectionLimitField.OwnerCanDestroy, value: limits.ownerCanDestroy},913 {field: CollectionLimitField.TransferEnabled, value: limits.transfersEnabled},914 ],915 },916 ).send();917918 const expectedLimits = {919 accountTokenOwnershipLimit: 1000,920 sponsoredDataSize: 1024,921 sponsoredDataRateLimit: {blocks: 30},922 tokenLimit: 1000000,923 sponsorTransferTimeout: 6,924 sponsorApproveTimeout: 6,925 ownerCanTransfer: true,926 ownerCanDestroy: false,927 transfersEnabled: false,928 };929930 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, testCase.case, owner);931932 // Check limits from sub:933 const data = (await helper.rft.getData(collectionId))!;934 expect(data.raw.limits).to.deep.eq(expectedLimits);935 expect(await helper.collection.getEffectiveLimits(collectionId)).to.deep.eq(expectedLimits);936 // Check limits from eth:937 const limitsEvm = await collectionEvm.methods.collectionLimits().call({from: owner});938 expect(limitsEvm).to.have.length(9);939 expect(limitsEvm[0]).to.deep.eq([CollectionLimitField.AccountTokenOwnership.toString(), [true, limits.accountTokenOwnershipLimit.toString()]]);940 expect(limitsEvm[1]).to.deep.eq([CollectionLimitField.SponsoredDataSize.toString(), [true, limits.sponsoredDataSize.toString()]]);941 expect(limitsEvm[2]).to.deep.eq([CollectionLimitField.SponsoredDataRateLimit.toString(), [true, limits.sponsoredDataRateLimit.toString()]]);942 expect(limitsEvm[3]).to.deep.eq([CollectionLimitField.TokenLimit.toString(), [true, limits.tokenLimit.toString()]]);943 expect(limitsEvm[4]).to.deep.eq([CollectionLimitField.SponsorTransferTimeout.toString(), [true, limits.sponsorTransferTimeout.toString()]]);944 expect(limitsEvm[5]).to.deep.eq([CollectionLimitField.SponsorApproveTimeout.toString(), [true, limits.sponsorApproveTimeout.toString()]]);945 expect(limitsEvm[6]).to.deep.eq([CollectionLimitField.OwnerCanTransfer.toString(), [true, limits.ownerCanTransfer.toString()]]);946 expect(limitsEvm[7]).to.deep.eq([CollectionLimitField.OwnerCanDestroy.toString(), [true, limits.ownerCanDestroy.toString()]]);947 expect(limitsEvm[8]).to.deep.eq([CollectionLimitField.TransferEnabled.toString(), [true, limits.transfersEnabled.toString()]]);948 }));949 });950951 describe('(!negative test!) Cannot set invalid collection limits', () => {952 [953 {case: 'nft' as const},954 {case: 'rft' as const, requiredPallets: [Pallets.ReFungible]},955 {case: 'ft' as const},956 ].map(testCase =>957 itEth.ifWithPallets(`for ${testCase.case}`, testCase.requiredPallets || [], async ({helper}) => {958 const invalidLimits = {959 accountTokenOwnershipLimit: BigInt(Number.MAX_SAFE_INTEGER),960 transfersEnabled: 3,961 };962963 const createCollectionData = {964 ...CREATE_COLLECTION_DATA_DEFAULTS,965 name: 'Limits',966 description: 'absolutely anything',967 tokenPrefix: 'ISNI',968 collectionMode: testCase.case,969 };970971 const owner = await helper.eth.createAccountWithBalance(donor);972 await expect(helper.eth.createCollection(973 owner,974 {975 ...createCollectionData,976 limits: [{field: 9 as CollectionLimitField, value: 1n}],977 },978 ).call()).to.be.rejectedWith('value not convertible into enum "CollectionLimitField"');979980 await expect(helper.eth.createCollection(981 owner,982 {983 ...createCollectionData,984 limits: [{field: CollectionLimitField.AccountTokenOwnership, value: invalidLimits.accountTokenOwnershipLimit}],985 },986 ).call()).to.be.rejectedWith(`can't convert value to u32 "${invalidLimits.accountTokenOwnershipLimit}"`);987988 await expect(helper.eth.createCollection(989 owner,990 {991 ...createCollectionData,992 limits: [{field: CollectionLimitField.TransferEnabled, value: 3n}],993 },994 ).call()).to.be.rejectedWith(`can't convert value to boolean "${invalidLimits.transfersEnabled}"`);995996 await expect(helper.eth.createCollection(997 owner,998 {999 ...createCollectionData,1000 limits: [{field: CollectionLimitField.SponsoredDataSize, value: -1n}],1001 },1002 ).call()).to.be.rejectedWith('value out-of-bounds');1003 }));1004 });1005 });10061007 describe('Collection properties', () => {10081009 [1010 {mode: 'nft' as const, methodParams: [{key: 'testKey1', value: Buffer.from('testValue1')}, {key: 'testKey2', value: Buffer.from('testValue2')}], expectedProps: [{key: 'testKey1', value: 'testValue1'}, {key: 'testKey2', value: 'testValue2'}]},1011 {mode: 'rft' as const, methodParams: [{key: 'testKey1', value: Buffer.from('testValue1')}, {key: 'testKey2', value: Buffer.from('testValue2')}], expectedProps: [{key: 'testKey1', value: 'testValue1'}, {key: 'testKey2', value: 'testValue2'}]},1012 {mode: 'ft' as const, methodParams: [{key: 'testKey1', value: Buffer.from('testValue1')}, {key: 'testKey2', value: Buffer.from('testValue2')}], expectedProps: [{key: 'testKey1', value: 'testValue1'}, {key: 'testKey2', value: 'testValue2'}]},1013 ].map(testCase =>1014 itEth.ifWithPallets(`Collection properties can be set for ${testCase.mode}`, testCase.mode === 'rft' ? [Pallets.ReFungible] : [], async({helper}) => {1015 const caller = await helper.eth.createAccountWithBalance(donor);1016 const callerCross = helper.ethCrossAccount.fromAddress(caller);1017 const owner = await helper.eth.createAccountWithBalance(donor);1018 const {collectionId, collectionAddress} = await helper.eth.createCollection(1019 owner,1020 {1021 ...CREATE_COLLECTION_DATA_DEFAULTS,1022 name: 'name',1023 description: 'test',1024 tokenPrefix: 'test',1025 collectionMode: testCase.mode,1026 adminList: [callerCross],1027 properties: testCase.methodParams,1028 },1029 ).send();10301031 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, testCase.mode, caller);10321033 const raw = (await helper[testCase.mode].getData(collectionId))?.raw;1034 expect(raw.properties).to.deep.equal(testCase.expectedProps);10351036 // collectionProperties returns properties:1037 expect(await collectionEvm.methods.collectionProperties([]).call()).to.be.like(testCase.expectedProps.map(prop => helper.ethProperty.property(prop.key, prop.value)));1038 }));10391040 [1041 {mode: 'nft' as const},1042 {mode: 'rft' as const},1043 {mode: 'ft' as const},1044 ].map(testCase =>1045 itEth.ifWithPallets(`Collection properties can be deleted for ${testCase.mode}`, testCase.mode === 'rft' ? [Pallets.ReFungible] : [], async({helper}) => {1046 const caller = await helper.eth.createAccountWithBalance(donor);1047 const callerCross = helper.ethCrossAccount.fromAddress(caller);1048 const owner = await helper.eth.createAccountWithBalance(donor);1049 const {collectionId, collectionAddress} = await helper.eth.createCollection(1050 owner,1051 {1052 ...CREATE_COLLECTION_DATA_DEFAULTS,1053 name: 'name',1054 description: 'test',1055 tokenPrefix: 'test',1056 collectionMode: testCase.mode,1057 adminList: [callerCross],1058 properties:[1059 {key: 'testKey1', value: Buffer.from('testValue1')},1060 {key: 'testKey2', value: Buffer.from('testValue2')},1061 {key: 'testKey3', value: Buffer.from('testValue3')}],1062 },1063 ).send();10641065 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, testCase.mode, caller);10661067 await collectionEvm.methods.deleteCollectionProperties(['testKey1', 'testKey2']).send({from: caller});10681069 const raw = (await helper[testCase.mode].getData(collectionId))?.raw;10701071 expect(raw.properties.length).to.equal(1);1072 expect(raw.properties).to.deep.equal([{key: 'testKey3', value: 'testValue3'}]);1073 }));10741075 itEth('(!negative test!) Cannot set invalid properties', async({helper}) => {1076 const caller = await helper.eth.createAccountWithBalance(donor);1077 const callerCross = helper.ethCrossAccount.fromAddress(caller);1078 const owner = await helper.eth.createAccountWithBalance(donor);1079 const createCollectionData = {1080 ...CREATE_COLLECTION_DATA_DEFAULTS,1081 name: 'name',1082 description: 'test',1083 tokenPrefix: 'test',1084 collectionMode: 'nft' as TCollectionMode,1085 adminList: [callerCross],1086 };1087 await expect(helper.eth.createCollection(1088 owner,1089 {1090 ...createCollectionData,1091 properties: [{key: '', value: Buffer.from('val1')}],1092 },1093 ).call()).to.be.rejected;10941095 await expect(helper.eth.createCollection(1096 owner,1097 {1098 ...createCollectionData,1099 properties: [{key: 'déjà vu', value: Buffer.from('hmm...')}],1100 },1101 ).call()).to.be.rejected;11021103 await expect(helper.eth.createCollection(1104 owner,1105 {1106 ...createCollectionData,1107 properties: [{key: 'a'.repeat(257), value: Buffer.from('val3')}],1108 },1109 ).call()).to.be.rejected;1110 });11111112 itEth('(!negative test!) cannot delete properties of non-owned collections', async ({helper}) => {1113 const caller = await helper.eth.createAccountWithBalance(donor);1114 const owner = await helper.eth.createAccountWithBalance(donor);1115 const {collectionAddress} = await helper.eth.createCollection(1116 owner,1117 {1118 ...CREATE_COLLECTION_DATA_DEFAULTS,1119 name: 'name',1120 description: 'test',1121 tokenPrefix: 'test',1122 collectionMode: 'nft',1123 properties:[1124 {key: 'testKey1', value: Buffer.from('testValue1')},1125 {key: 'testKey2', value: Buffer.from('testValue2')}],1126 },1127 ).send();11281129 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', caller);11301131 await expect(collectionEvm.methods.deleteCollectionProperties(['testKey2']).send({from: caller})).to.be.rejected;1132 });1133 });11341135 describe('Token property permissions', () => {1136 [1137 {mode: 'nft' as const, requiredPallets: []},1138 {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},1139 ].map(testCase =>1140 itEth.ifWithPallets(`[${testCase.mode}] Can set all possible token property permissions`, testCase.requiredPallets, async({helper}) => {1141 const owner = await helper.eth.createAccountWithBalance(donor);1142 const caller = await helper.ethCrossAccount.createAccountWithBalance(donor);1143 for(const [mutable,collectionAdmin, tokenOwner] of cartesian([], [false, true], [false, true], [false, true])) {1144 const {collectionId, collectionAddress} = await helper.eth.createCollection(1145 owner,1146 {1147 ...CREATE_COLLECTION_DATA_DEFAULTS,1148 name: 'A',1149 description: 'B',1150 tokenPrefix: 'C',1151 collectionMode: testCase.mode,1152 adminList: [caller],1153 tokenPropertyPermissions: [1154 {1155 key: 'testKey',1156 permissions: [1157 {code: TokenPermissionField.Mutable, value: mutable},1158 {code: TokenPermissionField.TokenOwner, value: tokenOwner},1159 {code: TokenPermissionField.CollectionAdmin, value: collectionAdmin},1160 ],1161 },1162 ],1163 },1164 ).send();1165 const collection = await helper.ethNativeContract.collection(collectionAddress, testCase.mode, owner);11661167 expect(await helper[testCase.mode].getPropertyPermissions(collectionId)).to.be.deep.equal([{1168 key: 'testKey',1169 permission: {mutable, collectionAdmin, tokenOwner},1170 }]);11711172 expect(await collection.methods.tokenPropertyPermissions().call({from: caller.eth})).to.be.like([1173 ['testKey', [1174 [TokenPermissionField.Mutable.toString(), mutable],1175 [TokenPermissionField.TokenOwner.toString(), tokenOwner],1176 [TokenPermissionField.CollectionAdmin.toString(), collectionAdmin]],1177 ],1178 ]);1179 }1180 }));11811182 [1183 {mode: 'nft' as const, requiredPallets: []},1184 {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},1185 ].map(testCase =>1186 itEth.ifWithPallets(`[${testCase.mode}] Can set multiple token property permissions`, testCase.requiredPallets, async({helper}) => {1187 const owner = await helper.eth.createAccountWithBalance(donor);1188 const {collectionId, collectionAddress} = await helper.eth.createCollection(1189 owner,1190 {1191 ...CREATE_COLLECTION_DATA_DEFAULTS,1192 name: 'A',1193 description: 'B',1194 tokenPrefix: 'C',1195 collectionMode: testCase.mode,1196 tokenPropertyPermissions: [1197 {1198 key: 'testKey_0',1199 permissions: [1200 {code: TokenPermissionField.Mutable, value: true},1201 {code: TokenPermissionField.TokenOwner, value: true},1202 {code: TokenPermissionField.CollectionAdmin, value: true}],1203 },1204 {1205 key: 'testKey_1',1206 permissions: [1207 {code: TokenPermissionField.Mutable, value: true},1208 {code: TokenPermissionField.TokenOwner, value: false},1209 {code: TokenPermissionField.CollectionAdmin, value: true}],1210 },1211 {1212 key: 'testKey_2',1213 permissions: [1214 {code: TokenPermissionField.Mutable, value: false},1215 {code: TokenPermissionField.TokenOwner, value: true},1216 {code: TokenPermissionField.CollectionAdmin, value: false}],1217 },1218 ],1219 },1220 ).send();1221 const collection = await helper.ethNativeContract.collection(collectionAddress, testCase.mode, owner);12221223 expect(await helper[testCase.mode].getPropertyPermissions(collectionId)).to.be.deep.equal([1224 {1225 key: 'testKey_0',1226 permission: {mutable: true, tokenOwner: true, collectionAdmin: true},1227 },1228 {1229 key: 'testKey_1',1230 permission: {mutable: true, tokenOwner: false, collectionAdmin: true},1231 },1232 {1233 key: 'testKey_2',1234 permission: {mutable: false, tokenOwner: true, collectionAdmin: false},1235 },1236 ]);12371238 expect(await collection.methods.tokenPropertyPermissions().call({from: owner})).to.be.like([1239 ['testKey_0', [1240 [TokenPermissionField.Mutable.toString(), true],1241 [TokenPermissionField.TokenOwner.toString(), true],1242 [TokenPermissionField.CollectionAdmin.toString(), true]],1243 ],1244 ['testKey_1', [1245 [TokenPermissionField.Mutable.toString(), true],1246 [TokenPermissionField.TokenOwner.toString(), false],1247 [TokenPermissionField.CollectionAdmin.toString(), true]],1248 ],1249 ['testKey_2', [1250 [TokenPermissionField.Mutable.toString(), false],1251 [TokenPermissionField.TokenOwner.toString(), true],1252 [TokenPermissionField.CollectionAdmin.toString(), false]],1253 ],1254 ]);1255 }));12561257 [1258 {mode: 'nft' as const, requiredPallets: []},1259 {mode: 'rft' as const, requiredPallets: [Pallets.ReFungible]},1260 ].map(testCase =>1261 itEth.ifWithPallets(`Can be deleted for ${testCase.mode}`, testCase.requiredPallets, async({helper}) => {1262 const caller = await helper.eth.createAccountWithBalance(donor);1263 const receiver = await helper.ethCrossAccount.createAccountWithBalance(donor);1264 const {collectionAddress} = await helper.eth.createCollection(1265 caller,1266 {1267 ...CREATE_COLLECTION_DATA_DEFAULTS,1268 name: 'A',1269 description: 'B',1270 tokenPrefix: 'C',1271 collectionMode: testCase.mode,1272 adminList: [receiver],1273 tokenPropertyPermissions: [1274 {1275 key: 'testKey',1276 permissions: [1277 {code: TokenPermissionField.Mutable, value: true},1278 {code: TokenPermissionField.CollectionAdmin, value: true}],1279 },1280 {1281 key: 'testKey_1',1282 permissions: [1283 {code: TokenPermissionField.Mutable, value: true},1284 {code: TokenPermissionField.CollectionAdmin, value: true}],1285 },1286 ],1287 },1288 ).send();12891290 const collection = await helper.ethNativeContract.collection(collectionAddress, testCase.mode, caller);1291 const tokenId = (await collection.methods.mintCross(receiver, [{key: 'testKey', value: Buffer.from('testValue')}, {key: 'testKey_1', value: Buffer.from('testValue_1')}]).send()).events.Transfer.returnValues.tokenId;1292 expect(await collection.methods.properties(tokenId, ['testKey', 'testKey_1']).call()).to.has.length(2);12931294 await collection.methods.deleteProperties(tokenId, ['testKey', 'testKey_1']).send({from: caller});1295 expect(await collection.methods.properties(tokenId, ['testKey', 'testKey_1']).call()).to.has.length(0);1296 }));1297 });12981299 describe('Nesting', () => {1300 itEth('NFT: allows an Owner to nest/unnest their token', async ({helper}) => {1301 const owner = await helper.eth.createAccountWithBalance(donor);1302 const {collectionAddress, collectionId} = await helper.eth.createCollection(1303 owner,1304 {1305 ...CREATE_COLLECTION_DATA_DEFAULTS,1306 name: 'A',1307 description: 'B',1308 tokenPrefix: 'C',1309 collectionMode: 'nft',1310 nestingSettings: {token_owner: true, collection_admin: false, restricted: []},1311 },1312 ).send();13131314 const contract = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner);13151316 // Create a token to be nested to1317 const mintingTargetNFTTokenIdResult = await contract.methods.mint(owner).send({from: owner});1318 const targetNFTTokenId = mintingTargetNFTTokenIdResult.events.Transfer.returnValues.tokenId;1319 const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetNFTTokenId);13201321 // Create a nested token1322 const mintingFirstTokenIdResult = await contract.methods.mint(targetNftTokenAddress).send({from: owner});1323 const firstTokenId = mintingFirstTokenIdResult.events.Transfer.returnValues.tokenId;1324 expect(await contract.methods.ownerOf(firstTokenId).call()).to.be.equal(targetNftTokenAddress);13251326 // Create a token to be nested and nest1327 const mintingSecondTokenIdResult = await contract.methods.mint(owner).send({from: owner});1328 const secondTokenId = mintingSecondTokenIdResult.events.Transfer.returnValues.tokenId;13291330 await contract.methods.transfer(targetNftTokenAddress, secondTokenId).send({from: owner});1331 expect(await contract.methods.ownerOf(secondTokenId).call()).to.be.equal(targetNftTokenAddress);13321333 // Unnest token back1334 await contract.methods.transferFrom(targetNftTokenAddress, owner, secondTokenId).send({from: owner});1335 expect(await contract.methods.ownerOf(secondTokenId).call()).to.be.equal(owner);1336 });13371338 itEth('NFT: collectionNesting()', async ({helper}) => {1339 const owner = await helper.eth.createAccountWithBalance(donor);1340 const {collectionAddress: unnestedCollectionAddress} = await helper.eth.createCollection(1341 owner,1342 new CreateCollectionData('A', 'B', 'C', 'nft'),1343 ).send();13441345 const unnestedContract = await helper.ethNativeContract.collection(unnestedCollectionAddress, 'nft', owner);1346 expect(await unnestedContract.methods.collectionNesting().call({from: owner})).to.be.like([false, false, []]);13471348 const {collectionAddress} = await helper.eth.createCollection(1349 owner,1350 {1351 ...CREATE_COLLECTION_DATA_DEFAULTS,1352 name: 'A',1353 description: 'B',1354 tokenPrefix: 'C',1355 collectionMode: 'nft',1356 nestingSettings: {token_owner: true, collection_admin: false, restricted: [unnestedCollectionAddress.toString()]},1357 },1358 ).send();13591360 const contract = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner);1361 expect(await contract.methods.collectionNesting().call({from: owner})).to.be.like([true, false, [unnestedCollectionAddress.toString()]]);1362 await contract.methods.setCollectionNesting([false, false, []]).send({from: owner});1363 expect(await contract.methods.collectionNesting().call({from: owner})).to.be.like([false, false, []]);1364 });13651366 itEth('NFT: disallows to nest token if nesting is disabled', async ({helper}) => {1367 const owner = await helper.eth.createAccountWithBalance(donor);13681369 const {collectionId, collectionAddress} = await helper.eth.createCollection(1370 owner,1371 {1372 ...CREATE_COLLECTION_DATA_DEFAULTS,1373 name: 'A',1374 description: 'B',1375 tokenPrefix: 'C',1376 collectionMode: 'nft',1377 nestingSettings: {token_owner: false, collection_admin: false, restricted: []},1378 },1379 ).send();13801381 const contract = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner);13821383 // Create a token to nest into1384 const mintingTargetTokenIdResult = await contract.methods.mint(owner).send({from: owner});1385 const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;1386 const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetTokenId);13871388 // Create a token to nest1389 const mintingNftTokenIdResult = await contract.methods.mint(owner).send({from: owner});1390 const nftTokenId = mintingNftTokenIdResult.events.Transfer.returnValues.tokenId;13911392 // Try to nest1393 await expect(contract.methods1394 .transfer(targetNftTokenAddress, nftTokenId)1395 .call({from: owner})).to.be.rejectedWith('UserIsNotAllowedToNest');1396 });1397 });13981399 describe('Flags', () => {1400 const createCollectionData = {1401 ...CREATE_COLLECTION_DATA_DEFAULTS,1402 name: 'A',1403 description: 'B',1404 tokenPrefix: 'C',1405 collectionMode: 'nft' as TCollectionMode,1406 };14071408 itEth('NFT: use numbers for flags', async ({helper}) => {1409 const owner = await helper.eth.createAccountWithBalance(donor);14101411 {1412 const {collectionId} = await helper.eth.createCollection(owner, {...createCollectionData, flags: 0}).send();1413 expect((await helper.nft.getData(collectionId))?.raw.flags).to.be.deep.equal({foreign: false, erc721metadata: false});1414 }14151416 {1417 const {collectionId} = await helper.eth.createCollection(owner, {...createCollectionData, flags: 64}).send();1418 expect((await helper.nft.getData(collectionId))?.raw.flags).to.be.deep.equal({foreign: false, erc721metadata: true});1419 }1420 });14211422 itEth('NFT: foreign flag number is ignored', async ({helper}) => {1423 const owner = await helper.eth.createAccountWithBalance(donor);14241425 {1426 const {collectionId} = await helper.eth.createCollection(owner, {...createCollectionData, flags: 128}).send();1427 expect((await helper.nft.getData(collectionId))?.raw.flags).to.be.deep.equal({foreign: false, erc721metadata: false});1428 }14291430 {1431 const {collectionId} = await helper.eth.createCollection(owner, {...createCollectionData, flags: 192}).send();1432 expect((await helper.nft.getData(collectionId))?.raw.flags).to.be.deep.equal({foreign: false, erc721metadata: true});1433 }1434 });14351436 itEth('NFT: use enum for flags', async ({helper}) => {1437 const owner = await helper.eth.createAccountWithBalance(donor);14381439 {1440 const {collectionId} = await helper.eth.createCollection(owner, {...createCollectionData, flags: [CollectionFlag.Erc721metadata]}).send();1441 expect((await helper.nft.getData(collectionId))?.raw.flags).to.be.deep.equal({foreign: false, erc721metadata: true});1442 }1443 });14441445 itEth('NFT: foreign flag enum is ignored', async ({helper}) => {1446 const owner = await helper.eth.createAccountWithBalance(donor);14471448 {1449 const {collectionId} = await helper.eth.createCollection(owner, {...createCollectionData, flags: [CollectionFlag.Foreign]}).send();1450 expect((await helper.nft.getData(collectionId))?.raw.flags).to.be.deep.equal({foreign: false, erc721metadata: false});1451 }14521453 {1454 const {collectionId} = await helper.eth.createCollection(owner, {...createCollectionData, flags: [CollectionFlag.Erc721metadata | CollectionFlag.Foreign]}).send();1455 expect((await helper.nft.getData(collectionId))?.raw.flags).to.be.deep.equal({foreign: false, erc721metadata: true});1456 }1457 });1458 });1459});tests/src/eth/createFTCollection.seqtest.tsdiffbeforeafterboth--- a/tests/src/eth/createFTCollection.seqtest.ts
+++ b/tests/src/eth/createFTCollection.seqtest.ts
@@ -59,7 +59,7 @@
const expectedCollectionId = +(await helper.callRpc('api.rpc.unique.collectionStats')).created + 1;
const expectedCollectionAddress = helper.ethAddress.fromCollectionId(expectedCollectionId);
- const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);
+ const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);
expect(await collectionHelpers.methods
.isCollectionExist(expectedCollectionAddress)
tests/src/eth/createFTCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/createFTCollection.test.ts
+++ b/tests/src/eth/createFTCollection.test.ts
@@ -50,7 +50,7 @@
await expect(collection.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');
- const sponsorCollection = await helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor, true);
+ const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor, true);
await sponsorCollection.methods.confirmCollectionSponsorship().send();
data = (await helper.rft.getData(collectionId))!;
@@ -64,7 +64,7 @@
const description = 'absolutely anything';
const {collectionId, collectionAddress} = await helper.eth.createFungibleCollection(owner, 'Sponsor', DECIMALS, description, 'ENVY');
- const collection = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
+ const collection = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
await collection.methods.setCollectionSponsorCross(sponsorCross).send();
@@ -73,7 +73,7 @@
await expect(collection.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');
- const sponsorCollection = await helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor);
+ const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor);
await sponsorCollection.methods.confirmCollectionSponsorship().send();
data = (await helper.rft.getData(collectionId))!;
@@ -84,7 +84,7 @@
itEth('Collection address exist', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const collectionAddressForNonexistentCollection = '0x17C4E6453CC49AAAAEACA894E6D9683E00112233';
- const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);
+ const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);
expect(await collectionHelpers
.methods.isCollectionExist(collectionAddressForNonexistentCollection).call())
@@ -96,7 +96,7 @@
.to.be.true;
// check collectionOwner:
- const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);
const collectionOwner = await collectionEvm.methods.collectionOwner().call();
expect(helper.address.restoreCrossAccountFromBigInt(BigInt(collectionOwner.sub))).to.eq(helper.address.ethToSubstrate(owner, true));
});
@@ -104,7 +104,7 @@
itEth('destroyCollection', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress, collectionId} = await helper.eth.createFungibleCollection(owner, 'Exister', DECIMALS, 'absolutely anything', 'WIWT');
- const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);
+ const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
const result = await collectionHelper.methods
.destroyCollection(collectionAddress)
@@ -143,7 +143,7 @@
itEth('(!negative test!) Create collection (bad lengths)', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
- const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);
+ const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
{
const MAX_NAME_LENGTH = 64;
const collectionName = 'A'.repeat(MAX_NAME_LENGTH + 1);
@@ -176,7 +176,7 @@
itEth('(!negative test!) cannot create collection if value !== 2', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
- const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);
+ const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
const expects = [0n, 1n, 30n].map(async value => {
await expect(collectionHelper.methods
.createFTCollection('Peasantry', DECIMALS, 'absolutely anything', 'TWIW')
@@ -190,7 +190,7 @@
const owner = await helper.eth.createAccountWithBalance(donor);
const peasant = helper.eth.createAccount();
const {collectionAddress} = await helper.eth.createFungibleCollection(owner, 'Transgressed', DECIMALS, 'absolutely anything', 'YVNE');
- const peasantCollection = await helper.ethNativeContract.collection(collectionAddress, 'ft', peasant, true);
+ const peasantCollection = helper.ethNativeContract.collection(collectionAddress, 'ft', peasant, true);
const EXPECTED_ERROR = 'NoPermission';
{
const sponsor = await helper.eth.createAccountWithBalance(donor);
@@ -198,7 +198,7 @@
.setCollectionSponsor(sponsor)
.call()).to.be.rejectedWith(EXPECTED_ERROR);
- const sponsorCollection = await helper.ethNativeContract.collection(collectionAddress, 'ft', sponsor, true);
+ const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'ft', sponsor, true);
await expect(sponsorCollection.methods
.confirmCollectionSponsorship()
.call()).to.be.rejectedWith('ConfirmSponsorshipFail');
@@ -214,7 +214,7 @@
const owner = await helper.eth.createAccountWithBalance(donor);
const peasant = helper.eth.createAccount();
const {collectionAddress} = await helper.eth.createFungibleCollection(owner, 'Transgressed', DECIMALS, 'absolutely anything', 'YVNE');
- const peasantCollection = await helper.ethNativeContract.collection(collectionAddress, 'ft', peasant);
+ const peasantCollection = helper.ethNativeContract.collection(collectionAddress, 'ft', peasant);
const EXPECTED_ERROR = 'NoPermission';
{
const sponsor = await helper.eth.createAccountWithBalance(donor);
@@ -223,7 +223,7 @@
.setCollectionSponsorCross(sponsorCross)
.call()).to.be.rejectedWith(EXPECTED_ERROR);
- const sponsorCollection = await helper.ethNativeContract.collection(collectionAddress, 'ft', sponsor);
+ const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'ft', sponsor);
await expect(sponsorCollection.methods
.confirmCollectionSponsorship()
.call()).to.be.rejectedWith('ConfirmSponsorshipFail');
tests/src/eth/createNFTCollection.seqtest.tsdiffbeforeafterboth--- a/tests/src/eth/createNFTCollection.seqtest.ts
+++ b/tests/src/eth/createNFTCollection.seqtest.ts
@@ -72,7 +72,7 @@
const expectedCollectionId = +(await helper.callRpc('api.rpc.unique.collectionStats')).created + 1;
const expectedCollectionAddress = helper.ethAddress.fromCollectionId(expectedCollectionId);
- const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);
+ const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);
expect(await collectionHelpers.methods
.isCollectionExist(expectedCollectionAddress)
tests/src/eth/createNFTCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/createNFTCollection.test.ts
+++ b/tests/src/eth/createNFTCollection.test.ts
@@ -39,7 +39,7 @@
const baseUri = 'BaseURI';
const {collectionId, collectionAddress, events} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, name, description, prefix, baseUri);
- const contract = await helper.ethNativeContract.collection(collectionAddress, 'nft');
+ const contract = helper.ethNativeContract.collection(collectionAddress, 'nft');
expect(events).to.be.deep.equal([
{
@@ -82,7 +82,7 @@
const ss58Format = helper.chain.getChainProperties().ss58Format;
const {collectionId, collectionAddress} = await helper.eth.createNFTCollection(owner, 'Sponsor', 'absolutely anything', 'ROC');
- const collection = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner, true);
+ const collection = helper.ethNativeContract.collection(collectionAddress, 'nft', owner, true);
await collection.methods.setCollectionSponsor(sponsor).send();
let data = (await helper.nft.getData(collectionId))!;
@@ -90,7 +90,7 @@
await expect(collection.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');
- const sponsorCollection = await helper.ethNativeContract.collection(collectionAddress, 'nft', sponsor, true);
+ const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'nft', sponsor, true);
await sponsorCollection.methods.confirmCollectionSponsorship().send();
data = (await helper.nft.getData(collectionId))!;
@@ -104,7 +104,7 @@
const description = 'absolutely anything';
const {collectionId, collectionAddress} = await helper.eth.createNFTCollection(owner, 'Sponsor', description, 'ROC');
- const collection = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
+ const collection = helper.ethNativeContract.collection(collectionAddress, 'nft', owner);
const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
await collection.methods.setCollectionSponsorCross(sponsorCross).send();
@@ -125,7 +125,7 @@
itEth('Collection address exist', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const collectionAddressForNonexistentCollection = '0x17C4E6453CC49AAAAEACA894E6D9683E00112233';
- const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);
+ const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);
expect(await collectionHelpers
.methods.isCollectionExist(collectionAddressForNonexistentCollection).call())
@@ -137,7 +137,7 @@
.to.be.true;
// check collectionOwner:
- const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);
const collectionOwner = await collectionEvm.methods.collectionOwner().call();
expect(helper.address.restoreCrossAccountFromBigInt(BigInt(collectionOwner.sub))).to.eq(helper.address.ethToSubstrate(owner, true));
});
@@ -156,7 +156,7 @@
itEth('(!negative test!) Create collection (bad lengths)', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
- const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);
+ const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
{
const MAX_NAME_LENGTH = 64;
const collectionName = 'A'.repeat(MAX_NAME_LENGTH + 1);
@@ -190,7 +190,7 @@
itEth('(!negative test!) Create collection (no funds)', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
- const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);
+ const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
await expect(collectionHelper.methods
.createNFTCollection('Peasantry', 'absolutely anything', 'CVE')
.call({value: Number(1n * nominal)})).to.be.rejectedWith('Sent amount not equals to collection creation price (2000000000000000000)');
@@ -209,7 +209,7 @@
.setCollectionSponsor(sponsor)
.call()).to.be.rejectedWith(EXPECTED_ERROR);
- const sponsorCollection = await helper.ethNativeContract.collection(collectionAddress, 'nft', sponsor, true);
+ const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'nft', sponsor, true);
await expect(sponsorCollection.methods
.confirmCollectionSponsorship()
.call()).to.be.rejectedWith('ConfirmSponsorshipFail');
@@ -225,7 +225,7 @@
const owner = await helper.eth.createAccountWithBalance(donor);
const malfeasant = helper.eth.createAccount();
const {collectionAddress} = await helper.eth.createNFTCollection(owner, 'Transgressed', 'absolutely anything', 'COR');
- const malfeasantCollection = await helper.ethNativeContract.collection(collectionAddress, 'nft', malfeasant);
+ const malfeasantCollection = helper.ethNativeContract.collection(collectionAddress, 'nft', malfeasant);
const EXPECTED_ERROR = 'NoPermission';
{
const sponsor = await helper.eth.createAccountWithBalance(donor);
@@ -234,7 +234,7 @@
.setCollectionSponsorCross(sponsorCross)
.call()).to.be.rejectedWith(EXPECTED_ERROR);
- const sponsorCollection = await helper.ethNativeContract.collection(collectionAddress, 'nft', sponsor);
+ const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'nft', sponsor);
await expect(sponsorCollection.methods
.confirmCollectionSponsorship()
.call()).to.be.rejectedWith('ConfirmSponsorshipFail');
@@ -249,7 +249,7 @@
itEth('destroyCollection', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'Limits', 'absolutely anything', 'OLF');
- const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);
+ const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
const result = await collectionHelper.methods
tests/src/eth/createRFTCollection.test.tsdiffbeforeafterboth--- a/tests/src/eth/createRFTCollection.test.ts
+++ b/tests/src/eth/createRFTCollection.test.ts
@@ -95,7 +95,7 @@
const ss58Format = helper.chain.getChainProperties().ss58Format;
const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(owner, 'Sponsor', 'absolutely anything', 'ENVY');
- const collection = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner, true);
+ const collection = helper.ethNativeContract.collection(collectionAddress, 'rft', owner, true);
await collection.methods.setCollectionSponsor(sponsor).send();
let data = (await helper.rft.getData(collectionId))!;
@@ -103,7 +103,7 @@
await expect(collection.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');
- const sponsorCollection = await helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor, true);
+ const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor, true);
await sponsorCollection.methods.confirmCollectionSponsorship().send();
data = (await helper.rft.getData(collectionId))!;
@@ -116,7 +116,7 @@
const ss58Format = helper.chain.getChainProperties().ss58Format;
const {collectionId, collectionAddress} = await helper.eth.createRFTCollection(owner, 'Sponsor', 'absolutely anything', 'ENVY');
- const collection = await helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
+ const collection = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);
const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);
await collection.methods.setCollectionSponsorCross(sponsorCross).send();
@@ -125,7 +125,7 @@
await expect(collection.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');
- const sponsorCollection = await helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor);
+ const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor);
await sponsorCollection.methods.confirmCollectionSponsorship().send();
data = (await helper.rft.getData(collectionId))!;
@@ -135,7 +135,7 @@
itEth('Collection address exist', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const collectionAddressForNonexistentCollection = '0x17C4E6453CC49AAAAEACA894E6D9683E00112233';
- const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);
+ const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);
expect(await collectionHelpers
.methods.isCollectionExist(collectionAddressForNonexistentCollection).call())
@@ -147,7 +147,7 @@
.to.be.true;
// check collectionOwner:
- const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);
+ const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'ft', owner, true);
const collectionOwner = await collectionEvm.methods.collectionOwner().call();
expect(helper.address.restoreCrossAccountFromBigInt(BigInt(collectionOwner.sub))).to.eq(helper.address.ethToSubstrate(owner, true));
});
@@ -167,7 +167,7 @@
itEth('(!negative test!) Create collection (bad lengths)', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
- const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);
+ const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
{
const MAX_NAME_LENGTH = 64;
const collectionName = 'A'.repeat(MAX_NAME_LENGTH + 1);
@@ -200,7 +200,7 @@
itEth('(!negative test!) Create collection (no funds)', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
- const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);
+ const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
await expect(collectionHelper.methods
.createRFTCollection('Peasantry', 'absolutely anything', 'TWIW')
.call({value: Number(1n * nominal)})).to.be.rejectedWith('Sent amount not equals to collection creation price (2000000000000000000)');
@@ -211,7 +211,7 @@
const owner = await helper.eth.createAccountWithBalance(donor);
const peasant = helper.eth.createAccount();
const {collectionAddress} = await helper.eth.createRFTCollection(owner, 'Transgressed', 'absolutely anything', 'YVNE');
- const peasantCollection = await helper.ethNativeContract.collection(collectionAddress, 'rft', peasant, true);
+ const peasantCollection = helper.ethNativeContract.collection(collectionAddress, 'rft', peasant, true);
const EXPECTED_ERROR = 'NoPermission';
{
const sponsor = await helper.eth.createAccountWithBalance(donor);
@@ -219,7 +219,7 @@
.setCollectionSponsor(sponsor)
.call()).to.be.rejectedWith(EXPECTED_ERROR);
- const sponsorCollection = await helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor, true);
+ const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor, true);
await expect(sponsorCollection.methods
.confirmCollectionSponsorship()
.call()).to.be.rejectedWith('ConfirmSponsorshipFail');
@@ -235,7 +235,7 @@
const owner = await helper.eth.createAccountWithBalance(donor);
const peasant = helper.eth.createAccount();
const {collectionAddress} = await helper.eth.createRFTCollection(owner, 'Transgressed', 'absolutely anything', 'YVNE');
- const peasantCollection = await helper.ethNativeContract.collection(collectionAddress, 'rft', peasant);
+ const peasantCollection = helper.ethNativeContract.collection(collectionAddress, 'rft', peasant);
const EXPECTED_ERROR = 'NoPermission';
{
const sponsor = await helper.eth.createAccountWithBalance(donor);
@@ -244,7 +244,7 @@
.setCollectionSponsorCross(sponsorCross)
.call()).to.be.rejectedWith(EXPECTED_ERROR);
- const sponsorCollection = await helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor);
+ const sponsorCollection = helper.ethNativeContract.collection(collectionAddress, 'rft', sponsor);
await expect(sponsorCollection.methods
.confirmCollectionSponsorship()
.call()).to.be.rejectedWith('ConfirmSponsorshipFail');
@@ -259,7 +259,7 @@
itEth('destroyCollection', async ({helper}) => {
const owner = await helper.eth.createAccountWithBalance(donor);
const {collectionAddress, collectionId} = await helper.eth.createRFTCollection(owner, 'Limits', 'absolutely anything', 'OLF');
- const collectionHelper = await helper.ethNativeContract.collectionHelpers(owner);
+ const collectionHelper = helper.ethNativeContract.collectionHelpers(owner);
await expect(collectionHelper.methods
.destroyCollection(collectionAddress)
tests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth--- a/tests/src/eth/util/playgrounds/unique.dev.ts
+++ b/tests/src/eth/util/playgrounds/unique.dev.ts
@@ -207,7 +207,7 @@
}
private async createTransaction() {
- const collectionHelper = await this.helper.ethNativeContract.collectionHelpers(this.signer);
+ const collectionHelper = this.helper.ethNativeContract.collectionHelpers(this.signer);
let collectionMode;
switch (this.data.collectionMode) {
case 'nft': collectionMode = CollectionMode.Nonfungible; break;
tests/src/util/index.tsdiffbeforeafterboth--- a/tests/src/util/index.ts
+++ b/tests/src/util/index.ts
@@ -15,6 +15,7 @@
import {dirname} from 'path';
import {fileURLToPath} from 'url';
+chai.config.truncateThreshold = 0;
chai.use(chaiAsPromised);
chai.use(chaiSubset);
export const expect = chai.expect;
tests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth--- a/tests/src/util/playgrounds/unique.dev.ts
+++ b/tests/src/util/playgrounds/unique.dev.ts
@@ -41,7 +41,9 @@
for(const arg of args) {
if(typeof arg !== 'string')
continue;
- if(arg.includes('1000:: Normal connection closure') || arg.includes('Not decorating unknown runtime apis:') || arg.includes('RPC methods not decorated:') || arg === 'Normal connection closure')
+ const skippedWarnings = ['1000:: Normal connection closure', 'Not decorating unknown runtime apis:', 'RPC methods not decorated:', 'Not decorating runtime apis'];
+ const needToSkip = skippedWarnings.reduce((a, b) => a || arg.includes(b), false);
+ if(needToSkip || arg === 'Normal connection closure')
return;
}
printer(...args);