difftreelog
test market evm tests to playgrounds
in: master
2 files changed
tests/src/eth/marketplace/marketplace.test.tsdiffbeforeafterboth14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.161617import {usingPlaygrounds} from './../../util/playgrounds/index';18import {IKeyringPair} from '@polkadot/types/types';17import {readFile} from 'fs/promises';19import {readFile} from 'fs/promises';18import {getBalanceSingle} from '../../substrate/get-balance';20import {collectionIdToAddress, contractHelpers, GAS_ARGS, SponsoringMode} from '../util/helpers';19import {20 addToAllowListExpectSuccess, 21 confirmSponsorshipExpectSuccess, 22 createCollectionExpectSuccess, 23 createItemExpectSuccess, 24 getTokenOwner,25 setCollectionLimitsExpectSuccess, 26 setCollectionSponsorExpectSuccess, 27 transferExpectSuccess, 28 transferFromExpectSuccess,29 transferBalanceTo,30} from '../../util/helpers';31import {collectionIdToAddress, contractHelpers, createEthAccountWithBalance, executeEthTxOnSub, GAS_ARGS, itWeb3, SponsoringMode, subToEth, subToEthLowercase, transferBalanceToEth} from '../util/helpers';32import {evmToAddress} from '@polkadot/util-crypto';33import nonFungibleAbi from '../nonFungibleAbi.json';21import nonFungibleAbi from '../nonFungibleAbi.json';342235import {expect} from 'chai';23import {itEth, expect} from '../util/playgrounds';362437const PRICE = 2000n;25const PRICE = 2000n;382639describe('Matcher contract usage', () => {27describe('Matcher contract usage', () => {40 itWeb3('With UNQ', async ({api, web3, privateKeyWrapper}) => {28 let donor: IKeyringPair;29 let alice: IKeyringPair;30 let aliceMirror: string;31 let aliceDoubleMirror: string;32 let seller: IKeyringPair;33 let sellerMirror: string;3435 before(async () => {36 await usingPlaygrounds(async (_helper, privateKey) => {41 const alice = privateKeyWrapper('//Alice');37 donor = privateKey('//Alice');42 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);38 }); 39 });4041 beforeEach(async () => {42 await usingPlaygrounds(async (helper, privateKey) => {43 [alice] = await helper.arrange.createAccounts([10000n], donor);43 const matcherOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);44 aliceMirror = helper.address.substrateToEth(alice.address).toLowerCase();45 aliceDoubleMirror = helper.address.ethToSubstrate(aliceMirror);46 seller = privateKey(`//Seller/${Date.now()}`);47 sellerMirror = helper.address.substrateToEth(seller.address).toLowerCase();4849 await helper.balance.transferToSubstrate(donor, aliceDoubleMirror, 10_000_000_000_000_000_000n);50 });51 });5253 itEth('With UNQ', async ({helper}) => {54 const web3 = helper.web3!;5556 const sponsor = await helper.eth.createAccountWithBalance(donor);57 const matcherOwner = await helper.eth.createAccountWithBalance(donor);44 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {58 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {45 from: matcherOwner,59 from: matcherOwner,46 ...GAS_ARGS,60 ...GAS_ARGS,53 await helpers.methods.setSponsor(matcher.options.address, sponsor).send({from: matcherOwner});67 await helpers.methods.setSponsor(matcher.options.address, sponsor).send({from: matcherOwner});54 await helpers.methods.confirmSponsorship(matcher.options.address).send({from: sponsor});68 await helpers.methods.confirmSponsorship(matcher.options.address).send({from: sponsor});556956 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});70 const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}, pendingSponsor: alice.address});57 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorApproveTimeout: 1});71 await collection.confirmSponsorship(alice);72 await collection.addToAllowList(alice, {Substrate: aliceDoubleMirror});58 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner});73 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collection.collectionId), {from: matcherOwner});59 await setCollectionSponsorExpectSuccess(collectionId, alice.address);74 await helper.eth.transferBalanceFromSubstrate(donor, aliceMirror);60 await transferBalanceToEth(api, alice, subToEth(alice.address));61 await confirmSponsorshipExpectSuccess(collectionId);627563 await helpers.methods.toggleAllowed(matcher.options.address, subToEth(alice.address), true).send({from: matcherOwner});76 await helpers.methods.toggleAllowed(matcher.options.address, aliceMirror, true).send({from: matcherOwner});64 await addToAllowListExpectSuccess(alice, collectionId, evmToAddress(subToEth(alice.address)));77 await helpers.methods.toggleAllowed(matcher.options.address, sellerMirror, true).send({from: matcherOwner});657866 const seller = privateKeyWrapper(`//Seller/${Date.now()}`);79 const token = await collection.mintToken(alice, {Ethereum: sellerMirror});67 await helpers.methods.toggleAllowed(matcher.options.address, subToEth(seller.address), true).send({from: matcherOwner});688069 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);7071 // To transfer item to matcher it first needs to be transfered to EVM account of bob72 await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});7374 // Token is owned by seller initially81 // Token is owned by seller initially75 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});82 expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror});768377 // Ask84 // Ask78 {85 {79 await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));86 await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0');80 await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId));87 await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0');81 }88 }828983 // Token is transferred to matcher90 // Token is transferred to matcher84 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});91 expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});859286 // Buy93 // Buy87 {94 {88 const sellerBalanceBeforePurchase = await getBalanceSingle(api, seller.address);95 const sellerBalanceBeforePurchase = await helper.balance.getSubstrate(seller.address);89 await executeEthTxOnSub(web3, api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId), {value: PRICE});96 await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buy(evmCollection.options.address, token.tokenId).encodeABI(), PRICE.toString());90 expect(await getBalanceSingle(api, seller.address) - sellerBalanceBeforePurchase === PRICE);97 expect(await helper.balance.getSubstrate(seller.address) - sellerBalanceBeforePurchase === PRICE);91 }98 }929993 // Token is transferred to evm account of alice100 // Token is transferred to evm account of alice94 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});101 expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror});9510296 // Transfer token to substrate side of alice103 // Transfer token to substrate side of alice97 await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});104 await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address});9810599 // Token is transferred to substrate account of alice, seller received funds106 // Token is transferred to substrate account of alice, seller received funds100 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});107 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});101 });108 });102109110 itEth('With escrow', async ({helper}) => {111 const web3 = helper.web3!;103112104 itWeb3('With escrow', async ({api, web3, privateKeyWrapper}) => {113 const sponsor = await helper.eth.createAccountWithBalance(donor);105 const alice = privateKeyWrapper('//Alice');106 const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper);107 const matcherOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);114 const matcherOwner = await helper.eth.createAccountWithBalance(donor);108 const escrow = await createEthAccountWithBalance(api, web3, privateKeyWrapper);115 const escrow = await helper.eth.createAccountWithBalance(donor);109 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {116 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {110 from: matcherOwner,117 from: matcherOwner,111 ...GAS_ARGS,118 ...GAS_ARGS,119 await helpers.methods.setSponsor(matcher.options.address, sponsor).send({from: matcherOwner});126 await helpers.methods.setSponsor(matcher.options.address, sponsor).send({from: matcherOwner});120 await helpers.methods.confirmSponsorship(matcher.options.address).send({from: sponsor});127 await helpers.methods.confirmSponsorship(matcher.options.address).send({from: sponsor});121128122 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});129 const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}, pendingSponsor: alice.address});123 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorApproveTimeout: 1});130 await collection.confirmSponsorship(alice);131 await collection.addToAllowList(alice, {Substrate: aliceDoubleMirror});124 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner});132 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collection.collectionId), {from: matcherOwner});125 await setCollectionSponsorExpectSuccess(collectionId, alice.address);133 await helper.eth.transferBalanceFromSubstrate(donor, aliceMirror);126 await transferBalanceToEth(api, alice, subToEth(alice.address));127 await confirmSponsorshipExpectSuccess(collectionId);128134129 await helpers.methods.toggleAllowed(matcher.options.address, subToEth(alice.address), true).send({from: matcherOwner});130 await addToAllowListExpectSuccess(alice, collectionId, evmToAddress(subToEth(alice.address)));131135132 const seller = privateKeyWrapper(`//Seller/${Date.now()}`);136 await helpers.methods.toggleAllowed(matcher.options.address, aliceMirror, true).send({from: matcherOwner});133 await helpers.methods.toggleAllowed(matcher.options.address, subToEth(seller.address), true).send({from: matcherOwner});134137135 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);138 await helpers.methods.toggleAllowed(matcher.options.address, sellerMirror, true).send({from: matcherOwner});136139137 // To transfer item to matcher it first needs to be transfered to EVM account of bob140 const token = await collection.mintToken(alice, {Ethereum: sellerMirror});138 await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});139141140 // Token is owned by seller initially142 // Token is owned by seller initially141 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});143 expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror});142144143 // Ask145 // Ask144 {146 {145 await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));147 await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0');146 await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId));148 await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0');147 }149 }148150149 // Token is transferred to matcher151 // Token is transferred to matcher150 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});152 expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});151153152 // Give buyer KSM154 // Give buyer KSM153 await matcher.methods.depositKSM(PRICE, subToEth(alice.address)).send({from: escrow});155 await matcher.methods.depositKSM(PRICE, aliceMirror).send({from: escrow});154156155 // Buy157 // Buy156 {158 {157 expect(await matcher.methods.balanceKSM(subToEth(seller.address)).call()).to.be.equal('0');159 expect(await matcher.methods.balanceKSM(sellerMirror).call()).to.be.equal('0');158 expect(await matcher.methods.balanceKSM(subToEth(alice.address)).call()).to.be.equal(PRICE.toString());160 expect(await matcher.methods.balanceKSM(aliceMirror).call()).to.be.equal(PRICE.toString());159161160 await executeEthTxOnSub(web3, api, alice, matcher, m => m.buyKSM(evmCollection.options.address, tokenId, subToEth(alice.address), subToEth(alice.address)));162 await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buyKSM(evmCollection.options.address, token.tokenId, aliceMirror, aliceMirror).encodeABI(), '0');161163162 // Price is removed from buyer balance, and added to seller164 // Price is removed from buyer balance, and added to seller163 expect(await matcher.methods.balanceKSM(subToEth(alice.address)).call()).to.be.equal('0');165 expect(await matcher.methods.balanceKSM(aliceMirror).call()).to.be.equal('0');164 expect(await matcher.methods.balanceKSM(subToEth(seller.address)).call()).to.be.equal(PRICE.toString());166 expect(await matcher.methods.balanceKSM(sellerMirror).call()).to.be.equal(PRICE.toString());165 }167 }166168167 // Token is transferred to evm account of alice169 // Token is transferred to evm account of alice168 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});170 expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror});169171170 // Transfer token to substrate side of alice172 // Transfer token to substrate side of alice171 await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});173 await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address});172174173 // Token is transferred to substrate account of alice, seller received funds175 // Token is transferred to substrate account of alice, seller received funds174 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});176 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});175 });177 });176178179 itEth('Sell tokens from substrate user via EVM contract', async ({helper, privateKey}) => {180 const web3 = helper.web3!;177181178 itWeb3('Sell tokens from substrate user via EVM contract', async ({api, web3, privateKeyWrapper}) => {182 const matcherOwner = await helper.eth.createAccountWithBalance(donor);179 const alice = privateKeyWrapper('//Alice');180 const matcherOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);181 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {183 const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, {182 from: matcherOwner,184 from: matcherOwner,183 ...GAS_ARGS,185 ...GAS_ARGS,184 });186 });185 const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments:[matcherOwner]}).send({from: matcherOwner});187 const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments:[matcherOwner]}).send({from: matcherOwner});186 await transferBalanceToEth(api, alice, matcher.options.address);188 await helper.eth.transferBalanceFromSubstrate(donor, matcher.options.address);187189188 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});190 const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}});189 await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorApproveTimeout: 1});190 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner});191 const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collection.collectionId), {from: matcherOwner});191192192 const seller = privateKeyWrapper(`//Seller/${Date.now()}`);193 await helper.balance.transferToSubstrate(donor, seller.address, 100_000_000_000_000_000_000n);193 await transferBalanceTo(api, alice, seller.address);194 194 195 const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address);195 const token = await collection.mintToken(alice, {Ethereum: sellerMirror});196197 // To transfer item to matcher it first needs to be transfered to EVM account of bob198 await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)});199196200 // Token is owned by seller initially197 // Token is owned by seller initially201 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)});198 expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror});202199203 // Ask200 // Ask204 {201 {205 await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId));202 await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0');206 await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId));203 await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0');207 }204 }208205209 // Token is transferred to matcher206 // Token is transferred to matcher210 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});207 expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()});211208212 // Buy209 // Buy213 {210 {214 const sellerBalanceBeforePurchase = await getBalanceSingle(api, seller.address);211 const sellerBalanceBeforePurchase = await helper.balance.getSubstrate(seller.address);215 await executeEthTxOnSub(web3, api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId), {value: PRICE});212 await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buy(evmCollection.options.address, token.tokenId).encodeABI(), PRICE.toString());216 expect(await getBalanceSingle(api, seller.address) - sellerBalanceBeforePurchase === PRICE);213 expect(await helper.balance.getSubstrate(seller.address) - sellerBalanceBeforePurchase === PRICE);217 }214 }218215219 // Token is transferred to evm account of alice216 // Token is transferred to evm account of alice220 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)});217 expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror});221218222 // Transfer token to substrate side of alice219 // Transfer token to substrate side of alice223 await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address});220 await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address});224221225 // Token is transferred to substrate account of alice, seller received funds222 // Token is transferred to substrate account of alice, seller received funds226 expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address});223 expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address});227 });224 });228});225});229226tests/src/util/playgrounds/unique.tsdiffbeforeafterboth275 }275 }276 276 277 private static extractData(data: any, type: any): any {277 private static extractData(data: any, type: any): any {278 if(!type) return data.toHuman();278 if (['u16', 'u32'].indexOf(type.type) > -1) return data.toNumber();279 if (['u16', 'u32'].indexOf(type.type) > -1) return data.toNumber();279 if (['u64', 'u128', 'u256'].indexOf(type.type) > -1) return data.toBigInt();280 if (['u64', 'u128', 'u256'].indexOf(type.type) > -1) return data.toBigInt();280 if(type.hasOwnProperty('sub')) return this.extractSub(data, type.sub);281 if(type.hasOwnProperty('sub')) return this.extractSub(data, type.sub);