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 web3 = helper.getWeb3();50 const matcherOwner = await helper.eth.createAccountWithBalance(donor);51 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {52 from: matcherOwner,53 gas: helper.eth.DEFAULT_GAS,54 });55 const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments:[matcherOwner]}).send({from: matcherOwner});5657 const sponsor = await helper.eth.createAccountWithBalance(donor);58 const helpers = helper.ethNativeContract.contractHelpers(matcherOwner);59 await helpers.methods.setSponsoringMode(matcher.options.address, SponsoringMode.Allowlisted).send({from: matcherOwner});60 await helpers.methods.setSponsoringRateLimit(matcher.options.address, 1).send({from: matcherOwner});61 62 await helpers.methods.setSponsor(matcher.options.address, sponsor).send({from: matcherOwner});63 await helpers.methods.confirmSponsorship(matcher.options.address).send({from: sponsor});6465 const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}, pendingSponsor: alice.address});66 await collection.confirmSponsorship(alice);67 await collection.addToAllowList(alice, {Substrate: aliceDoubleMirror});68 const evmCollection = helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(collection.collectionId), 'nft');69 await helper.eth.transferBalanceFromSubstrate(donor, aliceMirror);7071 await helpers.methods.toggleAllowed(matcher.options.address, aliceMirror, true).send({from: matcherOwner});72 await helpers.methods.toggleAllowed(matcher.options.address, sellerMirror, true).send({from: matcherOwner});7374 const token = await collection.mintToken(alice, {Ethereum: sellerMirror});7576 77 expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror});7879 80 {81 await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0');82 await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0');83 }8485 86 expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});8788 89 {90 const sellerBalanceBeforePurchase = await helper.balance.getSubstrate(seller.address);91 await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buy(evmCollection.options.address, token.tokenId).encodeABI(), PRICE.toString());92 expect(await helper.balance.getSubstrate(seller.address) - sellerBalanceBeforePurchase === PRICE);93 }9495 96 expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror});9798 99 await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address});100101 102 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});103 });104105 itEth('With escrow', async ({helper}) => {106 const web3 = helper.getWeb3();107 const matcherOwner = await helper.eth.createAccountWithBalance(donor);108 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {109 from: matcherOwner,110 gas: helper.eth.DEFAULT_GAS,111 });112 const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments: [matcherOwner]}).send({from: matcherOwner, gas: 10000000});113114 const sponsor = await helper.eth.createAccountWithBalance(donor);115 const escrow = await helper.eth.createAccountWithBalance(donor);116 await matcher.methods.setEscrow(escrow).send({from: matcherOwner});117 const helpers = helper.ethNativeContract.contractHelpers(matcherOwner);118 await helpers.methods.setSponsoringMode(matcher.options.address, SponsoringMode.Allowlisted).send({from: matcherOwner});119 await helpers.methods.setSponsoringRateLimit(matcher.options.address, 1).send({from: matcherOwner});120 121 await helpers.methods.setSponsor(matcher.options.address, sponsor).send({from: matcherOwner});122 await helpers.methods.confirmSponsorship(matcher.options.address).send({from: sponsor});123124 const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}, pendingSponsor: alice.address});125 await collection.confirmSponsorship(alice);126 await collection.addToAllowList(alice, {Substrate: aliceDoubleMirror});127 const evmCollection = helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(collection.collectionId), 'nft');128 await helper.eth.transferBalanceFromSubstrate(donor, aliceMirror);129130131 await helpers.methods.toggleAllowed(matcher.options.address, aliceMirror, true).send({from: matcherOwner});132133 await helpers.methods.toggleAllowed(matcher.options.address, sellerMirror, true).send({from: matcherOwner});134135 const token = await collection.mintToken(alice, {Ethereum: sellerMirror});136137 138 expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror});139140 141 {142 await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0');143 await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0');144 }145146 147 expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});148149 150 await matcher.methods.depositKSM(PRICE, aliceMirror).send({from: escrow});151152 153 {154 expect(await matcher.methods.balanceKSM(sellerMirror).call()).to.be.equal('0');155 expect(await matcher.methods.balanceKSM(aliceMirror).call()).to.be.equal(PRICE.toString());156157 await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buyKSM(evmCollection.options.address, token.tokenId, aliceMirror, aliceMirror).encodeABI(), '0');158159 160 expect(await matcher.methods.balanceKSM(aliceMirror).call()).to.be.equal('0');161 expect(await matcher.methods.balanceKSM(sellerMirror).call()).to.be.equal(PRICE.toString());162 }163164 165 expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror});166167 168 await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address});169170 171 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});172 });173174 itEth('Sell tokens from substrate user via EVM contract', async ({helper}) => {175 const web3 = helper.getWeb3();176 const matcherOwner = await helper.eth.createAccountWithBalance(donor);177 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {178 from: matcherOwner,179 gas: helper.eth.DEFAULT_GAS,180 });181 const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments:[matcherOwner]}).send({from: matcherOwner});182183 await helper.eth.transferBalanceFromSubstrate(donor, matcher.options.address);184185 const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}});186 const evmCollection = helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(collection.collectionId), 'nft');187188 await helper.balance.transferToSubstrate(donor, seller.address, 100_000_000_000_000_000_000n);189 190 const token = await collection.mintToken(alice, {Ethereum: sellerMirror});191192 193 expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror});194195 196 {197 await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0');198 await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0');199 }200201 202 expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});203204 205 {206 const sellerBalanceBeforePurchase = await helper.balance.getSubstrate(seller.address);207 await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buy(evmCollection.options.address, token.tokenId).encodeABI(), PRICE.toString());208 expect(await helper.balance.getSubstrate(seller.address) - sellerBalanceBeforePurchase === PRICE);209 }210211 212 expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror});213214 215 await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address});216217 218 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});219 });220});