1import {IKeyringPair} from '@polkadot/types/types';2import {Contract} from 'web3-eth-contract';34import {itEth, EthUniqueHelper, usingEthPlaygrounds, expect} from '../util';56const createNestingCollection = async (7 helper: EthUniqueHelper,8 owner: string,9): Promise<{ collectionId: number, collectionAddress: string, contract: Contract }> => {10 const {collectionAddress, collectionId} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');1112 const contract = await helper.ethNativeContract.collection(collectionAddress, 'nft', owner);13 await contract.methods.setCollectionNesting(true).send({from: owner});1415 return {collectionId, collectionAddress, contract};16};171819describe('EVM nesting tests group', () => {20 let donor: IKeyringPair;2122 before(async function() {23 await usingEthPlaygrounds(async (_, privateKey) => {24 donor = await privateKey({url: import.meta.url});25 });26 });2728 describe('Integration Test: EVM Nesting', () => {29 itEth('NFT: allows an Owner to nest/unnest their token', async ({helper}) => {30 const owner = await helper.eth.createAccountWithBalance(donor);31 const {collectionId, contract} = await createNestingCollection(helper, owner);3233 34 const mintingTargetNFTTokenIdResult = await contract.methods.mint(owner).send({from: owner});35 const targetNFTTokenId = mintingTargetNFTTokenIdResult.events.Transfer.returnValues.tokenId;36 const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetNFTTokenId);3738 39 const mintingFirstTokenIdResult = await contract.methods.mint(targetNftTokenAddress).send({from: owner});40 const firstTokenId = mintingFirstTokenIdResult.events.Transfer.returnValues.tokenId;41 expect(await contract.methods.ownerOf(firstTokenId).call()).to.be.equal(targetNftTokenAddress);4243 44 const mintingSecondTokenIdResult = await contract.methods.mint(owner).send({from: owner});45 const secondTokenId = mintingSecondTokenIdResult.events.Transfer.returnValues.tokenId;4647 await contract.methods.transfer(targetNftTokenAddress, secondTokenId).send({from: owner});48 expect(await contract.methods.ownerOf(secondTokenId).call()).to.be.equal(targetNftTokenAddress);4950 51 await contract.methods.transferFrom(targetNftTokenAddress, owner, secondTokenId).send({from: owner});52 expect(await contract.methods.ownerOf(secondTokenId).call()).to.be.equal(owner);53 });5455 itEth('NFT: collectionNestingRestrictedCollectionIds() & collectionNestingPermissions', async ({helper}) => {56 const owner = await helper.eth.createAccountWithBalance(donor);57 const {collectionId: unnestedCollsectionId, collectionAddress: unnsetedCollectionAddress} = await helper.eth.createNFTCollection(owner, 'A', 'B', 'C');58 const unnestedContract = await helper.ethNativeContract.collection(unnsetedCollectionAddress, 'nft', owner);59 expect(await unnestedContract.methods.collectionNestingRestrictedCollectionIds().call({from: owner})).to.be.like([false, []]);6061 const {contract} = await createNestingCollection(helper, owner);62 expect(await contract.methods.collectionNestingRestrictedCollectionIds().call({from: owner})).to.be.like([true, []]);63 await contract.methods.setCollectionNesting(true, [unnsetedCollectionAddress]).send({from: owner});64 expect(await contract.methods.collectionNestingRestrictedCollectionIds().call({from: owner})).to.be.like([true, [unnestedCollsectionId.toString()]]);65 expect(await contract.methods.collectionNestingPermissions().call({from: owner})).to.be.like([['1', false], ['0', true]]);66 await contract.methods.setCollectionNesting(false).send({from: owner});67 expect(await contract.methods.collectionNestingPermissions().call({from: owner})).to.be.like([['1', false], ['0', false]]);68 });6970 itEth('NFT: allows an Owner to nest/unnest their token (Restricted nesting)', async ({helper}) => {71 const owner = await helper.eth.createAccountWithBalance(donor);7273 const {collectionId: collectionIdA, collectionAddress: collectionAddressA, contract: contractA} = await createNestingCollection(helper, owner);74 const {collectionAddress: collectionAddressB, contract: contractB} = await createNestingCollection(helper, owner);75 await contractA.methods.setCollectionNesting(true, [collectionAddressA, collectionAddressB]).send({from: owner});7677 78 const mintingtargetNftTokenIdResult = await contractA.methods.mint(owner).send({from: owner});79 const targetNftTokenId = mintingtargetNftTokenIdResult.events.Transfer.returnValues.tokenId;80 const nftTokenAddressA1 = helper.ethAddress.fromTokenId(collectionIdA, targetNftTokenId);8182 83 const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});84 const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;8586 87 const mintingTokenIdBResult = await contractB.methods.mint(owner).send({from: owner});88 const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;8990 91 await contractA.methods.transfer(nftTokenAddressA1, nftTokenIdA).send({from: owner});92 expect(await contractA.methods.ownerOf(nftTokenIdA).call()).to.be.equal(nftTokenAddressA1);9394 await contractB.methods.transfer(nftTokenAddressA1, nftTokenIdB).send({from: owner});95 expect(await contractB.methods.ownerOf(nftTokenIdB).call()).to.be.equal(nftTokenAddressA1);96 });97 });9899 describe('Negative Test: EVM Nesting', () => {100 itEth('NFT: disallows to nest token if nesting is disabled', async ({helper}) => {101 const owner = await helper.eth.createAccountWithBalance(donor);102103 const {collectionId, contract} = await createNestingCollection(helper, owner);104 await contract.methods.setCollectionNesting(false).send({from: owner});105106 107 const mintingTargetTokenIdResult = await contract.methods.mint(owner).send({from: owner});108 const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;109 const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetTokenId);110111 112 const mintingNftTokenIdResult = await contract.methods.mint(owner).send({from: owner});113 const nftTokenId = mintingNftTokenIdResult.events.Transfer.returnValues.tokenId;114115 116 await expect(contract.methods117 .transfer(targetNftTokenAddress, nftTokenId)118 .call({from: owner})).to.be.rejectedWith('UserIsNotAllowedToNest');119 });120121 itEth('NFT: disallows a non-Owner to nest someone else\'s token', async ({helper}) => {122 const owner = await helper.eth.createAccountWithBalance(donor);123 const malignant = await helper.eth.createAccountWithBalance(donor);124125 const {collectionId, contract} = await createNestingCollection(helper, owner);126127 128 const mintingTargetTokenIdResult = await contract.methods.mint(owner).send({from: owner});129 const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;130 const targetTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetTokenId);131132 133 const mintingTokenIdResult = await contract.methods.mint(malignant).send({from: owner});134 const tokenId = mintingTokenIdResult.events.Transfer.returnValues.tokenId;135136 137 await expect(contract.methods138 .transfer(targetTokenAddress, tokenId)139 .call({from: malignant})).to.be.rejectedWith('UserIsNotAllowedToNest');140 });141142 itEth('NFT: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async ({helper}) => {143 const owner = await helper.eth.createAccountWithBalance(donor);144 const malignant = await helper.eth.createAccountWithBalance(donor);145146 const {collectionId: collectionIdA, collectionAddress: collectionAddressA, contract: contractA} = await createNestingCollection(helper, owner);147 const {collectionAddress: collectionAddressB, contract: contractB} = await createNestingCollection(helper, owner);148149 await contractA.methods.setCollectionNesting(true, [collectionAddressA, collectionAddressB]).send({from: owner});150151 152 const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});153 const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;154 const nftTokenAddressA = helper.ethAddress.fromTokenId(collectionIdA, nftTokenIdA);155156 157 const mintingTokenIdBResult = await contractB.methods.mint(malignant).send({from: owner});158 const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;159160 161 await expect(contractB.methods162 .transfer(nftTokenAddressA, nftTokenIdB)163 .call({from: malignant})).to.be.rejectedWith('UserIsNotAllowedToNest');164 });165166 itEth('NFT: disallows to nest token in an unlisted collection', async ({helper}) => {167 const owner = await helper.eth.createAccountWithBalance(donor);168169 const {collectionId: collectionIdA, collectionAddress: collectionAddressA, contract: contractA} = await createNestingCollection(helper, owner);170 const {contract: contractB} = await createNestingCollection(helper, owner);171172 await contractA.methods.setCollectionNesting(true, [collectionAddressA]).send({from: owner});173174 175 const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});176 const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;177 const nftTokenAddressA = helper.ethAddress.fromTokenId(collectionIdA, nftTokenIdA);178179 180 const mintingTokenIdBResult = await contractB.methods.mint(owner).send({from: owner});181 const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;182183184 185 await expect(contractB.methods186 .transfer(nftTokenAddressA, nftTokenIdB)187 .call()).to.be.rejectedWith('SourceCollectionIsNotAllowedToNest');188 });189 });190});