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} from './util/helpers';31import {expect} from 'chai';3233describe('Number of tokens per address (NFT)', () => {34 let alice: IKeyringPair;3536 before(async () => {37 await usingApi(async (api, privateKeyWrapper) => {38 alice = privateKeyWrapper('//Alice');39 });40 });4142 it.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {4344 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});45 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 20});46 for(let i = 0; i < 10; i++){47 await createItemExpectSuccess(alice, collectionId, 'NFT');48 }49 await createItemExpectFailure(alice, collectionId, 'NFT');50 for(let i = 1; i < 11; i++) {51 await burnItemExpectSuccess(alice, collectionId, i);52 }53 await destroyCollectionExpectSuccess(collectionId);54 });5556 it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {5758 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});59 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 1});60 await createItemExpectSuccess(alice, collectionId, 'NFT');61 await createItemExpectFailure(alice, collectionId, 'NFT');62 await burnItemExpectSuccess(alice, collectionId, 1);63 await destroyCollectionExpectSuccess(collectionId);64 });65});6667describe('Number of tokens per address (ReFungible)', () => {68 let alice: IKeyringPair;6970 before(async () => {71 await usingApi(async (api, privateKeyWrapper) => {72 alice = privateKeyWrapper('//Alice');73 });74 });7576 it.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {77 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});78 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 20});79 for(let i = 0; i < 10; i++){80 await createItemExpectSuccess(alice, collectionId, 'ReFungible');81 }82 await createItemExpectFailure(alice, collectionId, 'ReFungible');83 for(let i = 1; i < 11; i++) {84 await burnItemExpectSuccess(alice, collectionId, i, 100);85 }86 await destroyCollectionExpectSuccess(collectionId);87 });8889 it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {90 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});91 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 1});92 await createItemExpectSuccess(alice, collectionId, 'ReFungible');93 await createItemExpectFailure(alice, collectionId, 'ReFungible');94 await burnItemExpectSuccess(alice, collectionId, 1, 100);95 await destroyCollectionExpectSuccess(collectionId);96 });97});9899describe.skip('Sponsor timeout (NFT) (only for special chain limits test)', () => {100 let alice: IKeyringPair;101 let bob: IKeyringPair;102 let charlie: IKeyringPair;103104 before(async () => {105 await usingApi(async (api, privateKeyWrapper) => {106 alice = privateKeyWrapper('//Alice');107 bob = privateKeyWrapper('//Bob');108 charlie = privateKeyWrapper('//Charlie');109 });110 });111112 it.skip('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {113 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});114 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});115 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');116 await setCollectionSponsorExpectSuccess(collectionId, alice.address);117 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');118 await transferExpectSuccess(collectionId, tokenId, alice, bob);119 const aliceBalanceBefore = await getFreeBalance(alice);120121 122 await waitNewBlocks(5);123 await transferExpectSuccess(collectionId, tokenId, bob, charlie);124 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);125 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);126127 128 await waitNewBlocks(2); 129 await transferExpectSuccess(collectionId, tokenId, charlie, bob);130 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);131 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;132 133 await destroyCollectionExpectSuccess(collectionId);134 });135136 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {137138 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});139 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});140 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');141 await setCollectionSponsorExpectSuccess(collectionId, alice.address);142 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');143 await transferExpectSuccess(collectionId, tokenId, alice, bob);144 const aliceBalanceBefore = await getFreeBalance(alice);145146 147 await waitNewBlocks(1);148 await transferExpectSuccess(collectionId, tokenId, bob, charlie);149 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);150 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);151152 153 await waitNewBlocks(4);154 await transferExpectSuccess(collectionId, tokenId, charlie, bob);155 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);156 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;157 158 await destroyCollectionExpectSuccess(collectionId);159 });160});161162describe.skip('Sponsor timeout (Fungible) (only for special chain limits test)', () => {163 let alice: IKeyringPair;164 let bob: IKeyringPair;165 let charlie: IKeyringPair;166167 before(async () => {168 await usingApi(async (api, privateKeyWrapper) => {169 alice = privateKeyWrapper('//Alice');170 bob = privateKeyWrapper('//Bob');171 charlie = privateKeyWrapper('//Charlie');172 });173 });174175 it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {176 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});177 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});178 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');179 await setCollectionSponsorExpectSuccess(collectionId, alice.address);180 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');181 await transferExpectSuccess(collectionId, tokenId, alice, bob, 10, 'Fungible');182 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');183 const aliceBalanceBefore = await getFreeBalance(alice);184185 186 await waitNewBlocks(5);187 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');188 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);189 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);190191 192 await waitNewBlocks(2); 193 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');194 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);195 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;196 197198 await destroyCollectionExpectSuccess(collectionId);199 });200201 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {202203 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});204 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});205 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');206 await setCollectionSponsorExpectSuccess(collectionId, alice.address);207 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');208 await transferExpectSuccess(collectionId, tokenId, alice, bob, 10, 'Fungible');209 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');210 const aliceBalanceBefore = await getFreeBalance(alice);211212 213 await waitNewBlocks(1);214 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');215 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);216 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);217218 219 await waitNewBlocks(4);220 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');221 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);222 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;223 224225 await destroyCollectionExpectSuccess(collectionId);226 });227});228229describe.skip('Sponsor timeout (ReFungible) (only for special chain limits test)', () => {230 let alice: IKeyringPair;231 let bob: IKeyringPair;232 let charlie: IKeyringPair;233234 before(async () => {235 await usingApi(async (api, privateKeyWrapper) => {236 alice = privateKeyWrapper('//Alice');237 bob = privateKeyWrapper('//Bob');238 charlie = privateKeyWrapper('//Charlie');239 });240 });241242 it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {243 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});244 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});245 const tokenId = await createItemExpectSuccess(alice, collectionId, 'ReFungible');246 await setCollectionSponsorExpectSuccess(collectionId, alice.address);247 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');248 await transferExpectSuccess(collectionId, tokenId, alice, bob, 100, 'ReFungible');249 const aliceBalanceBefore = await getFreeBalance(alice);250251 252 await waitNewBlocks(5);253 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');254 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);255 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);256257 258 await waitNewBlocks(2); 259 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');260 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);261 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;262 263 await destroyCollectionExpectSuccess(collectionId);264 });265266 it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {267268 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});269 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});270 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');271 await setCollectionSponsorExpectSuccess(collectionId, alice.address);272 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');273 await transferExpectSuccess(collectionId, tokenId, alice, bob);274 const aliceBalanceBefore = await getFreeBalance(alice);275276 277 await waitNewBlocks(1);278 await transferExpectSuccess(collectionId, tokenId, bob, charlie);279 const aliceBalanceAfterUnsponsoredTransaction = await getFreeBalance(alice);280 expect(aliceBalanceAfterUnsponsoredTransaction).to.be.equals(aliceBalanceBefore);281282 283 await waitNewBlocks(4);284 await transferExpectSuccess(collectionId, tokenId, charlie, bob);285 const aliceBalanceAfterSponsoredTransaction = await getFreeBalance(alice);286 expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;287 288 await destroyCollectionExpectSuccess(collectionId);289 });290});291292describe('Collection zero limits (NFT)', () => {293 let alice: IKeyringPair;294 let bob: IKeyringPair;295 let charlie: IKeyringPair;296297 before(async () => {298 await usingApi(async (api, privateKeyWrapper) => {299 alice = privateKeyWrapper('//Alice');300 bob = privateKeyWrapper('//Bob');301 charlie = privateKeyWrapper('//Charlie');302 });303 });304305 it.skip('Limits have 0 in tokens per address field, the chain limits are applied', async () => {306 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});307 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 0});308 for(let i = 0; i < 10; i++){309 await createItemExpectSuccess(alice, collectionId, 'NFT');310 }311 await createItemExpectFailure(alice, collectionId, 'NFT');312 });313314 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {315316 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});317 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});318 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');319 await setCollectionSponsorExpectSuccess(collectionId, alice.address);320 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');321 await transferExpectSuccess(collectionId, tokenId, alice, bob);322 const aliceBalanceBefore = await getFreeBalance(alice);323324 325 await waitNewBlocks(1);326 await transferExpectSuccess(collectionId, tokenId, bob, charlie);327 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);328 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;329 330 });331});332333describe('Collection zero limits (Fungible)', () => {334 let alice: IKeyringPair;335 let bob: IKeyringPair;336 let charlie: IKeyringPair;337338 before(async () => {339 await usingApi(async (api, privateKeyWrapper) => {340 alice = privateKeyWrapper('//Alice');341 bob = privateKeyWrapper('//Bob');342 charlie = privateKeyWrapper('//Charlie');343 });344 });345346 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {347 const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});348 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});349 const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');350 await setCollectionSponsorExpectSuccess(collectionId, alice.address);351 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');352 await transferExpectSuccess(collectionId, tokenId, alice, bob, 10, 'Fungible');353 const aliceBalanceBefore = await getFreeBalance(alice);354 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');355356 357 await waitNewBlocks(1);358 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');359 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);360 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;361 362 });363});364365describe('Collection zero limits (ReFungible)', () => {366 let alice: IKeyringPair;367 let bob: IKeyringPair;368 let charlie: IKeyringPair;369370 before(async () => {371 await usingApi(async (api, privateKeyWrapper) => {372 alice = privateKeyWrapper('//Alice');373 bob = privateKeyWrapper('//Bob');374 charlie = privateKeyWrapper('//Charlie');375 });376 });377378 it.skip('Limits have 0 in tokens per address field, the chain limits are applied', async () => {379 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});380 await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 0});381 for(let i = 0; i < 10; i++){382 await createItemExpectSuccess(alice, collectionId, 'ReFungible');383 }384 await createItemExpectFailure(alice, collectionId, 'ReFungible');385 });386387 it('Limits have 0 in sponsor timeout, no limits are applied', async () => {388389 const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});390 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});391 const tokenId = await createItemExpectSuccess(alice, collectionId, 'ReFungible');392 await setCollectionSponsorExpectSuccess(collectionId, alice.address);393 await confirmSponsorshipExpectSuccess(collectionId, '//Alice');394 await transferExpectSuccess(collectionId, tokenId, alice, bob, 100, 'ReFungible');395 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');396 const aliceBalanceBefore = await getFreeBalance(alice);397398 399 await waitNewBlocks(1);400 await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');401 const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);402 expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;403 404 });405 406 it('Effective collection limits', async () => {407 await usingApi(async (api) => {408 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});409 410 { 411 const collection = await api.rpc.unique.collectionById(collectionId);412 expect(collection.isSome).to.be.true;413 const limits = collection.unwrap().limits;414 expect(limits).to.be.any;415 416 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.null;417 expect(limits.sponsoredDataSize.toHuman()).to.be.null;418 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.null;419 expect(limits.tokenLimit.toHuman()).to.be.null;420 expect(limits.sponsorTransferTimeout.toHuman()).to.be.null;421 expect(limits.sponsorApproveTimeout.toHuman()).to.be.null;422 expect(limits.ownerCanTransfer.toHuman()).to.be.null;423 expect(limits.ownerCanDestroy.toHuman()).to.be.null;424 expect(limits.transfersEnabled.toHuman()).to.be.null;425 }426 427 { 428 const limits = await api.rpc.unique.effectiveCollectionLimits(11111);429 expect(limits.toHuman()).to.be.null;430 }431 432 { 433 const limitsOpt = await api.rpc.unique.effectiveCollectionLimits(collectionId);434 expect(limitsOpt.isNone).to.be.false;435 const limits = limitsOpt.unwrap();436 437 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.eq('100,000');438 expect(limits.sponsoredDataSize.toHuman()).to.be.eq('2,048');439 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.eq('SponsoringDisabled');440 expect(limits.tokenLimit.toHuman()).to.be.eq('4,294,967,295');441 expect(limits.sponsorTransferTimeout.toHuman()).to.be.eq('5');442 expect(limits.sponsorApproveTimeout.toHuman()).to.be.eq('5');443 expect(limits.ownerCanTransfer.toHuman()).to.be.true;444 expect(limits.ownerCanDestroy.toHuman()).to.be.true;445 expect(limits.transfersEnabled.toHuman()).to.be.true;446 }447448 { 449 await setCollectionLimitsExpectSuccess(alice, collectionId, {450 accountTokenOwnershipLimit: 99_999,451 sponsoredDataSize: 1024,452 tokenLimit: 123,453 transfersEnabled: false,454 });455456 const limitsOpt = await api.rpc.unique.effectiveCollectionLimits(collectionId);457 expect(limitsOpt.isNone).to.be.false;458 const limits = limitsOpt.unwrap();459 460 expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.eq('99,999');461 expect(limits.sponsoredDataSize.toHuman()).to.be.eq('1,024');462 expect(limits.sponsoredDataRateLimit.toHuman()).to.be.eq('SponsoringDisabled');463 expect(limits.tokenLimit.toHuman()).to.be.eq('123');464 expect(limits.sponsorTransferTimeout.toHuman()).to.be.eq('5');465 expect(limits.sponsorApproveTimeout.toHuman()).to.be.eq('5');466 expect(limits.ownerCanTransfer.toHuman()).to.be.true;467 expect(limits.ownerCanDestroy.toHuman()).to.be.true;468 expect(limits.transfersEnabled.toHuman()).to.be.false;469 }470 });471 });472});473474