1234567891011121314151617import type {IKeyringPair} from '@polkadot/types/types';18import {usingPlaygrounds, expect, itSub, Pallets} from './util/index.js';19import {NON_EXISTENT_COLLECTION_ID} from '@unique/playgrounds/types.js';2021async function setSponsorHelper(collection: any, signer: IKeyringPair, sponsorAddress: string) {22 await collection.setSponsor(signer, sponsorAddress);23 const raw = (await collection.getData())?.raw;24 expect(raw.sponsorship.Unconfirmed).to.be.equal(sponsorAddress);25}2627async function confirmSponsorHelper(collection: any, signer: IKeyringPair) {28 await collection.confirmSponsorship(signer);29 const raw = (await collection.getData())?.raw;30 expect(raw.sponsorship.Confirmed).to.be.equal(signer.address);31}3233describe('integration test: ext. confirmSponsorship():', () => {34 let alice: IKeyringPair;35 let bob: IKeyringPair;36 let charlie: IKeyringPair;37 let zeroBalance: IKeyringPair;3839 before(async () => {40 await usingPlaygrounds(async (helper, privateKey) => {41 const donor = await privateKey({url: import.meta.url});42 [alice, bob, charlie, zeroBalance] = await helper.arrange.createAccounts([100n, 100n, 100n, 0n], donor);43 });44 });4546 itSub('Confirm collection sponsorship', async ({helper}) => {47 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});48 await setSponsorHelper(collection, alice, bob.address);49 await confirmSponsorHelper(collection, bob);50 });5152 itSub('Add sponsor to a collection after the same sponsor was already added and confirmed', async ({helper}) => {53 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});54 await setSponsorHelper(collection, alice, bob.address);55 await confirmSponsorHelper(collection, bob);56 await setSponsorHelper(collection, alice, bob.address);57 });58 itSub('Add new sponsor to a collection after another sponsor was already added and confirmed', async ({helper}) => {59 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});60 await setSponsorHelper(collection, alice, bob.address);61 await confirmSponsorHelper(collection, bob);62 await setSponsorHelper(collection, alice, charlie.address);63 });6465 itSub('NFT: Transfer fees are paid by the sponsor after confirmation', async ({helper}) => {66 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});67 await collection.setSponsor(alice, bob.address);68 await collection.confirmSponsorship(bob);69 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);70 const token = await collection.mintToken(alice, {Substrate: zeroBalance.address});71 await token.transfer(zeroBalance, {Substrate: alice.address});72 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);73 expect(bobBalanceAfter < bobBalanceBefore).to.be.true;74 });7576 itSub('Fungible: Transfer fees are paid by the sponsor after confirmation', async ({helper}) => {77 const collection = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});78 await collection.setSponsor(alice, bob.address);79 await collection.confirmSponsorship(bob);80 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);81 await collection.mint(alice, 100n, {Substrate: zeroBalance.address});82 await collection.transfer(zeroBalance, {Substrate: alice.address}, 1n);83 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);84 expect(bobBalanceAfter < bobBalanceBefore).to.be.true;85 });8687 itSub.ifWithPallets('ReFungible: Transfer fees are paid by the sponsor after confirmation', [Pallets.ReFungible], async ({helper}) => {88 const collection = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});89 await collection.setSponsor(alice, bob.address);90 await collection.confirmSponsorship(bob);91 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);92 const token = await collection.mintToken(alice, 100n, {Substrate: zeroBalance.address});93 await token.transfer(zeroBalance, {Substrate: alice.address}, 1n);94 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);95 expect(bobBalanceAfter < bobBalanceBefore).to.be.true;96 });9798 itSub('CreateItem fees are paid by the sponsor after confirmation', async ({helper}) => {99 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});100 await collection.setSponsor(alice, bob.address);101 await collection.confirmSponsorship(bob);102 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});103 await collection.addToAllowList(alice, {Substrate: zeroBalance.address});104105 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);106 await collection.mintToken(zeroBalance, {Substrate: zeroBalance.address});107 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);108109 expect(bobBalanceAfter < bobBalanceBefore).to.be.true;110 });111112 itSub('NFT: Sponsoring of transfers is rate limited', async ({helper}) => {113 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL', limits: {114 sponsorTransferTimeout: 1000,115 }});116 await collection.setSponsor(alice, bob.address);117 await collection.confirmSponsorship(bob);118119 const token = await collection.mintToken(alice, {Substrate: alice.address});120 await token.transfer(alice, {Substrate: zeroBalance.address});121 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);122123 const transferTx = () => token.transfer(zeroBalance, {Substrate: alice.address});124 await expect(transferTx()).to.be.rejectedWith('Inability to pay some fees');125 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);126127 expect(bobBalanceAfter === bobBalanceBefore).to.be.true;128 });129130 itSub('Fungible: Sponsoring is rate limited', async ({helper}) => {131 const collection = await helper.ft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL', limits: {132 sponsorTransferTimeout: 1000,133 }});134 await collection.setSponsor(alice, bob.address);135 await collection.confirmSponsorship(bob);136137 await collection.mint(alice, 100n, {Substrate: zeroBalance.address});138 await collection.transfer(zeroBalance, {Substrate: zeroBalance.address}, 1n);139 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);140141 const transferTx = () => collection.transfer(zeroBalance, {Substrate: zeroBalance.address});142 await expect(transferTx()).to.be.rejected;143 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);144145 expect(bobBalanceAfter === bobBalanceBefore).to.be.true;146 });147148 itSub.ifWithPallets('ReFungible: Sponsoring is rate limited', [Pallets.ReFungible], async ({helper}) => {149 const collection = await helper.rft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL', limits: {150 sponsorTransferTimeout: 1000,151 }});152 await collection.setSponsor(alice, bob.address);153 await collection.confirmSponsorship(bob);154155 const token = await collection.mintToken(alice, 100n, {Substrate: zeroBalance.address});156 await token.transfer(zeroBalance, {Substrate: alice.address});157158 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);159 const transferTx = () => token.transfer(zeroBalance, {Substrate: alice.address});160 await expect(transferTx()).to.be.rejectedWith('Inability to pay some fees');161 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);162163 expect(bobBalanceAfter === bobBalanceBefore).to.be.true;164 });165166 itSub('NFT: Sponsoring of createItem is rate limited', async ({helper}) => {167 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL', limits: {168 sponsoredDataRateLimit: {blocks: 1000},169 sponsorTransferTimeout: 1000,170 }});171 await collection.setSponsor(alice, bob.address);172 await collection.confirmSponsorship(bob);173 await collection.setPermissions(alice, {mintMode: true, access: 'AllowList'});174 await collection.addToAllowList(alice, {Substrate: zeroBalance.address});175176 await collection.mintToken(zeroBalance, {Substrate: zeroBalance.address});177178 const bobBalanceBefore = await helper.balance.getSubstrate(bob.address);179 const mintTx = () => collection.mintToken(zeroBalance, {Substrate: zeroBalance.address});180 await expect(mintTx()).to.be.rejectedWith('Inability to pay some fees');181 const bobBalanceAfter = await helper.balance.getSubstrate(bob.address);182183 expect(bobBalanceAfter === bobBalanceBefore).to.be.true;184 });185});186187describe('(!negative test!) integration test: ext. confirmSponsorship():', () => {188 let alice: IKeyringPair;189 let bob: IKeyringPair;190 let charlie: IKeyringPair;191 let ownerZeroBalance: IKeyringPair;192 let senderZeroBalance: IKeyringPair;193194 before(async () => {195 await usingPlaygrounds(async (helper, privateKey) => {196 const donor = await privateKey({url: import.meta.url});197 [alice, bob, charlie, ownerZeroBalance, senderZeroBalance] = await helper.arrange.createAccounts([100n, 100n, 100n, 0n, 0n], donor);198 });199 });200201 itSub('(!negative test!) Confirm sponsorship for a collection that never existed', async ({helper}) => {202 const collectionId = NON_EXISTENT_COLLECTION_ID;203 const confirmSponsorshipTx = () => helper.collection.confirmSponsorship(bob, collectionId);204 await expect(confirmSponsorshipTx()).to.be.rejectedWith(/common\.CollectionNotFound/);205 });206207 itSub('(!negative test!) Confirm sponsorship using a non-sponsor address', async ({helper}) => {208 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});209 await collection.setSponsor(alice, bob.address);210 const confirmSponsorshipTx = () => collection.confirmSponsorship(charlie);211 await expect(confirmSponsorshipTx()).to.be.rejectedWith(/common\.ConfirmSponsorshipFail/);212 });213214 itSub('(!negative test!) Confirm sponsorship using owner address', async ({helper}) => {215 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});216 await collection.setSponsor(alice, bob.address);217 const confirmSponsorshipTx = () => collection.confirmSponsorship(alice);218 await expect(confirmSponsorshipTx()).to.be.rejectedWith(/common\.ConfirmSponsorshipFail/);219 });220221 itSub('(!negative test!) Confirm sponsorship by collection admin', async ({helper}) => {222 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});223 await collection.setSponsor(alice, bob.address);224 await collection.addAdmin(alice, {Substrate: charlie.address});225 const confirmSponsorshipTx = () => collection.confirmSponsorship(charlie);226 await expect(confirmSponsorshipTx()).to.be.rejectedWith(/common\.ConfirmSponsorshipFail/);227 });228229 itSub('(!negative test!) Confirm sponsorship without sponsor being set with setCollectionSponsor', async ({helper}) => {230 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});231 const confirmSponsorshipTx = () => collection.confirmSponsorship(charlie);232 await expect(confirmSponsorshipTx()).to.be.rejectedWith(/common\.ConfirmSponsorshipFail/);233 });234235 itSub('(!negative test!) Confirm sponsorship in a collection that was destroyed', async ({helper}) => {236 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});237 await collection.burn(alice);238 const confirmSponsorshipTx = () => collection.confirmSponsorship(charlie);239 await expect(confirmSponsorshipTx()).to.be.rejectedWith(/common\.CollectionNotFound/);240 });241242 itSub('(!negative test!) Transfer fees are not paid by the sponsor if the transfer failed', async ({helper}) => {243 const collection = await helper.nft.mintCollection(alice, {name: 'col', description: 'descr', tokenPrefix: 'COL'});244 await collection.setSponsor(alice, bob.address);245 await collection.confirmSponsorship(bob);246 const token = await collection.mintToken(alice, {Substrate: ownerZeroBalance.address});247 const sponsorBalanceBefore = await helper.balance.getSubstrate(bob.address);248 const transferTx = () => token.transfer(senderZeroBalance, {Substrate: alice.address});249 await expect(transferTx()).to.be.rejectedWith('Inability to pay some fees');250 const sponsorBalanceAfter = await helper.balance.getSubstrate(bob.address);251 expect(sponsorBalanceAfter).to.equal(sponsorBalanceBefore);252 });253});