1234567891011121314151617import {IKeyringPair} from '@polkadot/types/types';18import {Pallets, requirePalletsOrSkip, usingPlaygrounds} from '../util/index';19import {itEth, expect} from './util';2021describe('evm nft collection sponsoring', () => {22 let donor: IKeyringPair;23 let alice: IKeyringPair;24 let nominal: bigint;2526 before(async () => {27 await usingPlaygrounds(async (helper, privateKey) => {28 donor = await privateKey({filename: __filename});29 [alice] = await helper.arrange.createAccounts([100n], donor);30 nominal = helper.balance.getOneTokenNominal();31 });32 });3334 35 itEth('sponsors mint transactions', async ({helper}) => {36 const collection = await helper.nft.mintCollection(alice, {tokenPrefix: 'spnr', permissions: {mintMode: true}});37 await collection.setSponsor(alice, alice.address);38 await collection.confirmSponsorship(alice);3940 const minter = helper.eth.createAccount();41 expect(await helper.balance.getEthereum(minter)).to.equal(0n);4243 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);44 const contract = await helper.ethNativeContract.collection(collectionAddress, 'nft', minter);4546 await collection.addToAllowList(alice, {Ethereum: minter});4748 const result = await contract.methods.mint(minter).send();4950 const events = helper.eth.normalizeEvents(result.events);51 expect(events).to.be.deep.equal([52 {53 address: collectionAddress,54 event: 'Transfer',55 args: {56 from: '0x0000000000000000000000000000000000000000',57 to: minter,58 tokenId: '1',59 },60 },61 ]);62 });6364 65 66 67 68 69 70 71 7273 74 75 7677 78 79 8081 82 83 8485 [86 'setCollectionSponsorCross',87 'setCollectionSponsor', 88 ].map(testCase =>89 itEth(`[${testCase}] can remove collection sponsor`, async ({helper}) => {90 const owner = await helper.eth.createAccountWithBalance(donor);91 const collectionHelpers = await helper.ethNativeContract.collectionHelpers(owner);9293 let result = await collectionHelpers.methods.createNFTCollection('Sponsor collection', '1', '1').send({value: Number(2n * nominal)});94 const collectionIdAddress = helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);95 const sponsor = await helper.eth.createAccountWithBalance(donor);96 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);97 const collectionEvm = await helper.ethNativeContract.collection(collectionIdAddress, 'nft', owner, testCase === 'setCollectionSponsor');9899 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;100 result = await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsor : sponsorCross).send({from: owner});101 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.true;102103 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});104 let sponsorTuple = await collectionEvm.methods.collectionSponsor().call({from: owner});105 expect(helper.address.restoreCrossAccountFromBigInt(BigInt(sponsorTuple.sub))).to.be.eq(helper.address.ethToSubstrate(sponsor, true));106 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;107108 await collectionEvm.methods.removeCollectionSponsor().send({from: owner});109110 sponsorTuple = await collectionEvm.methods.collectionSponsor().call({from: owner});111 expect(sponsorTuple.eth).to.be.eq('0x0000000000000000000000000000000000000000');112 }));113114 [115 'setCollectionSponsorCross',116 'setCollectionSponsor', 117 ].map(testCase =>118 itEth(`[${testCase}] Can sponsor from evm address via access list`, async ({helper}) => {119 const owner = await helper.eth.createAccountWithBalance(donor);120 const sponsorEth = await helper.eth.createAccountWithBalance(donor);121 const sponsorCrossEth = helper.ethCrossAccount.fromAddress(sponsorEth);122123 const {collectionId, collectionAddress} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner, 'Sponsor collection', '1', '1', '');124125 const collectionSub = helper.nft.getCollectionObject(collectionId);126 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner, testCase === 'setCollectionSponsor');127128 129 await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsorEth : sponsorCrossEth).send({from: owner});130 let sponsorship = (await collectionSub.getData())!.raw.sponsorship;131 expect(sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsorEth, true));132 133 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');134135 136 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsorEth});137 sponsorship = (await collectionSub.getData())!.raw.sponsorship;138 expect(sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsorEth, true));139140 141 const user = helper.eth.createAccount();142 const userCross = helper.ethCrossAccount.fromAddress(user);143 const nextTokenId = await collectionEvm.methods.nextTokenId().call();144 expect(nextTokenId).to.be.equal('1');145146 147 const oldPermissions = (await collectionSub.getData())!.raw.permissions;148 expect(oldPermissions.mintMode).to.be.false;149 expect(oldPermissions.access).to.be.equal('Normal');150151 await collectionEvm.methods.setCollectionAccess(1 ).send({from: owner});152 await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});153 await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});154 155 const newPermissions = (await collectionSub.getData())!.raw.permissions;156 expect(newPermissions.mintMode).to.be.true;157 expect(newPermissions.access).to.be.equal('AllowList');158159 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));160 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));161162 163 {164 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});165 const event = helper.eth.normalizeEvents(result.events)166 .find(event => event.event === 'Transfer');167168 expect(event).to.be.deep.equal({169 address: collectionAddress,170 event: 'Transfer',171 args: {172 from: '0x0000000000000000000000000000000000000000',173 to: user,174 tokenId: '1',175 },176 });177178 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));179 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));180 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));181182 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');183 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);184 expect(userBalanceAfter).to.be.eq(0n);185 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;186 }187 }));188189 190 191 192 193 194 195 196 197198 199200 201 202203 204 205 206207 208 209 210211 212 213214 215 216 217 218 219 220 221 222 223224 225 226 227 228 229 230 231 232 233 234 235236 237 238239 240 241 242 243 244245 [246 'setCollectionSponsorCross',247 'setCollectionSponsor', 248 ].map(testCase =>249 itEth(`[${testCase}] Check that transaction via EVM spend money from sponsor address`, async ({helper}) => {250 const owner = await helper.eth.createAccountWithBalance(donor);251 const sponsor = await helper.eth.createAccountWithBalance(donor);252 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);253254 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner,'Sponsor collection', '1', '1', '');255256 const collectionSub = helper.nft.getCollectionObject(collectionId);257 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner, testCase === 'setCollectionSponsor');258 259 await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsor : sponsorCross).send();260 let collectionData = (await collectionSub.getData())!;261 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));262 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('ConfirmSponsorshipFail');263264 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});265 collectionData = (await collectionSub.getData())!;266 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));267268 const user = helper.eth.createAccount();269 const userCross = helper.ethCrossAccount.fromAddress(user);270 await collectionEvm.methods.addCollectionAdminCross(userCross).send();271272 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));273 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));274275 const mintingResult = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});276 const tokenId = mintingResult.events.Transfer.returnValues.tokenId;277278 const event = helper.eth.normalizeEvents(mintingResult.events)279 .find(event => event.event === 'Transfer');280 const address = helper.ethAddress.fromCollectionId(collectionId);281282 expect(event).to.be.deep.equal({283 address,284 event: 'Transfer',285 args: {286 from: '0x0000000000000000000000000000000000000000',287 to: user,288 tokenId: '1',289 },290 });291 expect(await collectionEvm.methods.tokenURI(tokenId).call({from: user})).to.be.equal('Test URI');292293 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));294 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);295 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));296 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;297 }));298299 itEth('Can reassign collection sponsor', async ({helper}) => {300 const owner = await helper.eth.createAccountWithBalance(donor);301 const sponsorEth = await helper.eth.createAccountWithBalance(donor);302 const sponsorCrossEth = helper.ethCrossAccount.fromAddress(sponsorEth);303 const [sponsorSub] = await helper.arrange.createAccounts([100n], donor);304 const sponsorCrossSub = helper.ethCrossAccount.fromKeyringPair(sponsorSub);305306 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleNFTCollection(owner,'Sponsor collection', '1', '1', '');307 const collectionSub = helper.nft.getCollectionObject(collectionId);308 const collectionEvm = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner);309310 311 await collectionEvm.methods.setCollectionSponsorCross(sponsorCrossEth).send({from: owner});312 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsorEth});313314 315 await collectionEvm.methods.setCollectionSponsorCross(sponsorCrossSub).send({from: owner});316 const collectionSponsor = (await collectionSub.getData())?.raw.sponsorship;317 expect(collectionSponsor).to.deep.eq({Unconfirmed: sponsorSub.address});318 });319});320321describe('evm RFT collection sponsoring', () => {322 let donor: IKeyringPair;323 let alice: IKeyringPair;324 let nominal: bigint;325326 before(async function() {327 await usingPlaygrounds(async (helper, privateKey) => {328 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);329 donor = await privateKey({filename: __filename});330 [alice] = await helper.arrange.createAccounts([100n], donor);331 nominal = helper.balance.getOneTokenNominal();332 });333 });334 335 itEth('sponsors mint transactions', async ({helper}) => {336 const collection = await helper.rft.mintCollection(alice, {tokenPrefix: 'spnr', permissions: {mintMode: true}});337 await collection.setSponsor(alice, alice.address);338 await collection.confirmSponsorship(alice);339340 const minter = helper.eth.createAccount();341 expect(await helper.balance.getEthereum(minter)).to.equal(0n);342343 const collectionAddress = helper.ethAddress.fromCollectionId(collection.collectionId);344 const contract = helper.ethNativeContract.collection(collectionAddress, 'rft', minter);345346 await collection.addToAllowList(alice, {Ethereum: minter});347348 const result = await contract.methods.mint(minter).send();349350 const events = helper.eth.normalizeEvents(result.events);351 expect(events).to.deep.include({352 address: collectionAddress,353 event: 'Transfer',354 args: {355 from: '0x0000000000000000000000000000000000000000',356 to: minter,357 tokenId: '1',358 },359 });360 });361362 363 364 365 366 367 368 369 370371 372 373 374375 376 377 378379 380 381 382383 [384 'setCollectionSponsorCross',385 'setCollectionSponsor', 386 ].map(testCase => 387 itEth(`[${testCase}] can remove collection sponsor`, async ({helper}) => {388 const owner = await helper.eth.createAccountWithBalance(donor);389 const collectionHelpers = helper.ethNativeContract.collectionHelpers(owner);390 391 let result = await collectionHelpers.methods.createRFTCollection('Sponsor collection', '1', '1').send({value: Number(2n * nominal)});392 const collectionIdAddress = helper.ethAddress.normalizeAddress(result.events.CollectionCreated.returnValues.collectionId);393 const sponsor = await helper.eth.createAccountWithBalance(donor);394 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);395 const collectionEvm = helper.ethNativeContract.collection(collectionIdAddress, 'rft', owner, testCase === 'setCollectionSponsor');396 397 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;398 result = await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsor : sponsorCross).send({from: owner});399 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.true;400 401 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});402 expect(await collectionEvm.methods.hasCollectionPendingSponsor().call({from: owner})).to.be.false;403 404 await collectionEvm.methods.removeCollectionSponsor().send({from: owner});405 406 const sponsorTuple = await collectionEvm.methods.collectionSponsor().call({from: owner});407 expect(sponsorTuple.field_0).to.be.eq('0x0000000000000000000000000000000000000000');408 }));409410 [411 'setCollectionSponsorCross',412 'setCollectionSponsor', 413 ].map(testCase => 414 itEth(`[${testCase}] Can sponsor from evm address via access list`, async ({helper}) => {415 const owner = await helper.eth.createAccountWithBalance(donor);416 const sponsorEth = await helper.eth.createAccountWithBalance(donor);417 const sponsorCrossEth = helper.ethCrossAccount.fromAddress(sponsorEth);418 419 const {collectionId, collectionAddress} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner, 'Sponsor collection', '1', '1', '');420 421 const collectionSub = helper.rft.getCollectionObject(collectionId);422 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner, testCase === 'setCollectionSponsor');423 424 425 await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsorEth : sponsorCrossEth).send({from: owner});426 let sponsorship = (await collectionSub.getData())!.raw.sponsorship;427 expect(sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsorEth, true));428 429 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');430 431 432 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsorEth});433 sponsorship = (await collectionSub.getData())!.raw.sponsorship;434 expect(sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsorEth, true));435 436 437 const user = helper.eth.createAccount();438 const userCross = helper.ethCrossAccount.fromAddress(user);439 const nextTokenId = await collectionEvm.methods.nextTokenId().call();440 expect(nextTokenId).to.be.equal('1');441 442 443 const oldPermissions = (await collectionSub.getData())!.raw.permissions;444 expect(oldPermissions.mintMode).to.be.false;445 expect(oldPermissions.access).to.be.equal('Normal');446447 await collectionEvm.methods.setCollectionAccess(1 ).send({from: owner});448 await collectionEvm.methods.addToCollectionAllowListCross(userCross).send({from: owner});449 await collectionEvm.methods.setCollectionMintMode(true).send({from: owner});450 451 const newPermissions = (await collectionSub.getData())!.raw.permissions;452 expect(newPermissions.mintMode).to.be.true;453 expect(newPermissions.access).to.be.equal('AllowList');454 455 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));456 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));457458 459 {460 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});461 const events = helper.eth.normalizeEvents(result.events);462463 expect(events).to.deep.include({464 address: collectionAddress,465 event: 'Transfer',466 args: {467 from: '0x0000000000000000000000000000000000000000',468 to: user,469 tokenId: '1',470 },471 });472 473 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));474 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsorEth));475 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));476 477 expect(await collectionEvm.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI');478 expect(ownerBalanceBefore).to.be.eq(ownerBalanceAfter);479 expect(userBalanceAfter).to.be.eq(0n);480 expect(sponsorBalanceBefore > sponsorBalanceAfter).to.be.true;481 }482 }));483484 485 486 487 488 489 490 491 492493 494495 496 497498 499 500 501502 503 504 505506 507 508509 510 511 512 513 514 515 516 517 518519 520 521 522 523 524 525 526 527 528 529 530531 532 533534 535 536 537 538 539540 [541 'setCollectionSponsorCross',542 'setCollectionSponsor', 543 ].map(testCase => 544 itEth(`[${testCase}] Check that transaction via EVM spend money from sponsor address`, async ({helper}) => {545 const owner = await helper.eth.createAccountWithBalance(donor);546 const sponsor = await helper.eth.createAccountWithBalance(donor);547 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);548 549 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');550551 const collectionSub = helper.rft.getCollectionObject(collectionId);552 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner, testCase === 'setCollectionSponsor');553 554 await collectionEvm.methods[testCase](testCase === 'setCollectionSponsor' ? sponsor : sponsorCross).send();555 let collectionData = (await collectionSub.getData())!;556 expect(collectionData.raw.sponsorship.Unconfirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));557 await expect(collectionEvm.methods.confirmCollectionSponsorship().call()).to.be.rejectedWith('caller is not set as sponsor');558 559 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});560 collectionData = (await collectionSub.getData())!;561 expect(collectionData.raw.sponsorship.Confirmed).to.be.eq(helper.address.ethToSubstrate(sponsor, true));562 563 const user = helper.eth.createAccount();564 const userCross = helper.ethCrossAccount.fromAddress(user);565 await collectionEvm.methods.addCollectionAdminCross(userCross).send();566 567 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));568 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));569 570 const mintingResult = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});571 const tokenId = mintingResult.events.Transfer.returnValues.tokenId;572 573 const events = helper.eth.normalizeEvents(mintingResult.events);574 const address = helper.ethAddress.fromCollectionId(collectionId);575 576 expect(events).to.deep.include({577 address,578 event: 'Transfer',579 args: {580 from: '0x0000000000000000000000000000000000000000',581 to: user,582 tokenId: '1',583 },584 });585 expect(await collectionEvm.methods.tokenURI(tokenId).call({from: user})).to.be.equal('Test URI');586 587 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));588 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);589 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));590 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;591 }));592593 itEth('Check that transaction via EVM spend money from substrate sponsor address', async ({helper}) => {594 const owner = await helper.eth.createAccountWithBalance(donor);595 const sponsor = alice;596 const sponsorCross = helper.ethCrossAccount.fromKeyringPair(sponsor);597598 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');599600 const collectionSub = helper.rft.getCollectionObject(collectionId);601 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner, false);602 603 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();604605 await collectionSub.confirmSponsorship(sponsor);606607 const user = helper.eth.createAccount();608 const userCross = helper.ethCrossAccount.fromAddress(user);609 await collectionEvm.methods.addCollectionAdminCross(userCross).send();610611 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));612 const sponsorBalanceBefore = await helper.balance.getSubstrate(sponsor.address);613 614 const mintingResult = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});615 const tokenId = mintingResult.events.Transfer.returnValues.tokenId;616617 const events = helper.eth.normalizeEvents(mintingResult.events);618 const address = helper.ethAddress.fromCollectionId(collectionId);619620 expect(events).to.deep.include({621 address,622 event: 'Transfer',623 args: {624 from: '0x0000000000000000000000000000000000000000',625 to: user,626 tokenId: '1',627 },628 });629 expect(await collectionEvm.methods.tokenURI(tokenId).call({from: user})).to.be.equal('Test URI');630631 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));632 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);633 const sponsorBalanceAfter = await helper.balance.getSubstrate(sponsor.address);634 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;635 });636637 itEth('Can reassign collection sponsor', async ({helper}) => {638 const owner = await helper.eth.createAccountWithBalance(donor);639 const sponsorEth = await helper.eth.createAccountWithBalance(donor);640 const sponsorCrossEth = helper.ethCrossAccount.fromAddress(sponsorEth);641 const [sponsorSub] = await helper.arrange.createAccounts([100n], donor);642 const sponsorCrossSub = helper.ethCrossAccount.fromKeyringPair(sponsorSub);643644 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');645 const collectionSub = helper.rft.getCollectionObject(collectionId);646 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);647648 649 await collectionEvm.methods.setCollectionSponsorCross(sponsorCrossEth).send({from: owner});650 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsorEth});651652 653 await collectionEvm.methods.setCollectionSponsorCross(sponsorCrossSub).send({from: owner});654 const collectionSponsor = (await collectionSub.getData())?.raw.sponsorship;655 expect(collectionSponsor).to.deep.eq({Unconfirmed: sponsorSub.address});656 });657});658659describe('evm RFT token sponsoring', () => {660 let donor: IKeyringPair;661662 before(async function() {663 await usingPlaygrounds(async (helper, privateKey) => {664 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);665 donor = await privateKey({filename: __filename});666 });667 });668669 itEth('[cross] Check that transfer via EVM spend money from sponsor address', async ({helper}) => {670 const owner = await helper.eth.createAccountWithBalance(donor);671672 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');673 const sponsor = await helper.eth.createAccountWithBalance(donor);674 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);675 const receiver = await helper.eth.createAccountWithBalance(donor);676 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);677678 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();679 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});680681 const user = await helper.eth.createAccountWithBalance(donor);682 const userCross = helper.ethCrossAccount.fromAddress(user);683 await collectionEvm.methods.addCollectionAdminCross(userCross).send();684685 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});686 const tokenId = result.events.Transfer.returnValues.tokenId;687688 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, user); 689 await tokenContract.methods.repartition(2).send();690 691 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));692 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));693 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));694695 await tokenContract.methods.transfer(receiver, 1).send();696697 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));698 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);699 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));700 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;701 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));702 expect(userBalanceAfter).to.be.eq(userBalanceBefore);703 });704705 itEth('[cross] Check that approve via EVM spend money from sponsor address', async ({helper}) => {706 const owner = await helper.eth.createAccountWithBalance(donor);707708 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');709 const sponsor = await helper.eth.createAccountWithBalance(donor);710 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);711 const receiver = await helper.eth.createAccountWithBalance(donor);712 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);713714 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();715 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});716717 const user = await helper.eth.createAccountWithBalance(donor);718 const userCross = helper.ethCrossAccount.fromAddress(user);719 await collectionEvm.methods.addCollectionAdminCross(userCross).send();720721 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});722 const tokenId = result.events.Transfer.returnValues.tokenId;723724 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, user); 725 await tokenContract.methods.repartition(2).send();726 727 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));728 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));729 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));730731 await tokenContract.methods.approve(receiver, 1).send();732733 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));734 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);735 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));736 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;737 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));738 expect(userBalanceAfter).to.be.eq(userBalanceBefore);739 });740 741742 itEth('[cross] Check that transferFrom via EVM spend money from sponsor address', async ({helper}) => {743 const owner = await helper.eth.createAccountWithBalance(donor);744745 const {collectionAddress, collectionId} = await helper.eth.createERC721MetadataCompatibleRFTCollection(owner,'Sponsor collection', '1', '1', '');746 const sponsor = await helper.eth.createAccountWithBalance(donor);747 const sponsorCross = helper.ethCrossAccount.fromAddress(sponsor);748 const receiver = await helper.eth.createAccountWithBalance(donor);749 const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'rft', owner);750751 await collectionEvm.methods.setCollectionSponsorCross(sponsorCross).send();752 await collectionEvm.methods.confirmCollectionSponsorship().send({from: sponsor});753754 const user = await helper.eth.createAccountWithBalance(donor);755 const userCross = helper.ethCrossAccount.fromAddress(user);756 await collectionEvm.methods.addCollectionAdminCross(userCross).send();757758 const result = await collectionEvm.methods.mintWithTokenURI(user, 'Test URI').send({from: user});759 const tokenId = result.events.Transfer.returnValues.tokenId;760761 const tokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, user); 762 await tokenContract.methods.repartition(2).send();763 await tokenContract.methods.approve(receiver, 1).send();764 765 const ownerBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));766 const sponsorBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));767 const userBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));768 const receiverBalanceBefore = await helper.balance.getSubstrate(helper.address.ethToSubstrate(receiver));769770 const receiverTokenContract = helper.ethNativeContract.rftTokenById(collectionId, tokenId, receiver); 771 await receiverTokenContract.methods.transferFrom(user, receiver, 1).send();772773 const receiverBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(receiver));774 expect(receiverBalanceAfter).to.be.eq(receiverBalanceBefore);775 const ownerBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(owner));776 expect(ownerBalanceAfter).to.be.eq(ownerBalanceBefore);777 const sponsorBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(sponsor));778 expect(sponsorBalanceAfter < sponsorBalanceBefore).to.be.true;779 const userBalanceAfter = await helper.balance.getSubstrate(helper.address.ethToSubstrate(user));780 expect(userBalanceAfter).to.be.eq(userBalanceBefore);781 });782});