1234567891011121314151617import {IKeyringPair} from '@polkadot/types/types';18import {usingPlaygrounds, expect, itSub, Pallets} from './util';1920async function setSponsorHelper(collection: any, signer: IKeyringPair, sponsorAddress: string) {21 await collection.setSponsor(signer, sponsorAddress);22 const raw = (await collection.getData())?.raw;23 expect(raw.sponsorship.Unconfirmed).to.be.equal(sponsorAddress);24}2526async function confirmSponsorHelper(collection: any, signer: IKeyringPair) {27 await collection.confirmSponsorship(signer);28 const raw = (await collection.getData())?.raw;29 expect(raw.sponsorship.Confirmed).to.be.equal(signer.address);30}3132describe('integration test: ext. confirmSponsorship():', () => {33 let alice: IKeyringPair;34 let bob: IKeyringPair;35 let charlie: IKeyringPair;36 let zeroBalance: IKeyringPair;3738 before(async () => {39 await usingPlaygrounds(async (helper, privateKey) => {40 const donor = await privateKey({filename: __filename});41 [alice, bob, charlie, zeroBalance] = await helper.arrange.createAccounts([100n, 100n, 100n, 0n], donor);42 });43 });4445 itSub('Confirm collection sponsorship', async ({helper}) => {46 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});47 await setSponsorHelper(collection, alice, bob.address);48 await confirmSponsorHelper(collection, bob);49 });5051 itSub('Add sponsor to a collection after the same sponsor was already added and confirmed', async ({helper}) => {52 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});53 await setSponsorHelper(collection, alice, bob.address);54 await confirmSponsorHelper(collection, bob);55 await setSponsorHelper(collection, alice, bob.address);56 });57 itSub('Add new sponsor to a collection after another sponsor was already added and confirmed', async ({helper}) => {58 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});59 await setSponsorHelper(collection, alice, bob.address);60 await confirmSponsorHelper(collection, bob);61 await setSponsorHelper(collection, alice, charlie.address);62 });6364 itSub('NFT: Transfer fees are paid by the sponsor after confirmation', async ({helper}) => {65 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});66 await collection.setSponsor(alice, bob.address);67 await collection.confirmSponsorship(bob);68 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);69 const token = await collection.mintToken(alice, {Substrate: zeroBalance.address});70 await token.transfer(zeroBalance, {Substrate: alice.address});71 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);72 expect(bobBalanceAfter < bobBalanceBefore).to.be.true;73 });7475 itSub('Fungible: Transfer fees are paid by the sponsor after confirmation', async ({helper}) => {76 const collection = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});77 await collection.setSponsor(alice, bob.address);78 await collection.confirmSponsorship(bob);79 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);80 await collection.mint(alice, 100n, {Substrate: zeroBalance.address});81 await collection.transfer(zeroBalance, {Substrate: alice.address}, 1n);82 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);83 expect(bobBalanceAfter < bobBalanceBefore).to.be.true;84 });8586 itSub.ifWithPallets('ReFungible: Transfer fees are paid by the sponsor after confirmation', [Pallets.ReFungible], async ({helper}) => {87 const collection = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});88 await collection.setSponsor(alice, bob.address);89 await collection.confirmSponsorship(bob);90 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);91 const token = await collection.mintToken(alice, 100n, {Substrate: zeroBalance.address});92 await token.transfer(zeroBalance, {Substrate: alice.address}, 1n);93 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);94 expect(bobBalanceAfter < bobBalanceBefore).to.be.true;95 });9697 itSub('CreateItem fees are paid by the sponsor after confirmation', async ({helper}) => {98 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});99 await collection.setSponsor(alice, bob.address);100 await collection.confirmSponsorship(bob);101 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});102 await collection.addToAllowList(alice, {Substrate: zeroBalance.address});103104 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);105 await collection.mintToken(zeroBalance, {Substrate: zeroBalance.address});106 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);107108 expect(bobBalanceAfter < bobBalanceBefore).to.be.true;109 });110111 itSub('NFT: Sponsoring of transfers is rate limited', async ({helper}) => {112 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL', limits: {113 sponsorTransferTimeout: 1000,114 }});115 await collection.setSponsor(alice, bob.address);116 await collection.confirmSponsorship(bob);117118 const token = await collection.mintToken(alice, {Substrate: alice.address});119 await token.transfer(alice, {Substrate: zeroBalance.address});120 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);121122 const transferTx = () => token.transfer(zeroBalance, {Substrate: alice.address});123 await expect(transferTx()).to.be.rejectedWith('Inability to pay some fees');124 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);125126 expect(bobBalanceAfter === bobBalanceBefore).to.be.true;127 });128129 itSub('Fungible: Sponsoring is rate limited', async ({helper}) => {130 const collection = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL', limits: {131 sponsorTransferTimeout: 1000,132 }});133 await collection.setSponsor(alice, bob.address);134 await collection.confirmSponsorship(bob);135136 await collection.mint(alice, 100n, {Substrate: zeroBalance.address});137 await collection.transfer(zeroBalance, {Substrate: zeroBalance.address}, 1n);138 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);139140 const transferTx = () => collection.transfer(zeroBalance, {Substrate: zeroBalance.address});141 await expect(transferTx()).to.be.rejected;142 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);143144 expect(bobBalanceAfter === bobBalanceBefore).to.be.true;145 });146147 itSub.ifWithPallets('ReFungible: Sponsoring is rate limited', [Pallets.ReFungible], async ({helper}) => {148 const collection = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL', limits: {149 sponsorTransferTimeout: 1000,150 }});151 await collection.setSponsor(alice, bob.address);152 await collection.confirmSponsorship(bob);153154 const token = await collection.mintToken(alice, 100n, {Substrate: zeroBalance.address});155 await token.transfer(zeroBalance, {Substrate: alice.address});156157 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);158 const transferTx = () => token.transfer(zeroBalance, {Substrate: alice.address});159 await expect(transferTx()).to.be.rejectedWith('Inability to pay some fees');160 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);161162 expect(bobBalanceAfter === bobBalanceBefore).to.be.true;163 });164165 itSub('NFT: Sponsoring of createItem is rate limited', async ({helper}) => {166 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL', limits: {167 sponsoredDataRateLimit: {blocks: 1000},168 sponsorTransferTimeout: 1000,169 }});170 await collection.setSponsor(alice, bob.address);171 await collection.confirmSponsorship(bob);172 await collection.setPermissions(alice, {mintMode: true, access: 'AllowList'});173 await collection.addToAllowList(alice, {Substrate: zeroBalance.address});174175 await collection.mintToken(zeroBalance, {Substrate: zeroBalance.address});176177 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);178 const mintTx = () => collection.mintToken(zeroBalance, {Substrate: zeroBalance.address});179 await expect(mintTx()).to.be.rejectedWith('Inability to pay some fees');180 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);181182 expect(bobBalanceAfter === bobBalanceBefore).to.be.true;183 });184});185186describe('(!negative test!) integration test: ext. confirmSponsorship():', () => {187 let alice: IKeyringPair;188 let bob: IKeyringPair;189 let charlie: IKeyringPair;190 let ownerZeroBalance: IKeyringPair;191 let senderZeroBalance: IKeyringPair;192193 before(async () => {194 await usingPlaygrounds(async (helper, privateKey) => {195 const donor = await privateKey({filename: __filename});196 [alice, bob, charlie, ownerZeroBalance, senderZeroBalance] = await helper.arrange.createAccounts([100n, 100n, 100n, 0n, 0n], donor);197 });198 });199200 itSub('(!negative test!) Confirm sponsorship for a collection that never existed', async ({helper}) => {201 const collectionId = (1 << 32) - 1;202 const confirmSponsorshipTx = () => helper.collection.confirmSponsorship(bob, collectionId);203 await expect(confirmSponsorshipTx()).to.be.rejectedWith(/common\.CollectionNotFound/);204 });205206 itSub('(!negative test!) Confirm sponsorship using a non-sponsor address', async ({helper}) => {207 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});208 await collection.setSponsor(alice, bob.address);209 const confirmSponsorshipTx = () => collection.confirmSponsorship(charlie);210 await expect(confirmSponsorshipTx()).to.be.rejectedWith(/common\.ConfirmSponsorshipFail/);211 });212213 itSub('(!negative test!) Confirm sponsorship using owner address', async ({helper}) => {214 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});215 await collection.setSponsor(alice, bob.address);216 const confirmSponsorshipTx = () => collection.confirmSponsorship(alice);217 await expect(confirmSponsorshipTx()).to.be.rejectedWith(/common\.ConfirmSponsorshipFail/);218 });219220 itSub('(!negative test!) Confirm sponsorship by collection admin', async ({helper}) => {221 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});222 await collection.setSponsor(alice, bob.address);223 await collection.addAdmin(alice, {Substrate: charlie.address});224 const confirmSponsorshipTx = () => collection.confirmSponsorship(charlie);225 await expect(confirmSponsorshipTx()).to.be.rejectedWith(/common\.ConfirmSponsorshipFail/);226 });227228 itSub('(!negative test!) Confirm sponsorship without sponsor being set with setCollectionSponsor', async ({helper}) => {229 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});230 const confirmSponsorshipTx = () => collection.confirmSponsorship(charlie);231 await expect(confirmSponsorshipTx()).to.be.rejectedWith(/common\.ConfirmSponsorshipFail/);232 });233234 itSub('(!negative test!) Confirm sponsorship in a collection that was destroyed', async ({helper}) => {235 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});236 await collection.burn(alice);237 const confirmSponsorshipTx = () => collection.confirmSponsorship(charlie);238 await expect(confirmSponsorshipTx()).to.be.rejectedWith(/common\.CollectionNotFound/);239 });240241 itSub('(!negative test!) Transfer fees are not paid by the sponsor if the transfer failed', async ({helper}) => {242 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});243 await collection.setSponsor(alice, bob.address);244 await collection.confirmSponsorship(bob);245 const token = await collection.mintToken(alice, {Substrate: ownerZeroBalance.address});246 const sponsorBalanceBefore = await helper.balance.getSubstrate(bob.address);247 const transferTx = () => token.transfer(senderZeroBalance, {Substrate: alice.address});248 await expect(transferTx()).to.be.rejectedWith('Inability to pay some fees');249 const sponsorBalanceAfter = await helper.balance.getSubstrate(bob.address);250 expect(sponsorBalanceAfter).to.equal(sponsorBalanceBefore);251 });252});