1234567891011121314151617import type {IKeyringPair} from '@polkadot/types/types';18import {expect, itSub, Pallets, usingPlaygrounds} from '../../util/index.js';19import {CrossAccountId, UniqueNFTCollection, UniqueRFTCollection} from '@unique/playgrounds/unique.js';2021let alice: IKeyringPair;22let bob: IKeyringPair;2324describe('Common nesting tests', () => {25 before(async () => {26 await usingPlaygrounds(async (helper, privateKey) => {27 const donor = await privateKey({url: import.meta.url});28 [alice, bob] = await helper.arrange.createAccounts([100n, 100n], donor);29 });30 });3132 [33 {mode: 'nft' as const, restrictedMode: true, requiredPallets: []},34 {mode: 'nft' as const, restrictedMode: false, requiredPallets: []},35 {mode: 'rft' as const, restrictedMode: true, requiredPallets: [Pallets.ReFungible]},36 {mode: 'rft' as const, restrictedMode: false, requiredPallets: [Pallets.ReFungible]},37 ].map(testCase => {38 itSub.ifWithPallets(`Token owner can nest ${testCase.mode.toUpperCase()} in NFT if "tokenOwner" permission set ${testCase.restrictedMode ? 'in restricted mode': ''}`, testCase.requiredPallets, async ({helper}) => {39 40 const targetNFTCollection = await helper.nft.mintCollection(alice);41 const targetTokenBob = await targetNFTCollection.mintToken(alice, {Substrate: bob.address});4243 const collectionForNesting = await helper[testCase.mode].mintCollection(bob);44 45 await targetNFTCollection.setPermissions(alice, {46 nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionForNesting.collectionId] : null},47 });4849 50 const nestedToken1 = testCase.mode === 'nft'51 ? await (collectionForNesting as UniqueNFTCollection).mintToken(bob, targetTokenBob.nestingAccount())52 : await (collectionForNesting as UniqueRFTCollection).mintToken(bob, 10n, targetTokenBob.nestingAccount());53 expect(await nestedToken1.getTopmostOwner()).to.be.deep.equal({Substrate: bob.address});54 expect(await nestedToken1.getOwner()).to.be.deep.equal(CrossAccountId.toLowerCase(targetTokenBob.nestingAccount()));5556 57 const nestedToken2 = await collectionForNesting.mintToken(bob);58 await nestedToken2.nest(bob, targetTokenBob);59 expect(await nestedToken2.getTopmostOwner()).to.be.deep.equal({Substrate: bob.address});60 expect(await nestedToken2.getOwner()).to.be.deep.equal(CrossAccountId.toLowerCase(targetTokenBob.nestingAccount()));61 });62 });636465 [66 {restrictedMode: true},67 {restrictedMode: false},68 ].map(testCase => {69 itSub(`Token owner can nest FT in NFT if "tokenOwner" permission set ${testCase.restrictedMode ? 'in restricted mode': ''}`, async ({helper}) => {70 71 const targetNFTCollection = await helper.nft.mintCollection(alice);72 const targetTokenBob = await targetNFTCollection.mintToken(alice, {Substrate: bob.address});7374 const collectionForNesting = await helper.ft.mintCollection(bob);75 76 await targetNFTCollection.setPermissions(alice, {77 nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionForNesting.collectionId] : null},78 });7980 81 await collectionForNesting.mint(bob, 100n, targetTokenBob.nestingAccount());82 expect(await collectionForNesting.getTop10Owners()).deep.eq([CrossAccountId.toLowerCase(targetTokenBob.nestingAccount())]);83 expect(await collectionForNesting.getBalance(targetTokenBob.nestingAccount())).eq(100n);8485 86 await collectionForNesting.mint(bob, 100n);87 await collectionForNesting.transfer(bob, targetTokenBob.nestingAccount(), 50n);88 expect(await collectionForNesting.getBalance(targetTokenBob.nestingAccount())).eq(150n);89 expect(await targetTokenBob.getChildren()).to.be.deep.equal([{collectionId: collectionForNesting.collectionId, tokenId: 0}]);90 });91 });9293 [94 {restrictedMode: true},95 {restrictedMode: false},96 ].map(testCase => {97 itSub(`Token owner can nest Native FT in NFT if "tokenOwner" permission set ${testCase.restrictedMode ? 'in restricted mode': ''}`, async ({helper}) => {98 99 const targetNFTCollection = await helper.nft.mintCollection(alice);100 const targetTokenBob = await targetNFTCollection.mintToken(alice, {Substrate: bob.address});101 expect(await targetTokenBob.getChildren()).to.be.empty;102103 const collectionForNesting = helper.ft.getCollectionObject(0);104 105 await targetNFTCollection.setPermissions(alice, {106 nesting: {tokenOwner: true, restricted: testCase.restrictedMode ? [collectionForNesting.collectionId] : null},107 });108109 110 await collectionForNesting.transfer(bob, targetTokenBob.nestingAccount(), 50n);111 expect(await collectionForNesting.getBalance(targetTokenBob.nestingAccount())).eq(50n);112 113 expect(await targetTokenBob.getChildren()).to.be.deep.equal([]);114 });115 });116117118 itSub.ifWithPallets('Owner can unnest tokens using transferFrom', [Pallets.ReFungible], async ({helper}) => {119 const collectionToNest = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});120 const tokenA = await collectionToNest.mintToken(alice);121 const tokenB = await collectionToNest.mintToken(alice);122123 124 const nftCollectionToBeNested = await helper.nft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});125 const rftCollectionToBeNested = await helper.rft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});126 const ftCollectionToBeNested = await helper.ft.mintCollection(alice, {permissions: {nesting: {tokenOwner: true}}});127 const nativeFtCollectionToBeNested = helper.ft.getCollectionObject(0);128129 const nestedNFT = await nftCollectionToBeNested.mintToken(alice, tokenA.nestingAccount());130 const nestedRFT = await rftCollectionToBeNested.mintToken(alice, 100n, tokenA.nestingAccount());131 await ftCollectionToBeNested.mint(alice, 100n, tokenA.nestingAccount());132 await nativeFtCollectionToBeNested.transfer(alice, tokenA.nestingAccount(), 100n);133 expect(await nestedNFT.getOwner()).to.be.deep.equal(CrossAccountId.toLowerCase(tokenA.nestingAccount()));134 expect(await nestedRFT.getOwner()).to.be.deep.equal(CrossAccountId.toLowerCase(tokenA.nestingAccount()));135 expect(await ftCollectionToBeNested.getBalance(tokenA.nestingAccount())).to.equal(100n);136 expect(await nativeFtCollectionToBeNested.getBalance(tokenA.nestingAccount())).to.equal(100n);137138 expect(await tokenA.getChildren()).to.be.length(3);139 expect(await tokenB.getChildren()).to.be.length(0);140141 142 await nestedNFT.transferFrom(alice, tokenA.nestingAccount(), tokenB.nestingAccount());143 await nestedRFT.transferFrom(alice, tokenA.nestingAccount(), tokenB.nestingAccount(), 25n);144 await ftCollectionToBeNested.transferFrom(alice, tokenA.nestingAccount(), tokenB.nestingAccount(), 25n);145 await nativeFtCollectionToBeNested.transferFrom(alice, tokenA.nestingAccount(), tokenB.nestingAccount(), 25n);146147 expect(await nestedNFT.getTopmostOwner()).to.be.deep.equal({Substrate: alice.address});148 expect(await nestedNFT.getOwner()).to.be.deep.equal(CrossAccountId.toLowerCase(tokenB.nestingAccount()));149150 expect(await nestedRFT.getBalance(tokenB.nestingAccount())).to.equal(25n);151 expect(await nestedRFT.getBalance(tokenA.nestingAccount())).to.equal(75n);152153 expect(await ftCollectionToBeNested.getBalance(tokenB.nestingAccount())).to.equal(25n);154 expect(await ftCollectionToBeNested.getBalance(tokenA.nestingAccount())).to.equal(75n);155156 expect(await nativeFtCollectionToBeNested.getBalance(tokenB.nestingAccount())).to.equal(25n);157 expect(await nativeFtCollectionToBeNested.getBalance(tokenA.nestingAccount())).to.equal(75n);158159 160 expect(await tokenA.getChildren()).to.be.length(2);161 162 expect(await tokenB.getChildren()).to.be.length(3);163 });164});