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 = 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({filename: __filename});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: allows an Owner to nest/unnest their token (Restricted nesting)', async ({helper}) => {56 const owner = await helper.eth.createAccountWithBalance(donor);5758 const {collectionId: collectionIdA, collectionAddress: collectionAddressA, contract: contractA} = await createNestingCollection(helper, owner);59 const {collectionAddress: collectionAddressB, contract: contractB} = await createNestingCollection(helper, owner);60 await contractA.methods.setCollectionNesting(true, [collectionAddressA, collectionAddressB]).send({from: owner});6162 63 const mintingtargetNftTokenIdResult = await contractA.methods.mint(owner).send({from: owner});64 const targetNftTokenId = mintingtargetNftTokenIdResult.events.Transfer.returnValues.tokenId;65 const nftTokenAddressA1 = helper.ethAddress.fromTokenId(collectionIdA, targetNftTokenId);6667 68 const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});69 const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;7071 72 const mintingTokenIdBResult = await contractB.methods.mint(owner).send({from: owner});73 const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;7475 76 await contractA.methods.transfer(nftTokenAddressA1, nftTokenIdA).send({from: owner});77 expect(await contractA.methods.ownerOf(nftTokenIdA).call()).to.be.equal(nftTokenAddressA1);7879 await contractB.methods.transfer(nftTokenAddressA1, nftTokenIdB).send({from: owner});80 expect(await contractB.methods.ownerOf(nftTokenIdB).call()).to.be.equal(nftTokenAddressA1);81 });82 });8384 describe('Negative Test: EVM Nesting', () => {85 itEth('NFT: disallows to nest token if nesting is disabled', async ({helper}) => {86 const owner = await helper.eth.createAccountWithBalance(donor);8788 const {collectionId, contract} = await createNestingCollection(helper, owner);89 await contract.methods.setCollectionNesting(false).send({from: owner});9091 92 const mintingTargetTokenIdResult = await contract.methods.mint(owner).send({from: owner});93 const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;94 const targetNftTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetTokenId);9596 97 const mintingNftTokenIdResult = await contract.methods.mint(owner).send({from: owner});98 const nftTokenId = mintingNftTokenIdResult.events.Transfer.returnValues.tokenId;99100 101 await expect(contract.methods102 .transfer(targetNftTokenAddress, nftTokenId)103 .call({from: owner})).to.be.rejectedWith('UserIsNotAllowedToNest');104 });105106 itEth('NFT: disallows a non-Owner to nest someone else\'s token', async ({helper}) => {107 const owner = await helper.eth.createAccountWithBalance(donor);108 const malignant = await helper.eth.createAccountWithBalance(donor);109110 const {collectionId, contract} = await createNestingCollection(helper, owner);111112 113 const mintingTargetTokenIdResult = await contract.methods.mint(owner).send({from: owner});114 const targetTokenId = mintingTargetTokenIdResult.events.Transfer.returnValues.tokenId;115 const targetTokenAddress = helper.ethAddress.fromTokenId(collectionId, targetTokenId);116117 118 const mintingTokenIdResult = await contract.methods.mint(malignant).send({from: owner});119 const tokenId = mintingTokenIdResult.events.Transfer.returnValues.tokenId;120121 122 await expect(contract.methods123 .transfer(targetTokenAddress, tokenId)124 .call({from: malignant})).to.be.rejectedWith('UserIsNotAllowedToNest');125 });126127 itEth('NFT: disallows a non-Owner to nest someone else\'s token (Restricted nesting)', async ({helper}) => {128 const owner = await helper.eth.createAccountWithBalance(donor);129 const malignant = await helper.eth.createAccountWithBalance(donor);130131 const {collectionId: collectionIdA, collectionAddress: collectionAddressA, contract: contractA} = await createNestingCollection(helper, owner);132 const {collectionAddress: collectionAddressB, contract: contractB} = await createNestingCollection(helper, owner);133134 await contractA.methods.setCollectionNesting(true, [collectionAddressA, collectionAddressB]).send({from: owner});135136 137 const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});138 const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;139 const nftTokenAddressA = helper.ethAddress.fromTokenId(collectionIdA, nftTokenIdA);140141 142 const mintingTokenIdBResult = await contractB.methods.mint(malignant).send({from: owner});143 const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;144145 146 await expect(contractB.methods147 .transfer(nftTokenAddressA, nftTokenIdB)148 .call({from: malignant})).to.be.rejectedWith('UserIsNotAllowedToNest');149 });150151 itEth('NFT: disallows to nest token in an unlisted collection', async ({helper}) => {152 const owner = await helper.eth.createAccountWithBalance(donor);153154 const {collectionId: collectionIdA, collectionAddress: collectionAddressA, contract: contractA} = await createNestingCollection(helper, owner);155 const {contract: contractB} = await createNestingCollection(helper, owner);156157 await contractA.methods.setCollectionNesting(true, [collectionAddressA]).send({from: owner});158159 160 const mintingTokenIdAResult = await contractA.methods.mint(owner).send({from: owner});161 const nftTokenIdA = mintingTokenIdAResult.events.Transfer.returnValues.tokenId;162 const nftTokenAddressA = helper.ethAddress.fromTokenId(collectionIdA, nftTokenIdA);163164 165 const mintingTokenIdBResult = await contractB.methods.mint(owner).send({from: owner});166 const nftTokenIdB = mintingTokenIdBResult.events.Transfer.returnValues.tokenId;167168169 170 await expect(contractB.methods171 .transfer(nftTokenAddressA, nftTokenIdB)172 .call()).to.be.rejectedWith('SourceCollectionIsNotAllowedToNest');173 });174 });175});