1234567891011121314151617import type {IKeyringPair} from '@polkadot/types/types';18import {expect, itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds} from '@unique/test-utils/util.js';1920describe('Refungible nesting', () => {21 let alice: IKeyringPair;22 let charlie: IKeyringPair;2324 before(async function() {25 await usingPlaygrounds(async (helper, privateKey) => {26 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);27 const donor = await privateKey({url: import.meta.url});28 [alice, charlie] = await helper.arrange.createAccounts([50n, 10n], donor);29 });30 });3132 [33 {restrictedMode: true},34 {restrictedMode: false},35 ].map(testCase => {36 itSub(`Owner can nest their token${testCase.restrictedMode ? ': Restricted mode' : ''}`, async ({helper}) => {37 const collectionNFT = await helper.nft.mintCollection(alice, {permissions: {access: 'AllowList', mintMode: true, nesting: {tokenOwner: true}}});38 const collectionRFT = await helper.rft.mintCollection(alice);39 const targetToken = await collectionNFT.mintToken(alice, {Substrate: charlie.address});4041 await collectionNFT.setPermissions(alice, {access: 'AllowList', mintMode: true, nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionRFT.collectionId] : null}});42 await collectionNFT.addToAllowList(alice, {Substrate: charlie.address});43 await collectionNFT.addToAllowList(alice, targetToken.nestingAccount());4445 await collectionRFT.setPermissions(alice, {access: 'AllowList', mintMode: true});46 await collectionRFT.addToAllowList(alice, {Substrate: charlie.address});47 await collectionRFT.addToAllowList(alice, targetToken.nestingAccount());4849 50 const nestedToken = await collectionRFT.mintToken(charlie, 5n, targetToken.nestingAccount());51 expect(await nestedToken.getBalance(targetToken.nestingAccount())).to.be.equal(5n);5253 54 const newToken = await collectionRFT.mintToken(charlie, 5n);55 await newToken.transfer(charlie, targetToken.nestingAccount(), 2n);56 expect(await newToken.getBalance(targetToken.nestingAccount())).to.be.equal(2n);57 expect(await newToken.getBalance({Substrate: charlie.address})).to.be.equal(3n);58 });59 });6061 itSub('Owner can unnest nested token', async ({helper}) => {62 const collection = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});63 const targetToken = await collection.mintToken(alice);6465 66 const collectionRFT = await helper.rft.mintCollection(alice);67 const token = await collectionRFT.mintToken(alice, 10n, targetToken.nestingAccount());6869 70 await token.transferFrom(alice, targetToken.nestingAccount(), {Substrate: alice.address}, 9n);71 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(9n);72 expect(await token.getBalance(targetToken.nestingAccount())).to.be.equal(1n);7374 75 await token.transferFrom(alice, targetToken.nestingAccount(), {Substrate: alice.address}, 1n);76 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(10n);77 expect(await token.getBalance(targetToken.nestingAccount())).to.be.equal(0n);78 });7980 itSub('Owner can burn nested token pieces', async ({helper}) => {81 const collection = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});82 const targetToken = await collection.mintToken(alice);8384 85 const collectionRFT = await helper.rft.mintCollection(alice);86 const token = await collectionRFT.mintToken(alice, 100n, {Substrate: alice.address});87 await token.transfer(alice, targetToken.nestingAccount(), 30n);8889 90 await token.burnFrom(alice, targetToken.nestingAccount(), 10n);91 expect(await token.getBalance({Substrate: alice.address})).to.be.equal(70n);92 expect(await token.getBalance(targetToken.nestingAccount())).to.be.equal(20n);93 expect(await targetToken.getChildren()).to.has.length(1);9495 96 await token.burnFrom(alice, targetToken.nestingAccount(), 20n);97 expect(await token.getBalance(targetToken.nestingAccount())).to.be.equal(0n);98 expect(await targetToken.getChildren()).to.has.length(0);99 expect(await token.doesExist()).to.be.true;100101 102 await targetToken.burn(alice);103 expect(await targetToken.doesExist()).to.be.false;104 });105});106107describe('Refungible nesting negative tests', () => {108 let alice: IKeyringPair;109 let bob: IKeyringPair;110111 before(async function() {112 await usingPlaygrounds(async (helper, privateKey) => {113 requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);114 const donor = await privateKey({url: import.meta.url});115 [alice, bob] = await helper.arrange.createAccounts([100n, 50n], donor);116 });117 });118119 [120 {restrictedMode: true},121 {restrictedMode: false},122 ].map(testCase => {123 itSub(`non-Owner cannot nest someone else's token${testCase.restrictedMode ? ': Restricted mode' : ''}`, async ({helper}) => {124 const collectionNFT = await helper.nft.mintCollection(alice);125 const collectionRFT = await helper.rft.mintCollection(alice);126 const targetToken = await collectionNFT.mintToken(alice);127128 await collectionNFT.setPermissions(alice, {access: 'AllowList', mintMode: true, nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionRFT.collectionId] : null}});129 await collectionNFT.addToAllowList(alice, {Substrate: bob.address});130 await collectionNFT.addToAllowList(alice, targetToken.nestingAccount());131132 133 const newToken = await collectionRFT.mintToken(alice);134 await expect(newToken.transfer(bob, targetToken.nestingAccount())).to.be.rejectedWith(/common\.TokenValueTooLow/);135136 expect(await targetToken.getChildren()).to.be.length(0);137 expect(await newToken.getBalance({Substrate: alice.address})).to.be.equal(1n);138139 140 await newToken.transfer(alice, targetToken.nestingAccount());141142 143 await expect(newToken.transferFrom(bob, targetToken.nestingAccount(), {Substrate: alice.address}, 1n))144 .to.be.rejectedWith(/common\.ApprovedValueTooLow/);145 expect(await newToken.getBalance(targetToken.nestingAccount())).to.be.equal(1n);146 });147 });148});