--- a/tests/src/eth/collectionSponsoring.test.ts +++ b/tests/src/eth/collectionSponsoring.test.ts @@ -1,7 +1,8 @@ -import {addToAllowListExpectSuccess, confirmSponsorshipExpectSuccess, createCollectionExpectSuccess, enablePublicMintingExpectSuccess, setCollectionSponsorExpectSuccess} from '../util/helpers'; -import {itWeb3, createEthAccount, collectionIdToAddress, GAS_ARGS, normalizeEvents} from './util/helpers'; +import {addToAllowListExpectSuccess, confirmSponsorshipExpectSuccess, createCollectionExpectSuccess, enablePublicMintingExpectSuccess, getDetailedCollectionInfo, setCollectionSponsorExpectSuccess} from '../util/helpers'; +import {itWeb3, createEthAccount, collectionIdToAddress, GAS_ARGS, normalizeEvents, createEthAccountWithBalance, evmCollectionHelpers, getCollectionAddressFromResult, evmCollection, ethBalanceViaSub} from './util/helpers'; import nonFungibleAbi from './nonFungibleAbi.json'; import {expect} from 'chai'; +import { evmToAddress } from '@polkadot/util-crypto'; describe('evm collection sponsoring', () => { itWeb3('sponsors mint transactions', async ({web3, privateKeyWrapper}) => { @@ -36,4 +37,130 @@ }, ]); }); + + itWeb3('Sponsoring collection from evm address via access list', async ({api, web3, privateKeyWrapper}) => { + const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const collectionHelpers = evmCollectionHelpers(web3, owner); + let result = await collectionHelpers.methods.createNonfungibleCollection('Sponsor collection', '1', '1').send(); + const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const collectionEvm = evmCollection(web3, owner, collectionIdAddress); + result = await collectionEvm.methods.setCollectionSponsor(sponsor).send({from: owner}); + let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!; + const ss58Format = (api.registry.getChainProperties())!.toJSON().ss58Format; + expect(collectionSub.sponsorship.isUnconfirmed).to.be.true; + expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format))); + await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor'); + + await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor}); + collectionSub = (await getDetailedCollectionInfo(api, collectionId))!; + expect(collectionSub.sponsorship.isConfirmed).to.be.true; + expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format))); + + const user = createEthAccount(web3); + const nextTokenId = await collectionEvm.methods.nextTokenId().call(); + expect(nextTokenId).to.be.equal('1'); + + const oldPermissions = (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman(); + expect(oldPermissions.mintMode).to.be.false; + expect(oldPermissions.access).to.be.equal('Normal'); + + await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner}); + await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner}); + await collectionEvm.methods.setCollectionMintMode(true).send({from: owner}); + + const newPermissions = (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman(); + expect(newPermissions.mintMode).to.be.true; + expect(newPermissions.access).to.be.equal('AllowList'); + + const ownerBalanceBefore = await ethBalanceViaSub(api, owner); + const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor); + + { + const nextTokenId = await collectionEvm.methods.nextTokenId().call(); + expect(nextTokenId).to.be.equal('1'); + const result = await collectionEvm.methods.mintWithTokenURI( + user, + nextTokenId, + 'Test URI', + ).send({from: user}); + const events = normalizeEvents(result.events); + + expect(events).to.be.deep.equal([ + { + address: collectionIdAddress, + event: 'Transfer', + args: { + from: '0x0000000000000000000000000000000000000000', + to: user, + tokenId: nextTokenId, + }, + }, + ]); + + const ownerBalanceAfter = await ethBalanceViaSub(api, owner); + const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor); + + expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI'); + expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter); + expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true; + } + }); + + itWeb3('Check that transaction via EVM spend money from sponsor address', async ({api, web3, privateKeyWrapper}) => { + const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const collectionHelpers = evmCollectionHelpers(web3, owner); + let result = await collectionHelpers.methods.createNonfungibleCollection('Sponsor collection', '1', '1').send(); + const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const collectionEvm = evmCollection(web3, owner, collectionIdAddress); + result = await collectionEvm.methods.setCollectionSponsor(sponsor).send(); + let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!; + const ss58Format = (api.registry.getChainProperties())!.toJSON().ss58Format; + expect(collectionSub.sponsorship.isUnconfirmed).to.be.true; + expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format))); + await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor'); + const sponsorCollection = evmCollection(web3, sponsor, collectionIdAddress); + await sponsorCollection.methods.confirmCollectionSponsorship().send(); + collectionSub = (await getDetailedCollectionInfo(api, collectionId))!; + expect(collectionSub.sponsorship.isConfirmed).to.be.true; + expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format))); + + const user = createEthAccount(web3); + await collectionEvm.methods.addCollectionAdmin(user).send(); + + const ownerBalanceBefore = await ethBalanceViaSub(api, owner); + const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor); + + + const userCollectionEvm = evmCollection(web3, user, collectionIdAddress); + const nextTokenId = await userCollectionEvm.methods.nextTokenId().call(); + expect(nextTokenId).to.be.equal('1'); + result = await userCollectionEvm.methods.mintWithTokenURI( + user, + nextTokenId, + 'Test URI', + ).send(); + + const events = normalizeEvents(result.events); + const address = collectionIdToAddress(collectionId); + + expect(events).to.be.deep.equal([ + { + address, + event: 'Transfer', + args: { + from: '0x0000000000000000000000000000000000000000', + to: user, + tokenId: nextTokenId, + }, + }, + ]); + expect(await userCollectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI'); + + const ownerBalanceAfter = await ethBalanceViaSub(api, owner); + expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore); + const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor); + expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true; + }); }); --- a/tests/src/eth/contractSponsoring.test.ts +++ b/tests/src/eth/contractSponsoring.test.ts @@ -23,24 +23,8 @@ itWeb3, SponsoringMode, createEthAccount, - collectionIdToAddress, - GAS_ARGS, - normalizeEvents, - subToEth, - executeEthTxOnSub, - evmCollectionHelpers, - getCollectionAddressFromResult, - evmCollection, ethBalanceViaSub, } from './util/helpers'; -import { - addCollectionAdminExpectSuccess, - createCollectionExpectSuccess, - getDetailedCollectionInfo, - transferBalanceTo, -} from '../util/helpers'; -import nonFungibleAbi from './nonFungibleAbi.json'; -import getBalance from '../substrate/get-balance'; import {evmToAddress} from '@polkadot/util-crypto'; describe('Sponsoring EVM contracts', () => { @@ -62,39 +46,99 @@ await expect(helpers.methods.setSponsoringMode(notOwner, SponsoringMode.Allowlisted).send({from: notOwner})).to.rejected; expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; }); + + itWeb3('Sponsor can be set by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => { + const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const flipper = await deployFlipper(web3, owner); + const helpers = contractHelpers(web3, owner); + expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false; + await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected; + expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.true; + }); + + itWeb3('Sponsor can not be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => { + const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const flipper = await deployFlipper(web3, owner); + const helpers = contractHelpers(web3, owner); + expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false; + await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).call({from: notOwner})).to.be.rejectedWith('NoPermission'); + expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false; + }); + + itWeb3('Sponsorship can be confirmed by the address that pending as sponsor', async ({api, web3, privateKeyWrapper}) => { + const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const flipper = await deployFlipper(web3, owner); + const helpers = contractHelpers(web3, owner); + expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false; + await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected; + await expect(helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor})).to.be.not.rejected; + expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true; + }); + + itWeb3('Sponsorship can not be confirmed by the address that not pending as sponsor', async ({api, web3, privateKeyWrapper}) => { + const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const notSponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const flipper = await deployFlipper(web3, owner); + const helpers = contractHelpers(web3, owner); + expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false; + await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected; + await expect(helpers.methods.confirmSponsorship(flipper.options.address).call({from: notSponsor})).to.be.rejectedWith('NoPermission'); + expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false; + }); + + itWeb3('Get confirmed sponsor', async ({api, web3, privateKeyWrapper}) => { + const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const flipper = await deployFlipper(web3, owner); + const helpers = contractHelpers(web3, owner); + await helpers.methods.setSponsor(flipper.options.address, sponsor).send(); + await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor}); + + const result = await helpers.methods.getSponsor(flipper.options.address).call(); + + expect(result[0]).to.be.eq(sponsor); + const sponsorSub = api.registry.createType('AccountId', '0x' + BigInt(result[1]).toString(16).padStart(64, '0')).toJSON(); + expect(sponsorSub).to.be.eq(evmToAddress(sponsor)); + }); itWeb3('In generous mode, non-allowlisted user transaction will be sponsored', async ({api, web3, privateKeyWrapper}) => { - const alice = privateKeyWrapper('//Alice'); - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); const flipper = await deployFlipper(web3, owner); const helpers = contractHelpers(web3, owner); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; + expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false; + await helpers.methods.setSponsor(flipper.options.address, sponsor).send(); + await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor}); + expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true; + await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner}); await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner}); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; - - await transferBalanceToEth(api, alice, flipper.options.address); - const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address); - expect(originalFlipperBalance).to.be.not.equal('0'); + const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor); + const callerBalanceBefore = await ethBalanceViaSub(api, caller); await flipper.methods.flip().send({from: caller}); expect(await flipper.methods.getValue().call()).to.be.true; - // Balance should be taken from flipper instead of caller - const balanceAfter = await web3.eth.getBalance(flipper.options.address); - expect(+balanceAfter).to.be.lessThan(+originalFlipperBalance); + // Balance should be taken from sponsor instead of caller + const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor); + const callerBalanceAfter = await ethBalanceViaSub(api, caller); + expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true; + expect(callerBalanceAfter).to.be.eq(callerBalanceBefore); }); itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should decrease (allowlisted)', async ({api, web3, privateKeyWrapper}) => { - const alice = privateKeyWrapper('//Alice'); - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); const caller = createEthAccount(web3); const flipper = await deployFlipper(web3, owner); @@ -103,22 +147,21 @@ await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner}); await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner}); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner}); await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner}); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; - await transferBalanceToEth(api, alice, flipper.options.address); + await helpers.methods.setSponsor(flipper.options.address, sponsor).send(); + await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor}); - const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address); - expect(originalFlipperBalance).to.be.not.equal('0'); + const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor); + expect(sponsorBalanceBefore).to.be.not.equal('0'); await flipper.methods.flip().send({from: caller}); expect(await flipper.methods.getValue().call()).to.be.true; // Balance should be taken from flipper instead of caller - const balanceAfter = await web3.eth.getBalance(flipper.options.address); - expect(+balanceAfter).to.be.lessThan(+originalFlipperBalance); + const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor); + expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true; }); itWeb3('Sponsoring is set, an address that has no UNQ can send a transaction and it works. Sponsor balance should not decrease (non-allowlisted)', async ({api, web3, privateKeyWrapper}) => { @@ -131,10 +174,8 @@ const helpers = contractHelpers(web3, owner); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner}); await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner}); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; await transferBalanceToEth(api, alice, flipper.options.address); @@ -150,11 +191,9 @@ }); itWeb3('Sponsoring is set, an address that has UNQ can send a transaction and it works. User balance should not change', async ({api, web3, privateKeyWrapper}) => { - const alice = privateKeyWrapper('//Alice'); - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const originalCallerBalance = await web3.eth.getBalance(caller); const flipper = await deployFlipper(web3, owner); @@ -162,26 +201,27 @@ await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner}); await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner}); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner}); await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner}); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; - await transferBalanceToEth(api, alice, flipper.options.address); + await helpers.methods.setSponsor(flipper.options.address, sponsor).send(); + await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor}); - const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address); - expect(originalFlipperBalance).to.be.not.equal('0'); + const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor); + const callerBalanceBefore = await ethBalanceViaSub(api, caller); await flipper.methods.flip().send({from: caller}); expect(await flipper.methods.getValue().call()).to.be.true; - expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance); + const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor); + const callerBalanceAfter = await ethBalanceViaSub(api, caller); + expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true; + expect(callerBalanceAfter).to.be.equals(callerBalanceBefore); }); itWeb3('Sponsoring is limited, with setContractRateLimit. The limitation is working if transactions are sent more often, the sender pays the commission.', async ({api, web3, privateKeyWrapper}) => { - const alice = privateKeyWrapper('//Alice'); - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); const originalCallerBalance = await web3.eth.getBalance(caller); @@ -191,25 +231,24 @@ await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner}); await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner}); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false; await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner}); await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner}); - expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true; - await transferBalanceToEth(api, alice, flipper.options.address); + await helpers.methods.setSponsor(flipper.options.address, sponsor).send(); + await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor}); - const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address); + const originalFlipperBalance = await web3.eth.getBalance(sponsor); expect(originalFlipperBalance).to.be.not.equal('0'); await flipper.methods.flip().send({from: caller}); expect(await flipper.methods.getValue().call()).to.be.true; expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance); - const newFlipperBalance = await web3.eth.getBalance(flipper.options.address); + const newFlipperBalance = await web3.eth.getBalance(sponsor); expect(newFlipperBalance).to.be.not.equals(originalFlipperBalance); await flipper.methods.flip().send({from: caller}); - expect(await web3.eth.getBalance(flipper.options.address)).to.be.equal(newFlipperBalance); + expect(await web3.eth.getBalance(sponsor)).to.be.equal(newFlipperBalance); expect(await web3.eth.getBalance(caller)).to.be.not.equals(originalCallerBalance); }); @@ -219,131 +258,5 @@ const flipper = await deployFlipper(web3, owner); const helpers = contractHelpers(web3, owner); expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200'); - }); - - itWeb3('Sponsoring collection from evm address via access list', async ({api, web3, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionHelpers = evmCollectionHelpers(web3, owner); - let result = await collectionHelpers.methods.createNonfungibleCollection('Sponsor collection', '1', '1').send(); - const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); - const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - result = await collectionEvm.methods.setCollectionSponsor(sponsor).send({from: owner}); - let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!; - const ss58Format = (api.registry.getChainProperties())!.toJSON().ss58Format; - expect(collectionSub.sponsorship.isUnconfirmed).to.be.true; - expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format))); - await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor'); - - await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor}); - collectionSub = (await getDetailedCollectionInfo(api, collectionId))!; - expect(collectionSub.sponsorship.isConfirmed).to.be.true; - expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format))); - - const user = createEthAccount(web3); - const nextTokenId = await collectionEvm.methods.nextTokenId().call(); - expect(nextTokenId).to.be.equal('1'); - - const oldPermissions = (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman(); - expect(oldPermissions.mintMode).to.be.false; - expect(oldPermissions.access).to.be.equal('Normal'); - - await collectionEvm.methods.setCollectionAccess(1 /*'AllowList'*/).send({from: owner}); - await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner}); - await collectionEvm.methods.setCollectionMintMode(true).send({from: owner}); - - const newPermissions = (await getDetailedCollectionInfo(api, collectionId))!.permissions.toHuman(); - expect(newPermissions.mintMode).to.be.true; - expect(newPermissions.access).to.be.equal('AllowList'); - - const ownerBalanceBefore = await ethBalanceViaSub(api, owner); - const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor); - - { - const nextTokenId = await collectionEvm.methods.nextTokenId().call(); - expect(nextTokenId).to.be.equal('1'); - const result = await collectionEvm.methods.mintWithTokenURI( - user, - nextTokenId, - 'Test URI', - ).send({from: user}); - const events = normalizeEvents(result.events); - - expect(events).to.be.deep.equal([ - { - address: collectionIdAddress, - event: 'Transfer', - args: { - from: '0x0000000000000000000000000000000000000000', - to: user, - tokenId: nextTokenId, - }, - }, - ]); - - const ownerBalanceAfter = await ethBalanceViaSub(api, owner); - const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor); - - expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI'); - expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter); - expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true; - } - }); - - itWeb3('Check that transaction via EVM spend money from sponsor address', async ({api, web3, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionHelpers = evmCollectionHelpers(web3, owner); - let result = await collectionHelpers.methods.createNonfungibleCollection('Sponsor collection', '1', '1').send(); - const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); - const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - result = await collectionEvm.methods.setCollectionSponsor(sponsor).send(); - let collectionSub = (await getDetailedCollectionInfo(api, collectionId))!; - const ss58Format = (api.registry.getChainProperties())!.toJSON().ss58Format; - expect(collectionSub.sponsorship.isUnconfirmed).to.be.true; - expect(collectionSub.sponsorship.asUnconfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format))); - await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor'); - const sponsorCollection = evmCollection(web3, sponsor, collectionIdAddress); - await sponsorCollection.methods.confirmCollectionSponsorship().send(); - collectionSub = (await getDetailedCollectionInfo(api, collectionId))!; - expect(collectionSub.sponsorship.isConfirmed).to.be.true; - expect(collectionSub.sponsorship.asConfirmed.toHuman()).to.be.eq(evmToAddress(sponsor, Number(ss58Format))); - - const user = createEthAccount(web3); - await collectionEvm.methods.addCollectionAdmin(user).send(); - - const ownerBalanceBefore = await ethBalanceViaSub(api, owner); - const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor); - - - const userCollectionEvm = evmCollection(web3, user, collectionIdAddress); - const nextTokenId = await userCollectionEvm.methods.nextTokenId().call(); - expect(nextTokenId).to.be.equal('1'); - result = await userCollectionEvm.methods.mintWithTokenURI( - user, - nextTokenId, - 'Test URI', - ).send(); - - const events = normalizeEvents(result.events); - const address = collectionIdToAddress(collectionId); - - expect(events).to.be.deep.equal([ - { - address, - event: 'Transfer', - args: { - from: '0x0000000000000000000000000000000000000000', - to: user, - tokenId: nextTokenId, - }, - }, - ]); - expect(await userCollectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI'); - - const ownerBalanceAfter = await ethBalanceViaSub(api, owner); - expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore); - const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor); - expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true; }); });