difftreelog
Merge branch 'feature/app-staking' of https://github.com/UniqueNetwork/unique-chain into feature/app-staking
in: master
2 files changed
tests/src/eth/contractSponsoring.test.tsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {expect} from 'chai';18import {19 contractHelpers,20 createEthAccountWithBalance,21 transferBalanceToEth,22 deployFlipper,23 itWeb3,24 SponsoringMode,25 createEthAccount,26 ethBalanceViaSub,27 normalizeEvents,28} from './util/helpers';2930describe('Sponsoring EVM contracts', () => {31 itWeb3('Self sponsored can be set by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {32 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);33 const flipper = await deployFlipper(web3, owner);34 const helpers = contractHelpers(web3, owner);35 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;36 await expect(helpers.methods.selfSponsoredEnable(flipper.options.address).send()).to.be.not.rejected;37 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;38 });3940 itWeb3('Set self sponsored events', async ({api, web3, privateKeyWrapper}) => {41 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);42 const flipper = await deployFlipper(web3, owner);43 const helpers = contractHelpers(web3, owner);44 45 const result = await helpers.methods.selfSponsoredEnable(flipper.options.address).send();46 const events = normalizeEvents(result.events);47 expect(events).to.be.deep.equal([48 {49 address: flipper.options.address,50 event: 'ContractSponsorSet',51 args: {52 contractAddress: flipper.options.address,53 sponsor: flipper.options.address,54 },55 },56 {57 address: flipper.options.address,58 event: 'ContractSponsorshipConfirmed',59 args: {60 contractAddress: flipper.options.address,61 sponsor: flipper.options.address,62 },63 },64 ]);65 });6667 itWeb3('Self sponsored can not be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {68 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);69 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);70 const flipper = await deployFlipper(web3, owner);71 const helpers = contractHelpers(web3, owner);72 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;73 await expect(helpers.methods.selfSponsoredEnable(flipper.options.address).call({from: notOwner})).to.be.rejectedWith('NoPermission');74 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;75 });7677 itWeb3('Sponsoring can be set by the address that has deployed the contract', async ({api, web3, privateKeyWrapper}) => {78 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);79 const flipper = await deployFlipper(web3, owner);80 const helpers = contractHelpers(web3, owner);81 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;82 await expect(helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner})).to.be.not.rejected;83 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;84 });8586 itWeb3('Sponsoring cannot be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {87 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);88 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);89 const flipper = await deployFlipper(web3, owner);90 const helpers = contractHelpers(web3, owner);91 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;92 await expect(helpers.methods.setSponsoringMode(notOwner, SponsoringMode.Allowlisted).call({from: notOwner})).to.be.rejectedWith('NoPermission');93 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;94 });95 96 itWeb3('Sponsor can be set by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {97 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);98 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);99 const flipper = await deployFlipper(web3, owner);100 const helpers = contractHelpers(web3, owner);101 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false;102 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected;103 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.true;104 });105 106 itWeb3('Set sponsor event', async ({api, web3, privateKeyWrapper}) => {107 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);108 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);109 const flipper = await deployFlipper(web3, owner);110 const helpers = contractHelpers(web3, owner);111 112 const result = await helpers.methods.setSponsor(flipper.options.address, sponsor).send();113 const events = normalizeEvents(result.events);114 expect(events).to.be.deep.equal([115 {116 address: flipper.options.address,117 event: 'ContractSponsorSet',118 args: {119 contractAddress: flipper.options.address,120 sponsor: sponsor,121 },122 },123 ]);124 });125 126 itWeb3('Sponsor can not be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {127 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);128 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);129 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);130 const flipper = await deployFlipper(web3, owner);131 const helpers = contractHelpers(web3, owner);132 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false;133 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).call({from: notOwner})).to.be.rejectedWith('NoPermission');134 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false;135 });136137 itWeb3('Sponsorship can be confirmed by the address that pending as sponsor', async ({api, web3, privateKeyWrapper}) => {138 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);139 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);140 const flipper = await deployFlipper(web3, owner);141 const helpers = contractHelpers(web3, owner);142 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;143 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected;144 await expect(helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor})).to.be.not.rejected;145 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;146 });147148 itWeb3('Confirm sponsorship event', async ({api, web3, privateKeyWrapper}) => {149 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);150 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);151 const flipper = await deployFlipper(web3, owner);152 const helpers = contractHelpers(web3, owner);153 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected;154 const result = await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});155 const events = normalizeEvents(result.events);156 expect(events).to.be.deep.equal([157 {158 address: flipper.options.address,159 event: 'ContractSponsorshipConfirmed',160 args: {161 contractAddress: flipper.options.address,162 sponsor: sponsor,163 },164 },165 ]);166 });167168 itWeb3('Sponsorship can not be confirmed by the address that not pending as sponsor', async ({api, web3, privateKeyWrapper}) => {169 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);170 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);171 const notSponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);172 const flipper = await deployFlipper(web3, owner);173 const helpers = contractHelpers(web3, owner);174 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;175 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected;176 await expect(helpers.methods.confirmSponsorship(flipper.options.address).call({from: notSponsor})).to.be.rejectedWith('NoPermission');177 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;178 });179180 itWeb3('Sponsorship can not be confirmed by the address that not set as sponsor', async ({api, web3, privateKeyWrapper}) => {181 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);182 const notSponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);183 const flipper = await deployFlipper(web3, owner);184 const helpers = contractHelpers(web3, owner);185 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;186 await expect(helpers.methods.confirmSponsorship(flipper.options.address).call({from: notSponsor})).to.be.rejectedWith('NoPendingSponsor');187 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;188 });189190 itWeb3('Get self sponsored sponsor', async ({api, web3, privateKeyWrapper}) => {191 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);192 const flipper = await deployFlipper(web3, owner);193 const helpers = contractHelpers(web3, owner);194 await helpers.methods.selfSponsoredEnable(flipper.options.address).send();195 196 const result = await helpers.methods.getSponsor(flipper.options.address).call();197198 expect(result[0]).to.be.eq(flipper.options.address);199 expect(result[1]).to.be.eq('0');200 });201202 itWeb3('Get confirmed sponsor', async ({api, web3, privateKeyWrapper}) => {203 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);204 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);205 const flipper = await deployFlipper(web3, owner);206 const helpers = contractHelpers(web3, owner);207 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();208 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});209 210 const result = await helpers.methods.getSponsor(flipper.options.address).call();211212 expect(result[0]).to.be.eq(sponsor);213 expect(result[1]).to.be.eq('0');214 });215216 itWeb3('Sponsor can be removed by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {217 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);218 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);219 const flipper = await deployFlipper(web3, owner);220 const helpers = contractHelpers(web3, owner);221222 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;223 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();224 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});225 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;226 227 await helpers.methods.removeSponsor(flipper.options.address).send();228 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;229 });230231 itWeb3('Remove sponsor event', async ({api, web3, privateKeyWrapper}) => {232 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);233 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);234 const flipper = await deployFlipper(web3, owner);235 const helpers = contractHelpers(web3, owner);236237 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();238 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});239 240 const result = await helpers.methods.removeSponsor(flipper.options.address).send();241 const events = normalizeEvents(result.events);242 expect(events).to.be.deep.equal([243 {244 address: flipper.options.address,245 event: 'ContractSponsorRemoved',246 args: {247 contractAddress: flipper.options.address,248 },249 },250 ]);251 });252253 itWeb3('Sponsor can not be removed by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {254 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);255 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);256 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);257 const flipper = await deployFlipper(web3, owner);258 const helpers = contractHelpers(web3, owner);259260 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;261 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();262 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});263 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;264 265 await expect(helpers.methods.removeSponsor(flipper.options.address).call({from: notOwner})).to.be.rejectedWith('NoPermission');266 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;267 });268269 itWeb3('In generous mode, non-allowlisted user transaction will be sponsored', async ({api, web3, privateKeyWrapper}) => {270 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);271 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);272 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);273274 const flipper = await deployFlipper(web3, owner);275276 const helpers = contractHelpers(web3, owner);277278 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();279 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});280281 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner});282 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});283284 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);285 const callerBalanceBefore = await ethBalanceViaSub(api, caller);286287 await flipper.methods.flip().send({from: caller});288 expect(await flipper.methods.getValue().call()).to.be.true;289290 // Balance should be taken from sponsor instead of caller291 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);292 const callerBalanceAfter = await ethBalanceViaSub(api, caller);293 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;294 expect(callerBalanceAfter).to.be.eq(callerBalanceBefore);295 });296297 itWeb3('In generous mode, non-allowlisted user transaction will be self sponsored', async ({api, web3, privateKeyWrapper}) => {298 const alice = privateKeyWrapper('//Alice');299300 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);301 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);302303 const flipper = await deployFlipper(web3, owner);304305 const helpers = contractHelpers(web3, owner);306307 await helpers.methods.selfSponsoredEnable(flipper.options.address).send();308309 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner});310 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});311312 await transferBalanceToEth(api, alice, flipper.options.address);313314 const contractBalanceBefore = await ethBalanceViaSub(api, flipper.options.address);315 const callerBalanceBefore = await ethBalanceViaSub(api, caller);316317 await flipper.methods.flip().send({from: caller});318 expect(await flipper.methods.getValue().call()).to.be.true;319320 // Balance should be taken from sponsor instead of caller321 const contractBalanceAfter = await ethBalanceViaSub(api, flipper.options.address);322 const callerBalanceAfter = await ethBalanceViaSub(api, caller);323 expect(contractBalanceAfter < contractBalanceBefore).to.be.true;324 expect(callerBalanceAfter).to.be.eq(callerBalanceBefore);325 });326327 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}) => {328 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);329 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);330 const caller = createEthAccount(web3);331332 const flipper = await deployFlipper(web3, owner);333334 const helpers = contractHelpers(web3, owner);335 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});336 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});337338 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});339 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});340341 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();342 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});343344 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);345 expect(sponsorBalanceBefore).to.be.not.equal('0');346347 await flipper.methods.flip().send({from: caller});348 expect(await flipper.methods.getValue().call()).to.be.true;349350 // Balance should be taken from flipper instead of caller351 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);352 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;353 });354355 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}) => {356 const alice = privateKeyWrapper('//Alice');357358 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);359 const caller = createEthAccount(web3);360361 const flipper = await deployFlipper(web3, owner);362363 const helpers = contractHelpers(web3, owner);364365 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});366 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});367368 await transferBalanceToEth(api, alice, flipper.options.address);369370 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);371 expect(originalFlipperBalance).to.be.not.equal('0');372373 await expect(flipper.methods.flip().send({from: caller})).to.be.rejectedWith(/InvalidTransaction::Payment/);374 expect(await flipper.methods.getValue().call()).to.be.false;375376 // Balance should be taken from flipper instead of caller377 const balanceAfter = await web3.eth.getBalance(flipper.options.address);378 expect(+balanceAfter).to.be.equals(+originalFlipperBalance);379 });380381 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}) => {382 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);383 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);384 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);385386 const flipper = await deployFlipper(web3, owner);387388 const helpers = contractHelpers(web3, owner);389 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});390 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});391392 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});393 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});394395 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();396 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});397398 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);399 const callerBalanceBefore = await ethBalanceViaSub(api, caller);400401 await flipper.methods.flip().send({from: caller});402 expect(await flipper.methods.getValue().call()).to.be.true;403404 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);405 const callerBalanceAfter = await ethBalanceViaSub(api, caller);406 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;407 expect(callerBalanceAfter).to.be.equals(callerBalanceBefore);408 });409410 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}) => {411 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);412 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);413 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);414 const originalCallerBalance = await web3.eth.getBalance(caller);415416 const flipper = await deployFlipper(web3, owner);417418 const helpers = contractHelpers(web3, owner);419 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});420 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});421422 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});423 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner});424425 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();426 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});427428 const originalFlipperBalance = await web3.eth.getBalance(sponsor);429 expect(originalFlipperBalance).to.be.not.equal('0');430431 await flipper.methods.flip().send({from: caller});432 expect(await flipper.methods.getValue().call()).to.be.true;433 expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);434435 const newFlipperBalance = await web3.eth.getBalance(sponsor);436 expect(newFlipperBalance).to.be.not.equals(originalFlipperBalance);437438 await flipper.methods.flip().send({from: caller});439 expect(await web3.eth.getBalance(sponsor)).to.be.equal(newFlipperBalance);440 expect(await web3.eth.getBalance(caller)).to.be.not.equals(originalCallerBalance);441 });442443 // TODO: Find a way to calculate default rate limit444 itWeb3('Default rate limit equals 7200', async ({api, web3, privateKeyWrapper}) => {445 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);446 const flipper = await deployFlipper(web3, owner);447 const helpers = contractHelpers(web3, owner);448 expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200');449 });450});1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617import {expect} from 'chai';18import { expectSubstrateEventsAtBlock } from '../util/helpers';19import {20 contractHelpers,21 createEthAccountWithBalance,22 transferBalanceToEth,23 deployFlipper,24 itWeb3,25 SponsoringMode,26 createEthAccount,27 ethBalanceViaSub,28 normalizeEvents,29} from './util/helpers';3031describe('Sponsoring EVM contracts', () => {32 itWeb3('Self sponsored can be set by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {33 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);34 const flipper = await deployFlipper(web3, owner);35 const helpers = contractHelpers(web3, owner);36 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;37 await expect(helpers.methods.selfSponsoredEnable(flipper.options.address).send()).to.be.not.rejected;38 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;39 });4041 itWeb3('Set self sponsored events', async ({api, web3, privateKeyWrapper}) => {42 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);43 const flipper = await deployFlipper(web3, owner);44 const helpers = contractHelpers(web3, owner);45 46 const result = await helpers.methods.selfSponsoredEnable(flipper.options.address).send();47 // console.log(result);48 const ethEvents = normalizeEvents(result.events);49 expect(ethEvents).to.be.deep.equal([50 {51 address: flipper.options.address,52 event: 'ContractSponsorSet',53 args: {54 contractAddress: flipper.options.address,55 sponsor: flipper.options.address,56 },57 },58 {59 address: flipper.options.address,60 event: 'ContractSponsorshipConfirmed',61 args: {62 contractAddress: flipper.options.address,63 sponsor: flipper.options.address,64 },65 },66 ]);6768 await expectSubstrateEventsAtBlock(69 api, 70 result.blockNumber,71 'evmContractHelpers',72 ['ContractSponsorSet','ContractSponsorshipConfirmed'],73 );74 });7576 itWeb3('Self sponsored can not be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {77 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);78 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);79 const flipper = await deployFlipper(web3, owner);80 const helpers = contractHelpers(web3, owner);81 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;82 await expect(helpers.methods.selfSponsoredEnable(flipper.options.address).call({from: notOwner})).to.be.rejectedWith('NoPermission');83 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;84 });8586 itWeb3('Sponsoring can be set by the address that has deployed the contract', async ({api, web3, privateKeyWrapper}) => {87 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);88 const flipper = await deployFlipper(web3, owner);89 const helpers = contractHelpers(web3, owner);90 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;91 await expect(helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner})).to.be.not.rejected;92 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.true;93 });9495 itWeb3('Sponsoring cannot be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {96 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);97 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);98 const flipper = await deployFlipper(web3, owner);99 const helpers = contractHelpers(web3, owner);100 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;101 await expect(helpers.methods.setSponsoringMode(notOwner, SponsoringMode.Allowlisted).call({from: notOwner})).to.be.rejectedWith('NoPermission');102 expect(await helpers.methods.sponsoringEnabled(flipper.options.address).call()).to.be.false;103 });104 105 itWeb3('Sponsor can be set by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {106 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);107 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);108 const flipper = await deployFlipper(web3, owner);109 const helpers = contractHelpers(web3, owner);110 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false;111 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected;112 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.true;113 });114 115 itWeb3('Set sponsor event', async ({api, web3, privateKeyWrapper}) => {116 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);117 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);118 const flipper = await deployFlipper(web3, owner);119 const helpers = contractHelpers(web3, owner);120 121 const result = await helpers.methods.setSponsor(flipper.options.address, sponsor).send();122 const events = normalizeEvents(result.events);123 expect(events).to.be.deep.equal([124 {125 address: flipper.options.address,126 event: 'ContractSponsorSet',127 args: {128 contractAddress: flipper.options.address,129 sponsor: sponsor,130 },131 },132 ]);133134 await expectSubstrateEventsAtBlock(135 api, 136 result.blockNumber,137 'evmContractHelpers',138 ['ContractSponsorSet'],139 );140 });141 142 itWeb3('Sponsor can not be set by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {143 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);144 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);145 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);146 const flipper = await deployFlipper(web3, owner);147 const helpers = contractHelpers(web3, owner);148 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false;149 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).call({from: notOwner})).to.be.rejectedWith('NoPermission');150 expect(await helpers.methods.hasPendingSponsor(flipper.options.address).call()).to.be.false;151 });152153 itWeb3('Sponsorship can be confirmed by the address that pending as sponsor', async ({api, web3, privateKeyWrapper}) => {154 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);155 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);156 const flipper = await deployFlipper(web3, owner);157 const helpers = contractHelpers(web3, owner);158 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;159 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected;160 await expect(helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor})).to.be.not.rejected;161 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;162 });163164 itWeb3('Confirm sponsorship event', async ({api, web3, privateKeyWrapper}) => {165 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);166 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);167 const flipper = await deployFlipper(web3, owner);168 const helpers = contractHelpers(web3, owner);169 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected;170 const result = await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});171 const events = normalizeEvents(result.events);172 expect(events).to.be.deep.equal([173 {174 address: flipper.options.address,175 event: 'ContractSponsorshipConfirmed',176 args: {177 contractAddress: flipper.options.address,178 sponsor: sponsor,179 },180 },181 ]);182183 await expectSubstrateEventsAtBlock(184 api, 185 result.blockNumber,186 'evmContractHelpers',187 ['ContractSponsorshipConfirmed'],188 );189 });190191 itWeb3('Sponsorship can not be confirmed by the address that not pending as sponsor', async ({api, web3, privateKeyWrapper}) => {192 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);193 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);194 const notSponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);195 const flipper = await deployFlipper(web3, owner);196 const helpers = contractHelpers(web3, owner);197 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;198 await expect(helpers.methods.setSponsor(flipper.options.address, sponsor).send()).to.be.not.rejected;199 await expect(helpers.methods.confirmSponsorship(flipper.options.address).call({from: notSponsor})).to.be.rejectedWith('NoPermission');200 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;201 });202203 itWeb3('Sponsorship can not be confirmed by the address that not set as sponsor', async ({api, web3, privateKeyWrapper}) => {204 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);205 const notSponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);206 const flipper = await deployFlipper(web3, owner);207 const helpers = contractHelpers(web3, owner);208 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;209 await expect(helpers.methods.confirmSponsorship(flipper.options.address).call({from: notSponsor})).to.be.rejectedWith('NoPendingSponsor');210 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;211 });212213 itWeb3('Get self sponsored sponsor', async ({api, web3, privateKeyWrapper}) => {214 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);215 const flipper = await deployFlipper(web3, owner);216 const helpers = contractHelpers(web3, owner);217 await helpers.methods.selfSponsoredEnable(flipper.options.address).send();218 219 const result = await helpers.methods.getSponsor(flipper.options.address).call();220221 expect(result[0]).to.be.eq(flipper.options.address);222 expect(result[1]).to.be.eq('0');223 });224225 itWeb3('Get confirmed sponsor', async ({api, web3, privateKeyWrapper}) => {226 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);227 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);228 const flipper = await deployFlipper(web3, owner);229 const helpers = contractHelpers(web3, owner);230 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();231 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});232 233 const result = await helpers.methods.getSponsor(flipper.options.address).call();234235 expect(result[0]).to.be.eq(sponsor);236 expect(result[1]).to.be.eq('0');237 });238239 itWeb3('Sponsor can be removed by the address that deployed the contract', async ({api, web3, privateKeyWrapper}) => {240 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);241 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);242 const flipper = await deployFlipper(web3, owner);243 const helpers = contractHelpers(web3, owner);244245 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;246 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();247 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});248 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;249 250 await helpers.methods.removeSponsor(flipper.options.address).send();251 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;252 });253254 itWeb3('Remove sponsor event', async ({api, web3, privateKeyWrapper}) => {255 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);256 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);257 const flipper = await deployFlipper(web3, owner);258 const helpers = contractHelpers(web3, owner);259260 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();261 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});262 263 const result = await helpers.methods.removeSponsor(flipper.options.address).send();264 const events = normalizeEvents(result.events);265 expect(events).to.be.deep.equal([266 {267 address: flipper.options.address,268 event: 'ContractSponsorRemoved',269 args: {270 contractAddress: flipper.options.address,271 },272 },273 ]);274275 await expectSubstrateEventsAtBlock(276 api, 277 result.blockNumber,278 'evmContractHelpers',279 ['ContractSponsorRemoved'],280 );281 });282283 itWeb3('Sponsor can not be removed by the address that did not deployed the contract', async ({api, web3, privateKeyWrapper}) => {284 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);285 const notOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);286 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);287 const flipper = await deployFlipper(web3, owner);288 const helpers = contractHelpers(web3, owner);289290 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.false;291 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();292 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});293 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;294 295 await expect(helpers.methods.removeSponsor(flipper.options.address).call({from: notOwner})).to.be.rejectedWith('NoPermission');296 expect(await helpers.methods.hasSponsor(flipper.options.address).call()).to.be.true;297 });298299 itWeb3('In generous mode, non-allowlisted user transaction will be sponsored', async ({api, web3, privateKeyWrapper}) => {300 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);301 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);302 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);303304 const flipper = await deployFlipper(web3, owner);305306 const helpers = contractHelpers(web3, owner);307308 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();309 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});310311 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner});312 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});313314 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);315 const callerBalanceBefore = await ethBalanceViaSub(api, caller);316317 await flipper.methods.flip().send({from: caller});318 expect(await flipper.methods.getValue().call()).to.be.true;319320 // Balance should be taken from sponsor instead of caller321 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);322 const callerBalanceAfter = await ethBalanceViaSub(api, caller);323 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;324 expect(callerBalanceAfter).to.be.eq(callerBalanceBefore);325 });326327 itWeb3('In generous mode, non-allowlisted user transaction will be self sponsored', async ({api, web3, privateKeyWrapper}) => {328 const alice = privateKeyWrapper('//Alice');329330 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);331 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);332333 const flipper = await deployFlipper(web3, owner);334335 const helpers = contractHelpers(web3, owner);336337 await helpers.methods.selfSponsoredEnable(flipper.options.address).send();338339 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Generous).send({from: owner});340 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});341342 await transferBalanceToEth(api, alice, flipper.options.address);343344 const contractBalanceBefore = await ethBalanceViaSub(api, flipper.options.address);345 const callerBalanceBefore = await ethBalanceViaSub(api, caller);346347 await flipper.methods.flip().send({from: caller});348 expect(await flipper.methods.getValue().call()).to.be.true;349350 // Balance should be taken from sponsor instead of caller351 const contractBalanceAfter = await ethBalanceViaSub(api, flipper.options.address);352 const callerBalanceAfter = await ethBalanceViaSub(api, caller);353 expect(contractBalanceAfter < contractBalanceBefore).to.be.true;354 expect(callerBalanceAfter).to.be.eq(callerBalanceBefore);355 });356357 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}) => {358 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);359 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);360 const caller = createEthAccount(web3);361362 const flipper = await deployFlipper(web3, owner);363364 const helpers = contractHelpers(web3, owner);365 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});366 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});367368 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});369 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});370371 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();372 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});373374 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);375 expect(sponsorBalanceBefore).to.be.not.equal('0');376377 await flipper.methods.flip().send({from: caller});378 expect(await flipper.methods.getValue().call()).to.be.true;379380 // Balance should be taken from flipper instead of caller381 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);382 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;383 });384385 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}) => {386 const alice = privateKeyWrapper('//Alice');387388 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);389 const caller = createEthAccount(web3);390391 const flipper = await deployFlipper(web3, owner);392393 const helpers = contractHelpers(web3, owner);394395 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});396 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});397398 await transferBalanceToEth(api, alice, flipper.options.address);399400 const originalFlipperBalance = await web3.eth.getBalance(flipper.options.address);401 expect(originalFlipperBalance).to.be.not.equal('0');402403 await expect(flipper.methods.flip().send({from: caller})).to.be.rejectedWith(/InvalidTransaction::Payment/);404 expect(await flipper.methods.getValue().call()).to.be.false;405406 // Balance should be taken from flipper instead of caller407 const balanceAfter = await web3.eth.getBalance(flipper.options.address);408 expect(+balanceAfter).to.be.equals(+originalFlipperBalance);409 });410411 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}) => {412 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);413 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);414 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);415416 const flipper = await deployFlipper(web3, owner);417418 const helpers = contractHelpers(web3, owner);419 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});420 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});421422 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});423 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 0).send({from: owner});424425 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();426 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});427428 const sponsorBalanceBefore = await ethBalanceViaSub(api, sponsor);429 const callerBalanceBefore = await ethBalanceViaSub(api, caller);430431 await flipper.methods.flip().send({from: caller});432 expect(await flipper.methods.getValue().call()).to.be.true;433434 const sponsorBalanceAfter = await ethBalanceViaSub(api, sponsor);435 const callerBalanceAfter = await ethBalanceViaSub(api, caller);436 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;437 expect(callerBalanceAfter).to.be.equals(callerBalanceBefore);438 });439440 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}) => {441 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);442 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);443 const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper);444 const originalCallerBalance = await web3.eth.getBalance(caller);445446 const flipper = await deployFlipper(web3, owner);447448 const helpers = contractHelpers(web3, owner);449 await helpers.methods.toggleAllowlist(flipper.options.address, true).send({from: owner});450 await helpers.methods.toggleAllowed(flipper.options.address, caller, true).send({from: owner});451452 await helpers.methods.setSponsoringMode(flipper.options.address, SponsoringMode.Allowlisted).send({from: owner});453 await helpers.methods.setSponsoringRateLimit(flipper.options.address, 10).send({from: owner});454455 await helpers.methods.setSponsor(flipper.options.address, sponsor).send();456 await helpers.methods.confirmSponsorship(flipper.options.address).send({from: sponsor});457458 const originalFlipperBalance = await web3.eth.getBalance(sponsor);459 expect(originalFlipperBalance).to.be.not.equal('0');460461 await flipper.methods.flip().send({from: caller});462 expect(await flipper.methods.getValue().call()).to.be.true;463 expect(await web3.eth.getBalance(caller)).to.be.equals(originalCallerBalance);464465 const newFlipperBalance = await web3.eth.getBalance(sponsor);466 expect(newFlipperBalance).to.be.not.equals(originalFlipperBalance);467468 await flipper.methods.flip().send({from: caller});469 expect(await web3.eth.getBalance(sponsor)).to.be.equal(newFlipperBalance);470 expect(await web3.eth.getBalance(caller)).to.be.not.equals(originalCallerBalance);471 });472473 // TODO: Find a way to calculate default rate limit474 itWeb3('Default rate limit equals 7200', async ({api, web3, privateKeyWrapper}) => {475 const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);476 const flipper = await deployFlipper(web3, owner);477 const helpers = contractHelpers(web3, owner);478 expect(await helpers.methods.getSponsoringRateLimit(flipper.options.address).call()).to.be.equals('7200');479 });480});tests/src/util/helpers.tsdiffbeforeafterboth--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -17,10 +17,11 @@
import '../interfaces/augment-api-rpc';
import '../interfaces/augment-api-query';
import {ApiPromise} from '@polkadot/api';
-import type {AccountId, EventRecord, Event} from '@polkadot/types/interfaces';
+import type {AccountId, EventRecord, Event, BlockNumber} from '@polkadot/types/interfaces';
import type {GenericEventData} from '@polkadot/types';
import {AnyTuple, IEvent, IKeyringPair} from '@polkadot/types/types';
import {evmToAddress} from '@polkadot/util-crypto';
+import {AnyNumber} from '@polkadot/types-codec/types';
import BN from 'bn.js';
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
@@ -1780,3 +1781,23 @@
itApi.only = (name: string, cb: (apis: { api: ApiPromise, privateKeyWrapper: (account: string) => IKeyringPair }) => any) => itApi(name, cb, {only: true});
itApi.skip = (name: string, cb: (apis: { api: ApiPromise, privateKeyWrapper: (account: string) => IKeyringPair }) => any) => itApi(name, cb, {skip: true});
+
+
+export async function expectSubstrateEventsAtBlock(api: ApiPromise, blockNumber: AnyNumber | BlockNumber, section: string, methods: string[], dryRun = false) {
+ const blockHash = await api.rpc.chain.getBlockHash(blockNumber);
+ const subEvents = (await api.query.system.events.at(blockHash))
+ .filter(x => x.event.section === section)
+ .map((x) => x.toHuman());
+ const events = methods.map((m) => {
+ return {
+ event: {
+ method: m,
+ section,
+ },
+ };
+ });
+ if (!dryRun) {
+ expect(subEvents).to.be.like(events);
+ }
+ return subEvents;
+}
\ No newline at end of file