1234567891011121314151617import {IKeyringPair} from '@polkadot/types/types';18import {readFile} from 'fs/promises';19import {itEth, usingEthPlaygrounds, expect, SponsoringMode} from '../util';2021describe('Matcher contract usage', () => {22 const PRICE = 2000n;23 let donor: IKeyringPair;24 let alice: IKeyringPair;25 let aliceMirror: string;26 let aliceDoubleMirror: string;27 let seller: IKeyringPair;28 let sellerMirror: string;2930 before(async () => {31 await usingEthPlaygrounds(async (_helper, privateKey) => {32 donor = await privateKey({filename: __filename});33 }); 34 });3536 beforeEach(async () => {37 await usingEthPlaygrounds(async (helper, privateKey) => {38 [alice] = await helper.arrange.createAccounts([1000n], donor);39 aliceMirror = helper.address.substrateToEth(alice.address).toLowerCase();40 aliceDoubleMirror = helper.address.ethToSubstrate(aliceMirror);41 seller = await privateKey(`//Seller/${Date.now()}`);42 sellerMirror = helper.address.substrateToEth(seller.address).toLowerCase();4344 await helper.balance.transferToSubstrate(donor, aliceDoubleMirror, 10_000_000_000_000_000_000n);45 });46 });4748 itEth('With UNQ', async ({helper}) => {49 const matcherOwner = await helper.eth.createAccountWithBalance(donor);50 const matcher = await helper.ethContract.deployByCode(matcherOwner, 'MarketPlace', (await readFile(`${__dirname}/MarketPlace.sol`)).toString(), [{solPath: 'api/UniqueNFT.sol', fsPath: `${__dirname}/../api/UniqueNFT.sol`}], helper.eth.DEFAULT_GAS * 2);5152 const sponsor = await helper.eth.createAccountWithBalance(donor);53 const helpers = helper.ethNativeContract.contractHelpers(matcherOwner);54 await helpers.methods.setSponsoringMode(matcher.options.address, SponsoringMode.Allowlisted).send({from: matcherOwner});55 await helpers.methods.setSponsoringRateLimit(matcher.options.address, 1).send({from: matcherOwner});56 57 await helpers.methods.setSponsor(matcher.options.address, sponsor).send({from: matcherOwner});58 await helpers.methods.confirmSponsorship(matcher.options.address).send({from: sponsor});5960 const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}, pendingSponsor: alice.address});61 await collection.confirmSponsorship(alice);62 await collection.addToAllowList(alice, {Substrate: aliceDoubleMirror});63 const evmCollection = helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(collection.collectionId), 'nft');64 await helper.eth.transferBalanceFromSubstrate(donor, aliceMirror);6566 await helpers.methods.toggleAllowed(matcher.options.address, aliceMirror, true).send({from: matcherOwner});67 await helpers.methods.toggleAllowed(matcher.options.address, sellerMirror, true).send({from: matcherOwner});6869 const token = await collection.mintToken(alice, {Ethereum: sellerMirror});7071 72 expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror});7374 75 {76 await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0');77 await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0');78 }7980 81 expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});8283 84 {85 const sellerBalanceBeforePurchase = await helper.balance.getSubstrate(seller.address);86 await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buy(evmCollection.options.address, token.tokenId).encodeABI(), PRICE.toString());87 expect(await helper.balance.getSubstrate(seller.address) - sellerBalanceBeforePurchase === PRICE);88 }8990 91 expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror});9293 94 await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address});9596 97 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});98 });99100 itEth('With escrow', async ({helper}) => {101 const matcherOwner = await helper.eth.createAccountWithBalance(donor);102 const matcher = await helper.ethContract.deployByCode(matcherOwner, 'MarketPlace', (await readFile(`${__dirname}/MarketPlace.sol`)).toString(), [{solPath: 'api/UniqueNFT.sol', fsPath: `${__dirname}/../api/UniqueNFT.sol`}], helper.eth.DEFAULT_GAS * 2);103104 const sponsor = await helper.eth.createAccountWithBalance(donor);105 const escrow = await helper.eth.createAccountWithBalance(donor);106 await matcher.methods.setEscrow(escrow, true).send({from: matcherOwner});107 const helpers = helper.ethNativeContract.contractHelpers(matcherOwner);108 await helpers.methods.setSponsoringMode(matcher.options.address, SponsoringMode.Allowlisted).send({from: matcherOwner});109 await helpers.methods.setSponsoringRateLimit(matcher.options.address, 1).send({from: matcherOwner});110 111 await helpers.methods.setSponsor(matcher.options.address, sponsor).send({from: matcherOwner});112 await helpers.methods.confirmSponsorship(matcher.options.address).send({from: sponsor});113114 const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}, pendingSponsor: alice.address});115 await collection.confirmSponsorship(alice);116 await collection.addToAllowList(alice, {Substrate: aliceDoubleMirror});117 const evmCollection = helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(collection.collectionId), 'nft');118 await helper.eth.transferBalanceFromSubstrate(donor, aliceMirror);119120121 await helpers.methods.toggleAllowed(matcher.options.address, aliceMirror, true).send({from: matcherOwner});122123 await helpers.methods.toggleAllowed(matcher.options.address, sellerMirror, true).send({from: matcherOwner});124125 const token = await collection.mintToken(alice, {Ethereum: sellerMirror});126127 128 expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror});129130 131 {132 await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0');133 await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0');134 }135136 137 expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});138139 140 await matcher.methods.depositKSM(PRICE, aliceMirror).send({from: escrow});141142 143 {144 expect(await matcher.methods.balanceKSM(sellerMirror).call()).to.be.equal('0');145 expect(await matcher.methods.balanceKSM(aliceMirror).call()).to.be.equal(PRICE.toString());146147 await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buyKSM(evmCollection.options.address, token.tokenId, aliceMirror, aliceMirror).encodeABI(), '0');148149 150 expect(await matcher.methods.balanceKSM(aliceMirror).call()).to.be.equal('0');151 expect(await matcher.methods.balanceKSM(sellerMirror).call()).to.be.equal(PRICE.toString());152 }153154 155 expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror});156157 158 await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address});159160 161 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});162 });163164 itEth('Sell tokens from substrate user via EVM contract', async ({helper}) => {165 const matcherOwner = await helper.eth.createAccountWithBalance(donor);166 const matcher = await helper.ethContract.deployByCode(matcherOwner, 'MarketPlace', (await readFile(`${__dirname}/MarketPlace.sol`)).toString(), [{solPath: 'api/UniqueNFT.sol', fsPath: `${__dirname}/../api/UniqueNFT.sol`}], helper.eth.DEFAULT_GAS * 2);167168 await helper.eth.transferBalanceFromSubstrate(donor, matcher.options.address);169170 const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}});171 const evmCollection = helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(collection.collectionId), 'nft');172173 await helper.balance.transferToSubstrate(donor, seller.address, 100_000_000_000_000_000_000n);174 175 const token = await collection.mintToken(alice, {Ethereum: sellerMirror});176177 178 expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror});179180 181 {182 await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0');183 await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0');184 }185186 187 expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});188189 190 {191 const sellerBalanceBeforePurchase = await helper.balance.getSubstrate(seller.address);192 await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buy(evmCollection.options.address, token.tokenId).encodeABI(), PRICE.toString());193 expect(await helper.balance.getSubstrate(seller.address) - sellerBalanceBeforePurchase === PRICE);194 }195196 197 expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror});198199 200 await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address});201202 203 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});204 });205});