1234567891011121314151617import {IKeyringPair} from '@polkadot/types/types';18import privateKey from './substrate/privateKey';19import usingApi from './substrate/substrate-api';20import {21 createCollectionExpectSuccess,22 destroyCollectionExpectSuccess,23 setCollectionLimitsExpectSuccess,24 setCollectionSponsorExpectSuccess,25 confirmSponsorshipExpectSuccess,26 createItemExpectSuccess,27 createItemExpectFailure,28 transferExpectSuccess,29 getFreeBalance,30 waitNewBlocks, burnItemExpectSuccess,31} from './util/helpers';32import {expect} from 'chai';3334describe('Number of tokens per address (NFT)', () => {35 let alice: IKeyringPair;3637 before(async () => {38 await usingApi(async () => {39 alice = privateKey('//Alice');40 });41 });4243 it.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {4445 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});46 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 20});47 for(let i = 0; i < 10; i++){48 await createItemExpectSuccess(alice, collectionId, 'NFT');49 }50 await createItemExpectFailure(alice, collectionId, 'NFT');51 for(let i = 1; i < 11; i++) {52 await burnItemExpectSuccess(alice, collectionId, i);53 }54 await destroyCollectionExpectSuccess(collectionId);55 });5657 it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {5859 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});60 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 1});61 await createItemExpectSuccess(alice, collectionId, 'NFT');62 await createItemExpectFailure(alice, collectionId, 'NFT');63 await burnItemExpectSuccess(alice, collectionId, 1);64 await destroyCollectionExpectSuccess(collectionId);65 });66});6768describe('Number of tokens per address (ReFungible)', () => {69 let alice: IKeyringPair;7071 before(async () => {72 await usingApi(async () => {73 alice = privateKey('//Alice');74 });75 });7677 it.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {78 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});79 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 20});80 for(let i = 0; i < 10; i++){81 await createItemExpectSuccess(alice, collectionId, 'ReFungible');82 }83 await createItemExpectFailure(alice, collectionId, 'ReFungible');84 for(let i = 1; i < 11; i++) {85 await burnItemExpectSuccess(alice, collectionId, i, 100);86 }87 await destroyCollectionExpectSuccess(collectionId);88 });8990 it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {91 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});92 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 1});93 await createItemExpectSuccess(alice, collectionId, 'ReFungible');94 await createItemExpectFailure(alice, collectionId, 'ReFungible');95 await burnItemExpectSuccess(alice, collectionId, 1, 100);96 await destroyCollectionExpectSuccess(collectionId);97 });98});99100describe.skip('Sponsor timeout (NFT) (only for special chain limits test)', () => {101 let alice: IKeyringPair;102 let bob: IKeyringPair;103 let charlie: IKeyringPair;104105 before(async () => {106 await usingApi(async () => {107 alice = privateKey('//Alice');108 bob = privateKey('//Bob');109 charlie = privateKey('//Charlie');110 });111 });112113 it.skip('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {114 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});115 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});116 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');117 await setCollectionSponsorExpectSuccess(collectionId, alice.address);118 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');119 await transferExpectSuccess(collectionId, tokenId, alice, bob);120 const aliceBalanceBefore = await getFreeBalance(alice);121122 123 await waitNewBlocks(5);124 await transferExpectSuccess(collectionId, tokenId, bob, charlie);125 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);126 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);127128 129 await waitNewBlocks(2); 130 await transferExpectSuccess(collectionId, tokenId, charlie, bob);131 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);132 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;133 134 await destroyCollectionExpectSuccess(collectionId);135 });136137 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {138139 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});140 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});141 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');142 await setCollectionSponsorExpectSuccess(collectionId, alice.address);143 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');144 await transferExpectSuccess(collectionId, tokenId, alice, bob);145 const aliceBalanceBefore = await getFreeBalance(alice);146147 148 await waitNewBlocks(1);149 await transferExpectSuccess(collectionId, tokenId, bob, charlie);150 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);151 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);152153 154 await waitNewBlocks(4);155 await transferExpectSuccess(collectionId, tokenId, charlie, bob);156 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);157 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;158 159 await destroyCollectionExpectSuccess(collectionId);160 });161});162163describe.skip('Sponsor timeout (Fungible) (only for special chain limits test)', () => {164 let alice: IKeyringPair;165 let bob: IKeyringPair;166 let charlie: IKeyringPair;167168 before(async () => {169 await usingApi(async () => {170 alice = privateKey('//Alice');171 bob = privateKey('//Bob');172 charlie = privateKey('//Charlie');173 });174 });175176 it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {177 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});178 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});179 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');180 await setCollectionSponsorExpectSuccess(collectionId, alice.address);181 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');182 await transferExpectSuccess(collectionId, tokenId, alice, bob, 10, 'Fungible');183 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');184 const aliceBalanceBefore = await getFreeBalance(alice);185186 187 await waitNewBlocks(5);188 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');189 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);190 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);191192 193 await waitNewBlocks(2); 194 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');195 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);196 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;197 198199 await destroyCollectionExpectSuccess(collectionId);200 });201202 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {203204 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});205 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});206 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');207 await setCollectionSponsorExpectSuccess(collectionId, alice.address);208 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');209 await transferExpectSuccess(collectionId, tokenId, alice, bob, 10, 'Fungible');210 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');211 const aliceBalanceBefore = await getFreeBalance(alice);212213 214 await waitNewBlocks(1);215 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');216 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);217 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);218219 220 await waitNewBlocks(4);221 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');222 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);223 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;224 225226 await destroyCollectionExpectSuccess(collectionId);227 });228});229230describe.skip('Sponsor timeout (ReFungible) (only for special chain limits test)', () => {231 let alice: IKeyringPair;232 let bob: IKeyringPair;233 let charlie: IKeyringPair;234235 before(async () => {236 await usingApi(async () => {237 alice = privateKey('//Alice');238 bob = privateKey('//Bob');239 charlie = privateKey('//Charlie');240 });241 });242243 it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {244 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});245 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});246 const tokenId = await createItemExpectSuccess(alice, collectionId, 'ReFungible');247 await setCollectionSponsorExpectSuccess(collectionId, alice.address);248 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');249 await transferExpectSuccess(collectionId, tokenId, alice, bob, 100, 'ReFungible');250 const aliceBalanceBefore = await getFreeBalance(alice);251252 253 await waitNewBlocks(5);254 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');255 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);256 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);257258 259 await waitNewBlocks(2); 260 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');261 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);262 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;263 264 await destroyCollectionExpectSuccess(collectionId);265 });266267 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {268269 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});270 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});271 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');272 await setCollectionSponsorExpectSuccess(collectionId, alice.address);273 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');274 await transferExpectSuccess(collectionId, tokenId, alice, bob);275 const aliceBalanceBefore = await getFreeBalance(alice);276277 278 await waitNewBlocks(1);279 await transferExpectSuccess(collectionId, tokenId, bob, charlie);280 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);281 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);282283 284 await waitNewBlocks(4);285 await transferExpectSuccess(collectionId, tokenId, charlie, bob);286 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);287 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;288 289 await destroyCollectionExpectSuccess(collectionId);290 });291});292293describe('Collection zero limits (NFT)', () => {294 let alice: IKeyringPair;295 let bob: IKeyringPair;296 let charlie: IKeyringPair;297298 before(async () => {299 await usingApi(async () => {300 alice = privateKey('//Alice');301 bob = privateKey('//Bob');302 charlie = privateKey('//Charlie');303 });304 });305306 it.skip('Limits have 0 in tokens per address field, the chain limits are applied', async () => {307 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});308 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 0});309 for(let i = 0; i < 10; i++){310 await createItemExpectSuccess(alice, collectionId, 'NFT');311 }312 await createItemExpectFailure(alice, collectionId, 'NFT');313 });314315 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {316317 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});318 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});319 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');320 await setCollectionSponsorExpectSuccess(collectionId, alice.address);321 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');322 await transferExpectSuccess(collectionId, tokenId, alice, bob);323 const aliceBalanceBefore = await getFreeBalance(alice);324325 326 await waitNewBlocks(1);327 await transferExpectSuccess(collectionId, tokenId, bob, charlie);328 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);329 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;330 331 });332});333334describe('Collection zero limits (Fungible)', () => {335 let alice: IKeyringPair;336 let bob: IKeyringPair;337 let charlie: IKeyringPair;338339 before(async () => {340 await usingApi(async () => {341 alice = privateKey('//Alice');342 bob = privateKey('//Bob');343 charlie = privateKey('//Charlie');344 });345 });346347 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {348 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});349 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});350 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');351 await setCollectionSponsorExpectSuccess(collectionId, alice.address);352 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');353 await transferExpectSuccess(collectionId, tokenId, alice, bob, 10, 'Fungible');354 const aliceBalanceBefore = await getFreeBalance(alice);355 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');356357 358 await waitNewBlocks(1);359 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');360 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);361 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;362 363 });364});365366describe('Collection zero limits (ReFungible)', () => {367 let alice: IKeyringPair;368 let bob: IKeyringPair;369 let charlie: IKeyringPair;370371 before(async () => {372 await usingApi(async () => {373 alice = privateKey('//Alice');374 bob = privateKey('//Bob');375 charlie = privateKey('//Charlie');376 });377 });378379 it.skip('Limits have 0 in tokens per address field, the chain limits are applied', async () => {380 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});381 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 0});382 for(let i = 0; i < 10; i++){383 await createItemExpectSuccess(alice, collectionId, 'ReFungible');384 }385 await createItemExpectFailure(alice, collectionId, 'ReFungible');386 });387388 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {389390 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});391 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});392 const tokenId = await createItemExpectSuccess(alice, collectionId, 'ReFungible');393 await setCollectionSponsorExpectSuccess(collectionId, alice.address);394 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');395 await transferExpectSuccess(collectionId, tokenId, alice, bob, 100, 'ReFungible');396 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');397 const aliceBalanceBefore = await getFreeBalance(alice);398399 400 await waitNewBlocks(1);401 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');402 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);403 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;404 405 });406 407 it('Effective collection limits', async () => {408 await usingApi(async (api) => {409 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});410 411 { 412 const collection = await api.rpc.unique.collectionById(collectionId);413 expect(collection.isSome).to.be.true;414 const limits = collection.unwrap().limits;415 expect(limits).to.be.any;416 417 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.null;418 expect(limits.sponsoredDataSize.toHuman()).to.be.null;419 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.null;420 expect(limits.tokenLimit.toHuman()).to.be.null;421 expect(limits.sponsorTransferTimeout.toHuman()).to.be.null;422 expect(limits.sponsorApproveTimeout.toHuman()).to.be.null;423 expect(limits.ownerCanTransfer.toHuman()).to.be.null;424 expect(limits.ownerCanDestroy.toHuman()).to.be.null;425 expect(limits.transfersEnabled.toHuman()).to.be.null;426 }427 428 { 429 const limits = await api.rpc.unique.effectiveCollectionLimits(11111);430 expect(limits.toHuman()).to.be.null;431 }432 433 { 434 const limitsOpt = await api.rpc.unique.effectiveCollectionLimits(collectionId);435 expect(limitsOpt.isNone).to.be.false;436 const limits = limitsOpt.unwrap();437 438 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.eq('100,000');439 expect(limits.sponsoredDataSize.toHuman()).to.be.eq('2,048');440 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.eq('SponsoringDisabled');441 expect(limits.tokenLimit.toHuman()).to.be.eq('4,294,967,295');442 expect(limits.sponsorTransferTimeout.toHuman()).to.be.eq('5');443 expect(limits.sponsorApproveTimeout.toHuman()).to.be.eq('5');444 expect(limits.ownerCanTransfer.toHuman()).to.be.true;445 expect(limits.ownerCanDestroy.toHuman()).to.be.true;446 expect(limits.transfersEnabled.toHuman()).to.be.true;447 }448449 { 450 await setCollectionLimitsExpectSuccess(alice, collectionId, {451 accountTokenOwnershipLimit: 99_999,452 sponsoredDataSize: 1024,453 tokenLimit: 123,454 transfersEnabled: false,455 });456457 const limitsOpt = await api.rpc.unique.effectiveCollectionLimits(collectionId);458 expect(limitsOpt.isNone).to.be.false;459 const limits = limitsOpt.unwrap();460 461 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.eq('99,999');462 expect(limits.sponsoredDataSize.toHuman()).to.be.eq('1,024');463 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.eq('SponsoringDisabled');464 expect(limits.tokenLimit.toHuman()).to.be.eq('123');465 expect(limits.sponsorTransferTimeout.toHuman()).to.be.eq('5');466 expect(limits.sponsorApproveTimeout.toHuman()).to.be.eq('5');467 expect(limits.ownerCanTransfer.toHuman()).to.be.true;468 expect(limits.ownerCanDestroy.toHuman()).to.be.true;469 expect(limits.transfersEnabled.toHuman()).to.be.false;470 }471 });472 });473});474475