From 1d30029fd67b916adfd725f2a8e6a6b8a29665a4 Mon Sep 17 00:00:00 2001 From: Maksandre Date: Tue, 04 Oct 2022 21:46:18 +0000 Subject: [PATCH] Test: market evm tests to playgrounds --- --- a/tests/src/eth/marketplace/marketplace.test.ts +++ b/tests/src/eth/marketplace/marketplace.test.ts @@ -14,33 +14,47 @@ // You should have received a copy of the GNU General Public License // along with Unique Network. If not, see . +import {usingPlaygrounds} from './../../util/playgrounds/index'; +import {IKeyringPair} from '@polkadot/types/types'; import {readFile} from 'fs/promises'; -import {getBalanceSingle} from '../../substrate/get-balance'; -import { - addToAllowListExpectSuccess, - confirmSponsorshipExpectSuccess, - createCollectionExpectSuccess, - createItemExpectSuccess, - getTokenOwner, - setCollectionLimitsExpectSuccess, - setCollectionSponsorExpectSuccess, - transferExpectSuccess, - transferFromExpectSuccess, - transferBalanceTo, -} from '../../util/helpers'; -import {collectionIdToAddress, contractHelpers, createEthAccountWithBalance, executeEthTxOnSub, GAS_ARGS, itWeb3, SponsoringMode, subToEth, subToEthLowercase, transferBalanceToEth} from '../util/helpers'; -import {evmToAddress} from '@polkadot/util-crypto'; +import {collectionIdToAddress, contractHelpers, GAS_ARGS, SponsoringMode} from '../util/helpers'; import nonFungibleAbi from '../nonFungibleAbi.json'; -import {expect} from 'chai'; +import {itEth, expect} from '../util/playgrounds'; const PRICE = 2000n; describe('Matcher contract usage', () => { - itWeb3('With UNQ', async ({api, web3, privateKeyWrapper}) => { - const alice = privateKeyWrapper('//Alice'); - const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const matcherOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + let donor: IKeyringPair; + let alice: IKeyringPair; + let aliceMirror: string; + let aliceDoubleMirror: string; + let seller: IKeyringPair; + let sellerMirror: string; + + before(async () => { + await usingPlaygrounds(async (_helper, privateKey) => { + donor = privateKey('//Alice'); + }); + }); + + beforeEach(async () => { + await usingPlaygrounds(async (helper, privateKey) => { + [alice] = await helper.arrange.createAccounts([10000n], donor); + aliceMirror = helper.address.substrateToEth(alice.address).toLowerCase(); + aliceDoubleMirror = helper.address.ethToSubstrate(aliceMirror); + seller = privateKey(`//Seller/${Date.now()}`); + sellerMirror = helper.address.substrateToEth(seller.address).toLowerCase(); + + await helper.balance.transferToSubstrate(donor, aliceDoubleMirror, 10_000_000_000_000_000_000n); + }); + }); + + itEth('With UNQ', async ({helper}) => { + const web3 = helper.web3!; + + const sponsor = await helper.eth.createAccountWithBalance(donor); + const matcherOwner = await helper.eth.createAccountWithBalance(donor); const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, { from: matcherOwner, ...GAS_ARGS, @@ -53,59 +67,52 @@ await helpers.methods.setSponsor(matcher.options.address, sponsor).send({from: matcherOwner}); await helpers.methods.confirmSponsorship(matcher.options.address).send({from: sponsor}); - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorApproveTimeout: 1}); - const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner}); - await setCollectionSponsorExpectSuccess(collectionId, alice.address); - await transferBalanceToEth(api, alice, subToEth(alice.address)); - await confirmSponsorshipExpectSuccess(collectionId); - - await helpers.methods.toggleAllowed(matcher.options.address, subToEth(alice.address), true).send({from: matcherOwner}); - await addToAllowListExpectSuccess(alice, collectionId, evmToAddress(subToEth(alice.address))); + const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}, pendingSponsor: alice.address}); + await collection.confirmSponsorship(alice); + await collection.addToAllowList(alice, {Substrate: aliceDoubleMirror}); + const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collection.collectionId), {from: matcherOwner}); + await helper.eth.transferBalanceFromSubstrate(donor, aliceMirror); - const seller = privateKeyWrapper(`//Seller/${Date.now()}`); - await helpers.methods.toggleAllowed(matcher.options.address, subToEth(seller.address), true).send({from: matcherOwner}); - - const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address); + await helpers.methods.toggleAllowed(matcher.options.address, aliceMirror, true).send({from: matcherOwner}); + await helpers.methods.toggleAllowed(matcher.options.address, sellerMirror, true).send({from: matcherOwner}); - // To transfer item to matcher it first needs to be transfered to EVM account of bob - await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)}); + const token = await collection.mintToken(alice, {Ethereum: sellerMirror}); // Token is owned by seller initially - expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)}); + expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror}); // Ask { - await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId)); - await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId)); + await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0'); + await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0'); } // Token is transferred to matcher - expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()}); + expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()}); // Buy { - const sellerBalanceBeforePurchase = await getBalanceSingle(api, seller.address); - await executeEthTxOnSub(web3, api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId), {value: PRICE}); - expect(await getBalanceSingle(api, seller.address) - sellerBalanceBeforePurchase === PRICE); + const sellerBalanceBeforePurchase = await helper.balance.getSubstrate(seller.address); + await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buy(evmCollection.options.address, token.tokenId).encodeABI(), PRICE.toString()); + expect(await helper.balance.getSubstrate(seller.address) - sellerBalanceBeforePurchase === PRICE); } // Token is transferred to evm account of alice - expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)}); + expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror}); // Transfer token to substrate side of alice - await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address}); + await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address}); // Token is transferred to substrate account of alice, seller received funds - expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address}); + expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address}); }); + itEth('With escrow', async ({helper}) => { + const web3 = helper.web3!; - itWeb3('With escrow', async ({api, web3, privateKeyWrapper}) => { - const alice = privateKeyWrapper('//Alice'); - const sponsor = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const matcherOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const escrow = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const sponsor = await helper.eth.createAccountWithBalance(donor); + const matcherOwner = await helper.eth.createAccountWithBalance(donor); + const escrow = await helper.eth.createAccountWithBalance(donor); const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, { from: matcherOwner, ...GAS_ARGS, @@ -119,110 +126,100 @@ await helpers.methods.setSponsor(matcher.options.address, sponsor).send({from: matcherOwner}); await helpers.methods.confirmSponsorship(matcher.options.address).send({from: sponsor}); - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorApproveTimeout: 1}); - const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner}); - await setCollectionSponsorExpectSuccess(collectionId, alice.address); - await transferBalanceToEth(api, alice, subToEth(alice.address)); - await confirmSponsorshipExpectSuccess(collectionId); + const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}, pendingSponsor: alice.address}); + await collection.confirmSponsorship(alice); + await collection.addToAllowList(alice, {Substrate: aliceDoubleMirror}); + const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collection.collectionId), {from: matcherOwner}); + await helper.eth.transferBalanceFromSubstrate(donor, aliceMirror); - await helpers.methods.toggleAllowed(matcher.options.address, subToEth(alice.address), true).send({from: matcherOwner}); - await addToAllowListExpectSuccess(alice, collectionId, evmToAddress(subToEth(alice.address))); - const seller = privateKeyWrapper(`//Seller/${Date.now()}`); - await helpers.methods.toggleAllowed(matcher.options.address, subToEth(seller.address), true).send({from: matcherOwner}); + await helpers.methods.toggleAllowed(matcher.options.address, aliceMirror, true).send({from: matcherOwner}); - const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address); + await helpers.methods.toggleAllowed(matcher.options.address, sellerMirror, true).send({from: matcherOwner}); - // To transfer item to matcher it first needs to be transfered to EVM account of bob - await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)}); + const token = await collection.mintToken(alice, {Ethereum: sellerMirror}); // Token is owned by seller initially - expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)}); + expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror}); // Ask { - await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId)); - await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId)); + await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0'); + await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0'); } // Token is transferred to matcher - expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()}); + expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()}); // Give buyer KSM - await matcher.methods.depositKSM(PRICE, subToEth(alice.address)).send({from: escrow}); + await matcher.methods.depositKSM(PRICE, aliceMirror).send({from: escrow}); // Buy { - expect(await matcher.methods.balanceKSM(subToEth(seller.address)).call()).to.be.equal('0'); - expect(await matcher.methods.balanceKSM(subToEth(alice.address)).call()).to.be.equal(PRICE.toString()); + expect(await matcher.methods.balanceKSM(sellerMirror).call()).to.be.equal('0'); + expect(await matcher.methods.balanceKSM(aliceMirror).call()).to.be.equal(PRICE.toString()); - await executeEthTxOnSub(web3, api, alice, matcher, m => m.buyKSM(evmCollection.options.address, tokenId, subToEth(alice.address), subToEth(alice.address))); + await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buyKSM(evmCollection.options.address, token.tokenId, aliceMirror, aliceMirror).encodeABI(), '0'); // Price is removed from buyer balance, and added to seller - expect(await matcher.methods.balanceKSM(subToEth(alice.address)).call()).to.be.equal('0'); - expect(await matcher.methods.balanceKSM(subToEth(seller.address)).call()).to.be.equal(PRICE.toString()); + expect(await matcher.methods.balanceKSM(aliceMirror).call()).to.be.equal('0'); + expect(await matcher.methods.balanceKSM(sellerMirror).call()).to.be.equal(PRICE.toString()); } // Token is transferred to evm account of alice - expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)}); + expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror}); // Transfer token to substrate side of alice - await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address}); + await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address}); // Token is transferred to substrate account of alice, seller received funds - expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address}); + expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address}); }); + itEth('Sell tokens from substrate user via EVM contract', async ({helper, privateKey}) => { + const web3 = helper.web3!; - itWeb3('Sell tokens from substrate user via EVM contract', async ({api, web3, privateKeyWrapper}) => { - const alice = privateKeyWrapper('//Alice'); - const matcherOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const matcherOwner = await helper.eth.createAccountWithBalance(donor); const matcherContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/MarketPlace.abi`)).toString()), undefined, { from: matcherOwner, ...GAS_ARGS, }); const matcher = await matcherContract.deploy({data: (await readFile(`${__dirname}/MarketPlace.bin`)).toString(), arguments:[matcherOwner]}).send({from: matcherOwner}); - await transferBalanceToEth(api, alice, matcher.options.address); + await helper.eth.transferBalanceFromSubstrate(donor, matcher.options.address); - const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorApproveTimeout: 1}); - const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collectionId), {from: matcherOwner}); + const collection = await helper.nft.mintCollection(alice, {limits: {sponsorApproveTimeout: 1}}); + const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collection.collectionId), {from: matcherOwner}); - const seller = privateKeyWrapper(`//Seller/${Date.now()}`); - await transferBalanceTo(api, alice, seller.address); + await helper.balance.transferToSubstrate(donor, seller.address, 100_000_000_000_000_000_000n); - const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', seller.address); - - // To transfer item to matcher it first needs to be transfered to EVM account of bob - await transferExpectSuccess(collectionId, tokenId, seller, {Ethereum: subToEth(seller.address)}); + const token = await collection.mintToken(alice, {Ethereum: sellerMirror}); // Token is owned by seller initially - expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(seller.address)}); + expect(await token.getOwner()).to.be.deep.equal({Ethereum: sellerMirror}); // Ask { - await executeEthTxOnSub(web3, api, seller, evmCollection, m => m.approve(matcher.options.address, tokenId)); - await executeEthTxOnSub(web3, api, seller, matcher, m => m.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, tokenId)); + await helper.eth.sendEVM(seller, evmCollection.options.address, evmCollection.methods.approve(matcher.options.address, token.tokenId).encodeABI(), '0'); + await helper.eth.sendEVM(seller, matcher.options.address, matcher.methods.addAsk(PRICE, '0x0000000000000000000000000000000000000001', evmCollection.options.address, token.tokenId).encodeABI(), '0'); } // Token is transferred to matcher - expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()}); + expect(await token.getOwner()).to.be.deep.equal({Ethereum: matcher.options.address.toLowerCase()}); // Buy { - const sellerBalanceBeforePurchase = await getBalanceSingle(api, seller.address); - await executeEthTxOnSub(web3, api, alice, matcher, m => m.buy(evmCollection.options.address, tokenId), {value: PRICE}); - expect(await getBalanceSingle(api, seller.address) - sellerBalanceBeforePurchase === PRICE); + const sellerBalanceBeforePurchase = await helper.balance.getSubstrate(seller.address); + await helper.eth.sendEVM(alice, matcher.options.address, matcher.methods.buy(evmCollection.options.address, token.tokenId).encodeABI(), PRICE.toString()); + expect(await helper.balance.getSubstrate(seller.address) - sellerBalanceBeforePurchase === PRICE); } // Token is transferred to evm account of alice - expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Ethereum: subToEthLowercase(alice.address)}); + expect(await token.getOwner()).to.be.deep.equal({Ethereum: aliceMirror}); // Transfer token to substrate side of alice - await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: subToEth(alice.address)}, {Substrate: alice.address}); + await token.transferFrom(alice, {Ethereum: aliceMirror}, {Substrate: alice.address}); // Token is transferred to substrate account of alice, seller received funds - expect(await getTokenOwner(api, collectionId, tokenId)).to.be.deep.equal({Substrate: alice.address}); + expect(await token.getOwner()).to.be.deep.equal({Substrate: alice.address}); }); }); --- a/tests/src/util/playgrounds/unique.ts +++ b/tests/src/util/playgrounds/unique.ts @@ -275,6 +275,7 @@ } private static extractData(data: any, type: any): any { + if(!type) return data.toHuman(); if (['u16', 'u32'].indexOf(type.type) > -1) return data.toNumber(); if (['u64', 'u128', 'u256'].indexOf(type.type) > -1) return data.toBigInt(); if(type.hasOwnProperty('sub')) return this.extractSub(data, type.sub); -- gitstuff