1234567891011121314151617import {IKeyringPair} from '@polkadot/types/types';18import usingApi from './substrate/substrate-api';19import {20 createCollectionExpectSuccess,21 destroyCollectionExpectSuccess,22 setCollectionLimitsExpectSuccess,23 setCollectionSponsorExpectSuccess,24 confirmSponsorshipExpectSuccess,25 createItemExpectSuccess,26 createItemExpectFailure,27 transferExpectSuccess,28 getFreeBalance,29 waitNewBlocks, burnItemExpectSuccess,30 requirePallets,31 Pallets32} from './util/helpers';33import {expect} from 'chai';3435describe('Number of tokens per address (NFT)', () => {36 let alice: IKeyringPair;3738 before(async () => {39 await usingApi(async (api, privateKeyWrapper) => {40 alice = privateKeyWrapper('//Alice');41 });42 });4344 it.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {4546 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});47 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 20});48 for(let i = 0; i < 10; i++){49 await createItemExpectSuccess(alice, collectionId, 'NFT');50 }51 await createItemExpectFailure(alice, collectionId, 'NFT');52 for(let i = 1; i < 11; i++) {53 await burnItemExpectSuccess(alice, collectionId, i);54 }55 await destroyCollectionExpectSuccess(collectionId);56 });5758 it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {5960 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});61 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 1});62 await createItemExpectSuccess(alice, collectionId, 'NFT');63 await createItemExpectFailure(alice, collectionId, 'NFT');64 await burnItemExpectSuccess(alice, collectionId, 1);65 await destroyCollectionExpectSuccess(collectionId);66 });67});6869describe('Number of tokens per address (ReFungible)', () => {70 let alice: IKeyringPair;7172 before(async function() {73 await requirePallets(this, [Pallets.ReFungible]);7475 await usingApi(async (api, privateKeyWrapper) => {76 alice = privateKeyWrapper('//Alice');77 });78 });7980 it.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {81 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});82 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 20});83 for(let i = 0; i < 10; i++){84 await createItemExpectSuccess(alice, collectionId, 'ReFungible');85 }86 await createItemExpectFailure(alice, collectionId, 'ReFungible');87 for(let i = 1; i < 11; i++) {88 await burnItemExpectSuccess(alice, collectionId, i, 100);89 }90 await destroyCollectionExpectSuccess(collectionId);91 });9293 it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {94 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});95 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 1});96 await createItemExpectSuccess(alice, collectionId, 'ReFungible');97 await createItemExpectFailure(alice, collectionId, 'ReFungible');98 await burnItemExpectSuccess(alice, collectionId, 1, 100);99 await destroyCollectionExpectSuccess(collectionId);100 });101});102103describe.skip('Sponsor timeout (NFT) (only for special chain limits test)', () => {104 let alice: IKeyringPair;105 let bob: IKeyringPair;106 let charlie: IKeyringPair;107108 before(async () => {109 await usingApi(async (api, privateKeyWrapper) => {110 alice = privateKeyWrapper('//Alice');111 bob = privateKeyWrapper('//Bob');112 charlie = privateKeyWrapper('//Charlie');113 });114 });115116 it.skip('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {117 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});118 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});119 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');120 await setCollectionSponsorExpectSuccess(collectionId, alice.address);121 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');122 await transferExpectSuccess(collectionId, tokenId, alice, bob);123 const aliceBalanceBefore = await getFreeBalance(alice);124125 126 await waitNewBlocks(5);127 await transferExpectSuccess(collectionId, tokenId, bob, charlie);128 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);129 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);130131 132 await waitNewBlocks(2); 133 await transferExpectSuccess(collectionId, tokenId, charlie, bob);134 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);135 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;136 137 await destroyCollectionExpectSuccess(collectionId);138 });139140 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {141142 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});143 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});144 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');145 await setCollectionSponsorExpectSuccess(collectionId, alice.address);146 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');147 await transferExpectSuccess(collectionId, tokenId, alice, bob);148 const aliceBalanceBefore = await getFreeBalance(alice);149150 151 await waitNewBlocks(1);152 await transferExpectSuccess(collectionId, tokenId, bob, charlie);153 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);154 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);155156 157 await waitNewBlocks(4);158 await transferExpectSuccess(collectionId, tokenId, charlie, bob);159 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);160 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;161 162 await destroyCollectionExpectSuccess(collectionId);163 });164});165166describe.skip('Sponsor timeout (Fungible) (only for special chain limits test)', () => {167 let alice: IKeyringPair;168 let bob: IKeyringPair;169 let charlie: IKeyringPair;170171 before(async () => {172 await usingApi(async (api, privateKeyWrapper) => {173 alice = privateKeyWrapper('//Alice');174 bob = privateKeyWrapper('//Bob');175 charlie = privateKeyWrapper('//Charlie');176 });177 });178179 it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {180 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});181 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});182 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');183 await setCollectionSponsorExpectSuccess(collectionId, alice.address);184 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');185 await transferExpectSuccess(collectionId, tokenId, alice, bob, 10, 'Fungible');186 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');187 const aliceBalanceBefore = await getFreeBalance(alice);188189 190 await waitNewBlocks(5);191 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');192 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);193 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);194195 196 await waitNewBlocks(2); 197 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');198 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);199 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;200 201202 await destroyCollectionExpectSuccess(collectionId);203 });204205 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {206207 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});208 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});209 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');210 await setCollectionSponsorExpectSuccess(collectionId, alice.address);211 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');212 await transferExpectSuccess(collectionId, tokenId, alice, bob, 10, 'Fungible');213 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');214 const aliceBalanceBefore = await getFreeBalance(alice);215216 217 await waitNewBlocks(1);218 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');219 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);220 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);221222 223 await waitNewBlocks(4);224 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');225 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);226 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;227 228229 await destroyCollectionExpectSuccess(collectionId);230 });231});232233describe.skip('Sponsor timeout (ReFungible) (only for special chain limits test)', () => {234 let alice: IKeyringPair;235 let bob: IKeyringPair;236 let charlie: IKeyringPair;237238 before(async () => {239 await usingApi(async (api, privateKeyWrapper) => {240 alice = privateKeyWrapper('//Alice');241 bob = privateKeyWrapper('//Bob');242 charlie = privateKeyWrapper('//Charlie');243 });244 });245246 it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {247 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});248 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});249 const tokenId = await createItemExpectSuccess(alice, collectionId, 'ReFungible');250 await setCollectionSponsorExpectSuccess(collectionId, alice.address);251 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');252 await transferExpectSuccess(collectionId, tokenId, alice, bob, 100, 'ReFungible');253 const aliceBalanceBefore = await getFreeBalance(alice);254255 256 await waitNewBlocks(5);257 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');258 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);259 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);260261 262 await waitNewBlocks(2); 263 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');264 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);265 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;266 267 await destroyCollectionExpectSuccess(collectionId);268 });269270 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {271272 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});273 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});274 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');275 await setCollectionSponsorExpectSuccess(collectionId, alice.address);276 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');277 await transferExpectSuccess(collectionId, tokenId, alice, bob);278 const aliceBalanceBefore = await getFreeBalance(alice);279280 281 await waitNewBlocks(1);282 await transferExpectSuccess(collectionId, tokenId, bob, charlie);283 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);284 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);285286 287 await waitNewBlocks(4);288 await transferExpectSuccess(collectionId, tokenId, charlie, bob);289 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);290 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;291 292 await destroyCollectionExpectSuccess(collectionId);293 });294});295296describe('Collection zero limits (NFT)', () => {297 let alice: IKeyringPair;298 let bob: IKeyringPair;299 let charlie: IKeyringPair;300301 before(async () => {302 await usingApi(async (api, privateKeyWrapper) => {303 alice = privateKeyWrapper('//Alice');304 bob = privateKeyWrapper('//Bob');305 charlie = privateKeyWrapper('//Charlie');306 });307 });308309 it.skip('Limits have 0 in tokens per address field, the chain limits are applied', async () => {310 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});311 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 0});312 for(let i = 0; i < 10; i++){313 await createItemExpectSuccess(alice, collectionId, 'NFT');314 }315 await createItemExpectFailure(alice, collectionId, 'NFT');316 });317318 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {319320 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});321 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});322 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');323 await setCollectionSponsorExpectSuccess(collectionId, alice.address);324 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');325 await transferExpectSuccess(collectionId, tokenId, alice, bob);326 const aliceBalanceBefore = await getFreeBalance(alice);327328 329 await waitNewBlocks(1);330 await transferExpectSuccess(collectionId, tokenId, bob, charlie);331 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);332 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;333 334 });335});336337describe('Collection zero limits (Fungible)', () => {338 let alice: IKeyringPair;339 let bob: IKeyringPair;340 let charlie: IKeyringPair;341342 before(async () => {343 await usingApi(async (api, privateKeyWrapper) => {344 alice = privateKeyWrapper('//Alice');345 bob = privateKeyWrapper('//Bob');346 charlie = privateKeyWrapper('//Charlie');347 });348 });349350 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {351 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});352 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});353 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');354 await setCollectionSponsorExpectSuccess(collectionId, alice.address);355 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');356 await transferExpectSuccess(collectionId, tokenId, alice, bob, 10, 'Fungible');357 const aliceBalanceBefore = await getFreeBalance(alice);358 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');359360 361 await waitNewBlocks(1);362 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');363 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);364 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;365 366 });367});368369describe('Collection zero limits (ReFungible)', () => {370 let alice: IKeyringPair;371 let bob: IKeyringPair;372 let charlie: IKeyringPair;373374 before(async function() {375 await requirePallets(this, [Pallets.ReFungible]);376377 await usingApi(async (api, privateKeyWrapper) => {378 alice = privateKeyWrapper('//Alice');379 bob = privateKeyWrapper('//Bob');380 charlie = privateKeyWrapper('//Charlie');381 });382 });383384 it.skip('Limits have 0 in tokens per address field, the chain limits are applied', async () => {385 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});386 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 0});387 for(let i = 0; i < 10; i++){388 await createItemExpectSuccess(alice, collectionId, 'ReFungible');389 }390 await createItemExpectFailure(alice, collectionId, 'ReFungible');391 });392393 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {394395 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});396 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});397 const tokenId = await createItemExpectSuccess(alice, collectionId, 'ReFungible');398 await setCollectionSponsorExpectSuccess(collectionId, alice.address);399 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');400 await transferExpectSuccess(collectionId, tokenId, alice, bob, 100, 'ReFungible');401 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');402 const aliceBalanceBefore = await getFreeBalance(alice);403404 405 await waitNewBlocks(1);406 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');407 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);408 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;409 410 });411 412 it('Effective collection limits', async () => {413 await usingApi(async (api) => {414 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});415 await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});416 417 { 418 const collection = await api.rpc.unique.collectionById(collectionId);419 expect(collection.isSome).to.be.true;420 const limits = collection.unwrap().limits;421 expect(limits).to.be.any;422 423 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.null;424 expect(limits.sponsoredDataSize.toHuman()).to.be.null;425 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.null;426 expect(limits.tokenLimit.toHuman()).to.be.null;427 expect(limits.sponsorTransferTimeout.toHuman()).to.be.null;428 expect(limits.sponsorApproveTimeout.toHuman()).to.be.null;429 expect(limits.ownerCanTransfer.toHuman()).to.be.true;430 expect(limits.ownerCanDestroy.toHuman()).to.be.null;431 expect(limits.transfersEnabled.toHuman()).to.be.null;432 }433 434 { 435 const limits = await api.rpc.unique.effectiveCollectionLimits(11111);436 expect(limits.toHuman()).to.be.null;437 }438 439 { 440 const limitsOpt = await api.rpc.unique.effectiveCollectionLimits(collectionId);441 expect(limitsOpt.isNone).to.be.false;442 const limits = limitsOpt.unwrap();443 444 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.eq('100,000');445 expect(limits.sponsoredDataSize.toHuman()).to.be.eq('2,048');446 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.eq('SponsoringDisabled');447 expect(limits.tokenLimit.toHuman()).to.be.eq('4,294,967,295');448 expect(limits.sponsorTransferTimeout.toHuman()).to.be.eq('5');449 expect(limits.sponsorApproveTimeout.toHuman()).to.be.eq('5');450 expect(limits.ownerCanTransfer.toHuman()).to.be.true;451 expect(limits.ownerCanDestroy.toHuman()).to.be.true;452 expect(limits.transfersEnabled.toHuman()).to.be.true;453 }454455 { 456 await setCollectionLimitsExpectSuccess(alice, collectionId, {457 accountTokenOwnershipLimit: 99_999,458 sponsoredDataSize: 1024,459 tokenLimit: 123,460 transfersEnabled: false,461 });462463 const limitsOpt = await api.rpc.unique.effectiveCollectionLimits(collectionId);464 expect(limitsOpt.isNone).to.be.false;465 const limits = limitsOpt.unwrap();466 467 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.eq('99,999');468 expect(limits.sponsoredDataSize.toHuman()).to.be.eq('1,024');469 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.eq('SponsoringDisabled');470 expect(limits.tokenLimit.toHuman()).to.be.eq('123');471 expect(limits.sponsorTransferTimeout.toHuman()).to.be.eq('5');472 expect(limits.sponsorApproveTimeout.toHuman()).to.be.eq('5');473 expect(limits.ownerCanTransfer.toHuman()).to.be.true;474 expect(limits.ownerCanDestroy.toHuman()).to.be.true;475 expect(limits.transfersEnabled.toHuman()).to.be.false;476 }477 });478 });479});480481