From 3a01a5229f7ab7d4df48abfdecdcfec7696a4963 Mon Sep 17 00:00:00 2001 From: ut-akuznetsov <59873862+ut-akuznetsov@users.noreply.github.com> Date: Tue, 04 Oct 2022 22:33:25 +0000 Subject: [PATCH] Merge pull request #622 from UniqueNetwork/test/playground-migration Test/playground migration --- --- a/tests/src/check-event/burnItemEvent.test.ts +++ b/tests/src/check-event/burnItemEvent.test.ts @@ -15,36 +15,29 @@ // along with Unique Network. If not, see . // https://unique-network.readthedocs.io/en/latest/jsapi.html#setchainlimits -import {ApiPromise} from '@polkadot/api'; import {IKeyringPair} from '@polkadot/types/types'; -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import usingApi, {submitTransactionAsync} from '../substrate/substrate-api'; -import {createCollectionExpectSuccess, createItemExpectSuccess, uniqueEventMessage} from '../util/helpers'; +import {usingPlaygrounds, expect, itSub} from '../util/playgrounds'; +import {IEvent} from '../util/playgrounds/types'; -chai.use(chaiAsPromised); -const expect = chai.expect; describe('Burn Item event ', () => { let alice: IKeyringPair; - const checkSection = 'ItemDestroyed'; - const checkTreasury = 'Deposit'; - const checkSystem = 'ExtrinsicSuccess'; before(async () => { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); + await usingPlaygrounds(async (helper, privateKey) => { + const donor = privateKey('//Alice'); + [alice] = await helper.arrange.createAccounts([10n], donor); }); }); - it('Check event from burnItem(): ', async () => { - await usingApi(async (api: ApiPromise) => { - const collectionID = await createCollectionExpectSuccess(); - const itemID = await createItemExpectSuccess(alice, collectionID, 'NFT'); - const burnItem = api.tx.unique.burnItem(collectionID, itemID, 1); - const events = await submitTransactionAsync(alice, burnItem); - const msg = JSON.stringify(uniqueEventMessage(events)); - expect(msg).to.be.contain(checkSection); - expect(msg).to.be.contain(checkTreasury); - expect(msg).to.be.contain(checkSystem); - }); + itSub('Check event from burnItem(): ', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); + const token = await collection.mintToken(alice, {Substrate: alice.address}); + await token.burn(alice); + + const event = helper.chainLog[helper.chainLog.length - 1].events as IEvent[]; + const eventStrings = event.map(e => `${e.section}.${e.method}`); + + expect(eventStrings).to.contains('common.ItemDestroyed'); + expect(eventStrings).to.contains('treasury.Deposit'); + expect(eventStrings).to.contains('system.ExtrinsicSuccess'); }); }); --- a/tests/src/check-event/createCollectionEvent.test.ts +++ b/tests/src/check-event/createCollectionEvent.test.ts @@ -15,34 +15,25 @@ // along with Unique Network. If not, see . // https://unique-network.readthedocs.io/en/latest/jsapi.html#setchainlimits -import {ApiPromise} from '@polkadot/api'; import {IKeyringPair} from '@polkadot/types/types'; -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import usingApi, {submitTransactionAsync} from '../substrate/substrate-api'; -import {uniqueEventMessage} from '../util/helpers'; - -chai.use(chaiAsPromised); -const expect = chai.expect; +import {usingPlaygrounds, itSub, expect} from '../util/playgrounds'; +import {IEvent} from '../util/playgrounds/types'; describe('Create collection event ', () => { let alice: IKeyringPair; - const checkSection = 'CollectionCreated'; - const checkTreasury = 'Deposit'; - const checkSystem = 'ExtrinsicSuccess'; before(async () => { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); + await usingPlaygrounds(async (helper, privateKey) => { + const donor = privateKey('//Alice'); + [alice] = await helper.arrange.createAccounts([10n], donor); }); }); - it('Check event from createCollection(): ', async () => { - await usingApi(async (api: ApiPromise) => { - const tx = api.tx.unique.createCollectionEx({name: [0x31], description: [0x32], tokenPrefix: '0x33', mode: 'NFT'}); - const events = await submitTransactionAsync(alice, tx); - const msg = JSON.stringify(uniqueEventMessage(events)); - expect(msg).to.be.contain(checkSection); - expect(msg).to.be.contain(checkTreasury); - expect(msg).to.be.contain(checkSystem); - }); + itSub('Check event from createCollection(): ', async ({helper}) => { + await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); + const event = helper.chainLog[helper.chainLog.length - 1].events as IEvent[]; + const eventStrings = event.map(e => `${e.section}.${e.method}`); + + expect(eventStrings).to.contains('common.CollectionCreated'); + expect(eventStrings).to.contains('treasury.Deposit'); + expect(eventStrings).to.contains('system.ExtrinsicSuccess'); }); }); --- a/tests/src/check-event/createItemEvent.test.ts +++ b/tests/src/check-event/createItemEvent.test.ts @@ -15,35 +15,26 @@ // along with Unique Network. If not, see . // https://unique-network.readthedocs.io/en/latest/jsapi.html#setchainlimits -import {ApiPromise} from '@polkadot/api'; import {IKeyringPair} from '@polkadot/types/types'; -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import usingApi, {submitTransactionAsync} from '../substrate/substrate-api'; -import {createCollectionExpectSuccess, uniqueEventMessage, normalizeAccountId} from '../util/helpers'; - -chai.use(chaiAsPromised); -const expect = chai.expect; +import {itSub, usingPlaygrounds, expect} from '../util/playgrounds'; +import {IEvent} from '../util/playgrounds/types'; describe('Create Item event ', () => { let alice: IKeyringPair; - const checkSection = 'ItemCreated'; - const checkTreasury = 'Deposit'; - const checkSystem = 'ExtrinsicSuccess'; before(async () => { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); + await usingPlaygrounds(async (helper, privateKey) => { + const donor = privateKey('//Alice'); + [alice] = await helper.arrange.createAccounts([10n], donor); }); }); - it('Check event from createItem(): ', async () => { - await usingApi(async (api: ApiPromise) => { - const collectionID = await createCollectionExpectSuccess(); - const createItem = api.tx.unique.createItem(collectionID, normalizeAccountId(alice.address), 'NFT'); - const events = await submitTransactionAsync(alice, createItem); - const msg = JSON.stringify(uniqueEventMessage(events)); - expect(msg).to.be.contain(checkSection); - expect(msg).to.be.contain(checkTreasury); - expect(msg).to.be.contain(checkSystem); - }); + itSub('Check event from createItem(): ', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); + await collection.mintToken(alice, {Substrate: alice.address}); + const event = helper.chainLog[helper.chainLog.length - 1].events as IEvent[]; + const eventStrings = event.map(e => `${e.section}.${e.method}`); + + expect(eventStrings).to.contains('common.ItemCreated'); + expect(eventStrings).to.contains('treasury.Deposit'); + expect(eventStrings).to.contains('system.ExtrinsicSuccess'); }); }); --- a/tests/src/check-event/createMultipleItemsEvent.test.ts +++ b/tests/src/check-event/createMultipleItemsEvent.test.ts @@ -15,36 +15,31 @@ // along with Unique Network. If not, see . // https://unique-network.readthedocs.io/en/latest/jsapi.html#setchainlimits -import {ApiPromise} from '@polkadot/api'; import {IKeyringPair} from '@polkadot/types/types'; -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import usingApi, {submitTransactionAsync} from '../substrate/substrate-api'; -import {createCollectionExpectSuccess, uniqueEventMessage, normalizeAccountId} from '../util/helpers'; - -chai.use(chaiAsPromised); -const expect = chai.expect; +import {usingPlaygrounds, itSub, expect} from '../util/playgrounds'; +import {IEvent} from '../util/playgrounds/types'; describe('Create Multiple Items Event event ', () => { let alice: IKeyringPair; - const checkSection = 'ItemCreated'; - const checkTreasury = 'Deposit'; - const checkSystem = 'ExtrinsicSuccess'; before(async () => { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); + await usingPlaygrounds(async (helper, privateKey) => { + const donor = privateKey('//Alice'); + [alice] = await helper.arrange.createAccounts([10n], donor); }); }); - it('Check event from createMultipleItems(): ', async () => { - await usingApi(async (api: ApiPromise) => { - const collectionID = await createCollectionExpectSuccess(); - const args = [{NFT: {}}, {NFT: {}}, {NFT: {}}]; - const createMultipleItems = api.tx.unique.createMultipleItems(collectionID, normalizeAccountId(alice.address), args); - const events = await submitTransactionAsync(alice, createMultipleItems); - const msg = JSON.stringify(uniqueEventMessage(events)); - expect(msg).to.be.contain(checkSection); - expect(msg).to.be.contain(checkTreasury); - expect(msg).to.be.contain(checkSystem); - }); + itSub('Check event from createMultipleItems(): ', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); + + await collection.mintMultipleTokens(alice, [ + {owner: {Substrate: alice.address}}, + {owner: {Substrate: alice.address}}, + ]); + + const event = helper.chainLog[helper.chainLog.length - 1].events as IEvent[]; + const eventStrings = event.map(e => `${e.section}.${e.method}`); + + expect(eventStrings).to.contains('common.ItemCreated'); + expect(eventStrings).to.contains('treasury.Deposit'); + expect(eventStrings).to.contains('system.ExtrinsicSuccess'); }); }); --- a/tests/src/check-event/destroyCollectionEvent.test.ts +++ b/tests/src/check-event/destroyCollectionEvent.test.ts @@ -15,33 +15,27 @@ // along with Unique Network. If not, see . // https://unique-network.readthedocs.io/en/latest/jsapi.html#setchainlimits -import {ApiPromise} from '@polkadot/api'; import {IKeyringPair} from '@polkadot/types/types'; -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import usingApi, {submitTransactionAsync} from '../substrate/substrate-api'; -import {createCollectionExpectSuccess, uniqueEventMessage} from '../util/helpers'; - -chai.use(chaiAsPromised); -const expect = chai.expect; +import {itSub, usingPlaygrounds, expect} from '../util/playgrounds'; +import {IEvent} from '../util/playgrounds/types'; describe('Destroy collection event ', () => { let alice: IKeyringPair; - const checkTreasury = 'Deposit'; - const checkSystem = 'ExtrinsicSuccess'; before(async () => { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); + await usingPlaygrounds(async (helper, privateKey) => { + const donor = privateKey('//Alice'); + [alice] = await helper.arrange.createAccounts([10n], donor); }); }); - it('Check event from destroyCollection(): ', async () => { - await usingApi(async (api: ApiPromise) => { - const collectionID = await createCollectionExpectSuccess(); - const destroyCollection = api.tx.unique.destroyCollection(collectionID); - const events = await submitTransactionAsync(alice, destroyCollection); - const msg = JSON.stringify(uniqueEventMessage(events)); - expect(msg).to.be.contain(checkTreasury); - expect(msg).to.be.contain(checkSystem); - }); + + itSub('Check event from destroyCollection(): ', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); + await collection.burn(alice); + const event = helper.chainLog[helper.chainLog.length - 1].events as IEvent[]; + const eventStrings = event.map(e => `${e.section}.${e.method}`); + + expect(eventStrings).to.contains('common.CollectionDestroyed'); + expect(eventStrings).to.contains('treasury.Deposit'); + expect(eventStrings).to.contains('system.ExtrinsicSuccess'); }); }); --- a/tests/src/check-event/transferEvent.test.ts +++ b/tests/src/check-event/transferEvent.test.ts @@ -15,38 +15,30 @@ // along with Unique Network. If not, see . // https://unique-network.readthedocs.io/en/latest/jsapi.html#setchainlimits -import {ApiPromise} from '@polkadot/api'; import {IKeyringPair} from '@polkadot/types/types'; -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import usingApi, {submitTransactionAsync} from '../substrate/substrate-api'; -import {createCollectionExpectSuccess, createItemExpectSuccess, uniqueEventMessage, normalizeAccountId} from '../util/helpers'; - -chai.use(chaiAsPromised); -const expect = chai.expect; +import {usingPlaygrounds, expect, itSub} from '../util/playgrounds'; +import {IEvent} from '../util/playgrounds/types'; describe('Transfer event ', () => { let alice: IKeyringPair; let bob: IKeyringPair; - const checkSection = 'Transfer'; - const checkTreasury = 'Deposit'; - const checkSystem = 'ExtrinsicSuccess'; + before(async () => { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); - bob = privateKeyWrapper('//Bob'); + await usingPlaygrounds(async (helper, privateKey) => { + const donor = privateKey('//Alice'); + [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor); }); }); - it('Check event from transfer(): ', async () => { - await usingApi(async (api: ApiPromise) => { - const collectionID = await createCollectionExpectSuccess(); - const itemID = await createItemExpectSuccess(alice, collectionID, 'NFT'); - const transfer = api.tx.unique.transfer(normalizeAccountId(bob.address), collectionID, itemID, 1); - const events = await submitTransactionAsync(alice, transfer); - const msg = JSON.stringify(uniqueEventMessage(events)); - expect(msg).to.be.contain(checkSection); - expect(msg).to.be.contain(checkTreasury); - expect(msg).to.be.contain(checkSystem); - }); + + itSub('Check event from transfer(): ', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); + const token = await collection.mintToken(alice, {Substrate: alice.address}); + await token.transfer(alice, {Substrate: bob.address}); + const event = helper.chainLog[helper.chainLog.length - 1].events as IEvent[]; + const eventStrings = event.map(e => `${e.section}.${e.method}`); + + expect(eventStrings).to.contains('common.Transfer'); + expect(eventStrings).to.contains('treasury.Deposit'); + expect(eventStrings).to.contains('system.ExtrinsicSuccess'); }); }); --- a/tests/src/check-event/transferFromEvent.test.ts +++ b/tests/src/check-event/transferFromEvent.test.ts @@ -15,38 +15,29 @@ // along with Unique Network. If not, see . // https://unique-network.readthedocs.io/en/latest/jsapi.html#setchainlimits -import {ApiPromise} from '@polkadot/api'; import {IKeyringPair} from '@polkadot/types/types'; -import chai from 'chai'; -import chaiAsPromised from 'chai-as-promised'; -import usingApi, {submitTransactionAsync} from '../substrate/substrate-api'; -import {createCollectionExpectSuccess, createItemExpectSuccess, uniqueEventMessage, normalizeAccountId} from '../util/helpers'; - -chai.use(chaiAsPromised); -const expect = chai.expect; +import {usingPlaygrounds, expect, itSub} from '../util/playgrounds'; +import {IEvent} from '../util/playgrounds/types'; -describe('Transfer from event ', () => { +describe('Transfer event ', () => { let alice: IKeyringPair; let bob: IKeyringPair; - const checkSection = 'Transfer'; - const checkTreasury = 'Deposit'; - const checkSystem = 'ExtrinsicSuccess'; before(async () => { - await usingApi(async (api, privateKeyWrapper) => { - alice = privateKeyWrapper('//Alice'); - bob = privateKeyWrapper('//Bob'); + await usingPlaygrounds(async (helper, privateKey) => { + const donor = privateKey('//Alice'); + [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor); }); }); - it('Check event from transferFrom(): ', async () => { - await usingApi(async (api: ApiPromise) => { - const collectionID = await createCollectionExpectSuccess(); - const itemID = await createItemExpectSuccess(alice, collectionID, 'NFT'); - const transferFrom = api.tx.unique.transferFrom(normalizeAccountId(alice.address), normalizeAccountId(bob.address), collectionID, itemID, 1); - const events = await submitTransactionAsync(alice, transferFrom); - const msg = JSON.stringify(uniqueEventMessage(events)); - expect(msg).to.be.contain(checkSection); - expect(msg).to.be.contain(checkTreasury); - expect(msg).to.be.contain(checkSystem); - }); + + itSub('Check event from transfer(): ', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); + const token = await collection.mintToken(alice, {Substrate: alice.address}); + await token.transferFrom(alice, {Substrate: alice.address}, {Substrate: bob.address}); + const event = helper.chainLog[helper.chainLog.length - 1].events as IEvent[]; + const eventStrings = event.map(e => `${e.section}.${e.method}`); + + expect(eventStrings).to.contains('common.Transfer'); + expect(eventStrings).to.contains('treasury.Deposit'); + expect(eventStrings).to.contains('system.ExtrinsicSuccess'); }); }); --- a/tests/src/eth/allowlist.test.ts +++ b/tests/src/eth/allowlist.test.ts @@ -15,26 +15,21 @@ // along with Unique Network. If not, see . import {IKeyringPair} from '@polkadot/types/types'; -import {expect} from 'chai'; -import {isAllowlisted, normalizeAccountId} from '../util/helpers'; -import { - contractHelpers, - createEthAccount, - createEthAccountWithBalance, - deployFlipper, - evmCollection, - evmCollectionHelpers, - getCollectionAddressFromResult, - itWeb3, -} from './util/helpers'; -import {itEth, usingEthPlaygrounds} from './util/playgrounds'; +import {itEth, usingEthPlaygrounds, expect} from './util/playgrounds'; describe('EVM contract allowlist', () => { - itWeb3('Contract allowlist can be toggled', async ({api, web3, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const flipper = await deployFlipper(web3, owner); + let donor: IKeyringPair; + + before(async function() { + await usingEthPlaygrounds(async (_helper, privateKey) => { + donor = privateKey('//Alice'); + }); + }); - const helpers = contractHelpers(web3, owner); + itEth('Contract allowlist can be toggled', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const flipper = await helper.eth.deployFlipper(owner); + const helpers = helper.ethNativeContract.contractHelpers(owner); // Any user is allowed by default expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.false; @@ -48,12 +43,11 @@ expect(await helpers.methods.allowlistEnabled(flipper.options.address).call()).to.be.false; }); - itWeb3('Non-allowlisted user can\'t call contract with allowlist enabled', async ({api, web3, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const flipper = await deployFlipper(web3, owner); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - - const helpers = contractHelpers(web3, owner); + itEth('Non-allowlisted user can\'t call contract with allowlist enabled', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const caller = await helper.eth.createAccountWithBalance(donor); + const flipper = await helper.eth.deployFlipper(owner); + const helpers = helper.ethNativeContract.contractHelpers(owner); // User can flip with allowlist disabled await flipper.methods.flip().send({from: caller}); @@ -79,18 +73,18 @@ donor = privateKey('//Alice'); }); }); - + itEth('Collection allowlist can be added and removed by [eth] address', async ({helper}) => { const owner = await helper.eth.createAccountWithBalance(donor); const user = helper.eth.createAccount(); - + const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); - + expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false; await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner}); expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true; - + await collectionEvm.methods.removeFromCollectionAllowList(user).send({from: owner}); expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false; }); @@ -99,14 +93,14 @@ // itEth('Collection allowlist can be added and removed by [sub] address', async ({helper}) => { // const owner = await helper.eth.createAccountWithBalance(donor); // const user = donor; - + // const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); // const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); - + // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false; // await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner}); // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true; - + // await collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).send({from: owner}); // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false; // }); @@ -115,15 +109,15 @@ const owner = await helper.eth.createAccountWithBalance(donor); const notOwner = await helper.eth.createAccountWithBalance(donor); const user = helper.eth.createAccount(); - + const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); - + expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false; await expect(collectionEvm.methods.addToCollectionAllowList(user).call({from: notOwner})).to.be.rejectedWith('NoPermission'); expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.false; await collectionEvm.methods.addToCollectionAllowList(user).send({from: owner}); - + expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true; await expect(collectionEvm.methods.removeFromCollectionAllowList(user).call({from: notOwner})).to.be.rejectedWith('NoPermission'); expect(await collectionEvm.methods.allowed(user).call({from: owner})).to.be.true; @@ -134,15 +128,15 @@ // const owner = await helper.eth.createAccountWithBalance(donor); // const notOwner = await helper.eth.createAccountWithBalance(donor); // const user = donor; - + // const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); // const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); - + // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false; // await expect(collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission'); // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.false; // await collectionEvm.methods.addToCollectionAllowListSubstrate(user.addressRaw).send({from: owner}); - + // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true; // await expect(collectionEvm.methods.removeFromCollectionAllowListSubstrate(user.addressRaw).call({from: notOwner})).to.be.rejectedWith('NoPermission'); // expect(await helper.collection.allowed(collectionId, {Substrate: user.address})).to.be.true; --- a/tests/src/eth/base.test.ts +++ b/tests/src/eth/base.test.ts @@ -15,56 +15,54 @@ // along with Unique Network. If not, see . import { - collectionIdToAddress, - createEthAccount, - createEthAccountWithBalance, - deployFlipper, ethBalanceViaSub, GAS_ARGS, - itWeb3, recordEthFee, - usingWeb3, } from './util/helpers'; -import {expect} from 'chai'; -import {createCollectionExpectSuccess, createItemExpectSuccess, UNIQUE} from '../util/helpers'; -import nonFungibleAbi from './nonFungibleAbi.json'; import {Contract} from 'web3-eth-contract'; -import Web3 from 'web3'; +import {IKeyringPair} from '@polkadot/types/types'; +import {EthUniqueHelper, itEth, usingEthPlaygrounds, expect} from './util/playgrounds'; + describe('Contract calls', () => { - itWeb3('Call of simple contract fee is less than 0.2 UNQ', async ({web3, api, privateKeyWrapper}) => { - const deployer = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const flipper = await deployFlipper(web3, deployer); + let donor: IKeyringPair; - const cost = await recordEthFee(api, deployer, () => flipper.methods.flip().send({from: deployer})); - expect(cost < BigInt(0.2 * Number(UNIQUE))).to.be.true; + before(async function() { + await usingEthPlaygrounds(async (_helper, privateKey) => { + donor = privateKey('//Alice'); + }); }); - itWeb3('Balance transfer fee is less than 0.2 UNQ', async ({web3, api, privateKeyWrapper}) => { - const userA = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const userB = createEthAccount(web3); + itEth('Call of simple contract fee is less than 0.2 UNQ', async ({helper}) => { + const deployer = await helper.eth.createAccountWithBalance(donor); + const flipper = await helper.eth.deployFlipper(deployer); + + const cost = await recordEthFee(helper.api!, deployer, () => flipper.methods.flip().send({from: deployer})); + expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal()))).to.be.true; + }); - const cost = await recordEthFee(api, userA, () => web3.eth.sendTransaction({from: userA, to: userB, value: '1000000', ...GAS_ARGS})); - const balanceB = await ethBalanceViaSub(api, userB); - expect(cost - balanceB < BigInt(0.2 * Number(UNIQUE))).to.be.true; + itEth('Balance transfer fee is less than 0.2 UNQ', async ({helper}) => { + const userA = await helper.eth.createAccountWithBalance(donor); + const userB = helper.eth.createAccount(); + const cost = await recordEthFee(helper.api!, userA, () => helper.web3!.eth.sendTransaction({from: userA, to: userB, value: '1000000', ...GAS_ARGS})); + const balanceB = await ethBalanceViaSub(helper.api!, userB); + expect(cost - balanceB < BigInt(0.2 * Number(helper.balance.getOneTokenNominal()))).to.be.true; }); - itWeb3('NFT transfer is close to 0.15 UNQ', async ({web3, api, privateKeyWrapper}) => { - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const receiver = createEthAccount(web3); + itEth('NFT transfer is close to 0.15 UNQ', async ({helper}) => { + const caller = await helper.eth.createAccountWithBalance(donor); + const receiver = helper.eth.createAccount(); - const alice = privateKeyWrapper('//Alice'); - const collection = await createCollectionExpectSuccess({ - mode: {type: 'NFT'}, - }); - const itemId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller}); + const [alice] = await helper.arrange.createAccounts([10n], donor); + const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); + const {tokenId} = await collection.mintToken(alice, {Ethereum: caller}); - const address = collectionIdToAddress(collection); - const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const contract = helper.ethNativeContract.collection(address, 'nft', caller); - const cost = await recordEthFee(api, caller, () => contract.methods.transfer(receiver, itemId).send(caller)); + const cost = await recordEthFee(helper.api!, caller, () => contract.methods.transfer(receiver, tokenId).send(caller)); - const fee = Number(cost) / Number(UNIQUE); + const fee = Number(cost) / Number(helper.balance.getOneTokenNominal()); const expectedFee = 0.15; const tolerance = 0.001; @@ -78,46 +76,48 @@ let collection: number; let minter: string; - function contract(web3: Web3): Contract { - return new web3.eth.Contract(nonFungibleAbi as any, collectionIdToAddress(collection), {from: minter, ...GAS_ARGS}); + function contract(helper: EthUniqueHelper): Contract { + return helper.ethNativeContract.collection(helper.ethAddress.fromCollectionId(collection), 'nft', minter); } before(async () => { - await usingWeb3 (async (web3) => { - collection = await createCollectionExpectSuccess(); - minter = createEthAccount(web3); + await usingEthPlaygrounds(async (helper, privateKey) => { + const donor = privateKey('//Alice'); + const [alice] = await helper.arrange.createAccounts([10n], donor); + ({collectionId: collection} = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'})); + minter = helper.eth.createAccount(); }); }); - itWeb3('interfaceID == 0xffffffff always false', async ({web3}) => { - expect(await contract(web3).methods.supportsInterface('0xffffffff').call()).to.be.false; + itEth('interfaceID == 0xffffffff always false', async ({helper}) => { + expect(await contract(helper).methods.supportsInterface('0xffffffff').call()).to.be.false; }); - itWeb3('ERC721 support', async ({web3}) => { - expect(await contract(web3).methods.supportsInterface('0x780e9d63').call()).to.be.true; + itEth('ERC721 support', async ({helper}) => { + expect(await contract(helper).methods.supportsInterface('0x780e9d63').call()).to.be.true; }); - itWeb3('ERC721Metadata support', async ({web3}) => { - expect(await contract(web3).methods.supportsInterface('0x5b5e139f').call()).to.be.true; + itEth('ERC721Metadata support', async ({helper}) => { + expect(await contract(helper).methods.supportsInterface('0x5b5e139f').call()).to.be.true; }); - itWeb3('ERC721Mintable support', async ({web3}) => { - expect(await contract(web3).methods.supportsInterface('0x68ccfe89').call()).to.be.true; + itEth('ERC721Mintable support', async ({helper}) => { + expect(await contract(helper).methods.supportsInterface('0x68ccfe89').call()).to.be.true; }); - itWeb3('ERC721Enumerable support', async ({web3}) => { - expect(await contract(web3).methods.supportsInterface('0x780e9d63').call()).to.be.true; + itEth('ERC721Enumerable support', async ({helper}) => { + expect(await contract(helper).methods.supportsInterface('0x780e9d63').call()).to.be.true; }); - itWeb3('ERC721UniqueExtensions support', async ({web3}) => { - expect(await contract(web3).methods.supportsInterface('0xd74d154f').call()).to.be.true; + itEth('ERC721UniqueExtensions support', async ({helper}) => { + expect(await contract(helper).methods.supportsInterface('0xd74d154f').call()).to.be.true; }); - itWeb3('ERC721Burnable support', async ({web3}) => { - expect(await contract(web3).methods.supportsInterface('0x42966c68').call()).to.be.true; + itEth('ERC721Burnable support', async ({helper}) => { + expect(await contract(helper).methods.supportsInterface('0x42966c68').call()).to.be.true; }); - itWeb3('ERC165 support', async ({web3}) => { - expect(await contract(web3).methods.supportsInterface('0x01ffc9a7').call()).to.be.true; + itEth('ERC165 support', async ({helper}) => { + expect(await contract(helper).methods.supportsInterface('0x01ffc9a7').call()).to.be.true; }); }); --- a/tests/src/eth/collectionAdmin.test.ts +++ b/tests/src/eth/collectionAdmin.test.ts @@ -13,229 +13,194 @@ // You should have received a copy of the GNU General Public License // along with Unique Network. If not, see . -import {expect} from 'chai'; -import privateKey from '../substrate/privateKey'; -import {UNIQUE} from '../util/helpers'; -import { - createEthAccount, - createEthAccountWithBalance, - evmCollection, - evmCollectionHelpers, - getCollectionAddressFromResult, - itWeb3, - recordEthFee, -} from './util/helpers'; +import {IKeyringPair} from '@polkadot/types/types'; +import {usingEthPlaygrounds, itEth, expect, EthUniqueHelper} from './util/playgrounds'; +async function recordEthFee(helper: EthUniqueHelper, userAddress: string, call: () => Promise) { + const before = await helper.balance.getSubstrate(helper.address.ethToSubstrate(userAddress)); + await call(); + await helper.wait.newBlocks(1); + const after = await helper.balance.getSubstrate(helper.address.ethToSubstrate(userAddress)); + + expect(after < before).to.be.true; + + return before - after; +} + describe('Add collection admins', () => { - itWeb3('Add admin by owner', async ({api, web3, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionHelper = evmCollectionHelpers(web3, owner); + let donor: IKeyringPair; + + before(async function() { + await usingEthPlaygrounds(async (_helper, privateKey) => { + donor = privateKey('//Alice'); + }); + }); + + itEth('Add admin by owner', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); - const result = await collectionHelper.methods - .createNonfungibleCollection('A', 'B', 'C') - .send({value: Number(2n * UNIQUE)}); - const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + const newAdmin = helper.eth.createAccount(); - const newAdmin = createEthAccount(web3); - const collectionEvm = evmCollection(web3, owner, collectionIdAddress); await collectionEvm.methods.addCollectionAdmin(newAdmin).send(); - const adminList = await api.rpc.unique.adminlist(collectionId); + const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); expect(adminList[0].asEthereum.toString().toLocaleLowerCase()) .to.be.eq(newAdmin.toLocaleLowerCase()); }); - // TODO: Temprorary off. Need refactor - // itWeb3('Add substrate admin by owner', async ({api, web3, privateKeyWrapper}) => { - // const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - // const collectionHelper = evmCollectionHelpers(web3, owner); - - // const result = await collectionHelper.methods - // .createNonfungibleCollection('A', 'B', 'C') - // .send(); - // const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + itEth.skip('Add substrate admin by owner', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + + const [newAdmin] = await helper.arrange.createAccounts([10n], donor); + await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send(); - // const newAdmin = privateKeyWrapper('//Alice'); - // const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - // await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send(); + const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); + expect(adminList[0].asSubstrate.toString().toLocaleLowerCase()) + .to.be.eq(newAdmin.address.toLocaleLowerCase()); + }); - // const adminList = await api.rpc.unique.adminlist(collectionId); - // expect(adminList[0].asSubstrate.toString().toLocaleLowerCase()) - // .to.be.eq(newAdmin.address.toLocaleLowerCase()); - // }); - - itWeb3('Verify owner or admin', async ({api, web3, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionHelper = evmCollectionHelpers(web3, owner); - - const result = await collectionHelper.methods - .createNonfungibleCollection('A', 'B', 'C') - .send({value: Number(2n * UNIQUE)}); - const {collectionIdAddress} = await getCollectionAddressFromResult(api, result); + itEth('Verify owner or admin', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); - const newAdmin = createEthAccount(web3); - const collectionEvm = evmCollection(web3, owner, collectionIdAddress); + const newAdmin = helper.eth.createAccount(); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.false; await collectionEvm.methods.addCollectionAdmin(newAdmin).send(); expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.true; }); - itWeb3('(!negative tests!) Add admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionHelper = evmCollectionHelpers(web3, owner); - - const result = await collectionHelper.methods - .createNonfungibleCollection('A', 'B', 'C') - .send({value: Number(2n * UNIQUE)}); - const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + itEth('(!negative tests!) Add admin by ADMIN is not allowed', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); - const admin = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionEvm = evmCollection(web3, owner, collectionIdAddress); + const admin = await helper.eth.createAccountWithBalance(donor); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); await collectionEvm.methods.addCollectionAdmin(admin).send(); - - const user = createEthAccount(web3); + + const user = helper.eth.createAccount(); await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: admin})) .to.be.rejectedWith('NoPermission'); - const adminList = await api.rpc.unique.adminlist(collectionId); + const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); expect(adminList.length).to.be.eq(1); expect(adminList[0].asEthereum.toString().toLocaleLowerCase()) .to.be.eq(admin.toLocaleLowerCase()); }); - itWeb3('(!negative tests!) Add admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionHelper = evmCollectionHelpers(web3, owner); - - const result = await collectionHelper.methods - .createNonfungibleCollection('A', 'B', 'C') - .send({value: Number(2n * UNIQUE)}); - const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + itEth('(!negative tests!) Add admin by USER is not allowed', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); + + const notAdmin = await helper.eth.createAccountWithBalance(donor); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); - const notAdmin = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - - const user = createEthAccount(web3); + const user = helper.eth.createAccount(); await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: notAdmin})) .to.be.rejectedWith('NoPermission'); - const adminList = await api.rpc.unique.adminlist(collectionId); + const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); expect(adminList.length).to.be.eq(0); }); - // TODO: Temprorary off. Need refactor - // itWeb3('(!negative tests!) Add substrate admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => { - // const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - // const collectionHelper = evmCollectionHelpers(web3, owner); - - // const result = await collectionHelper.methods - // .createNonfungibleCollection('A', 'B', 'C') - // .send(); - // const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + itEth.skip('(!negative tests!) Add substrate admin by ADMIN is not allowed', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); + + const admin = await helper.eth.createAccountWithBalance(donor); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + await collectionEvm.methods.addCollectionAdmin(admin).send(); - // const admin = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - // const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - // await collectionEvm.methods.addCollectionAdmin(admin).send(); + const [notAdmin] = await helper.arrange.createAccounts([10n], donor); + await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin.addressRaw).call({from: admin})) + .to.be.rejectedWith('NoPermission'); - // const notAdmin = privateKey('//Alice'); - // await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin.addressRaw).call({from: admin})) - // .to.be.rejectedWith('NoPermission'); + const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); + expect(adminList.length).to.be.eq(1); + expect(adminList[0].asEthereum.toString().toLocaleLowerCase()) + .to.be.eq(admin.toLocaleLowerCase()); + }); - // const adminList = await api.rpc.unique.adminlist(collectionId); - // expect(adminList.length).to.be.eq(1); - // expect(adminList[0].asEthereum.toString().toLocaleLowerCase()) - // .to.be.eq(admin.toLocaleLowerCase()); - // }); - - // TODO: Temprorary off. Need refactor - // itWeb3('(!negative tests!) Add substrate admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => { - // const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - // const collectionHelper = evmCollectionHelpers(web3, owner); - - // const result = await collectionHelper.methods - // .createNonfungibleCollection('A', 'B', 'C') - // .send(); - // const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + itEth.skip('(!negative tests!) Add substrate admin by USER is not allowed', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); - // const notAdmin0 = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - // const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - // const notAdmin1 = privateKey('//Alice'); - // await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin1.addressRaw).call({from: notAdmin0})) - // .to.be.rejectedWith('NoPermission'); + const notAdmin0 = await helper.eth.createAccountWithBalance(donor); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + const [notAdmin1] = await helper.arrange.createAccounts([10n], donor); + await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin1.addressRaw).call({from: notAdmin0})) + .to.be.rejectedWith('NoPermission'); - // const adminList = await api.rpc.unique.adminlist(collectionId); - // expect(adminList.length).to.be.eq(0); - // }); + const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); + expect(adminList.length).to.be.eq(0); + }); }); describe('Remove collection admins', () => { - itWeb3('Remove admin by owner', async ({api, web3, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionHelper = evmCollectionHelpers(web3, owner); - - const result = await collectionHelper.methods - .createNonfungibleCollection('A', 'B', 'C') - .send({value: Number(2n * UNIQUE)}); - const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + let donor: IKeyringPair; - const newAdmin = createEthAccount(web3); - const collectionEvm = evmCollection(web3, owner, collectionIdAddress); + before(async function() { + await usingEthPlaygrounds(async (_helper, privateKey) => { + donor = privateKey('//Alice'); + }); + }); + + itEth('Remove admin by owner', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); + + const newAdmin = helper.eth.createAccount(); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); await collectionEvm.methods.addCollectionAdmin(newAdmin).send(); + { - const adminList = await api.rpc.unique.adminlist(collectionId); + const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); expect(adminList.length).to.be.eq(1); expect(adminList[0].asEthereum.toString().toLocaleLowerCase()) .to.be.eq(newAdmin.toLocaleLowerCase()); } await collectionEvm.methods.removeCollectionAdmin(newAdmin).send(); - const adminList = await api.rpc.unique.adminlist(collectionId); + const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); expect(adminList.length).to.be.eq(0); }); - // TODO: Temprorary off. Need refactor - // itWeb3('Remove substrate admin by owner', async ({api, web3, privateKeyWrapper}) => { - // const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - // const collectionHelper = evmCollectionHelpers(web3, owner); - - // const result = await collectionHelper.methods - // .createNonfungibleCollection('A', 'B', 'C') - // .send(); - // const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + itEth.skip('Remove substrate admin by owner', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); + + const [newAdmin] = await helper.arrange.createAccounts([10n], donor); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send(); + { + const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); + expect(adminList[0].asSubstrate.toString().toLocaleLowerCase()) + .to.be.eq(newAdmin.address.toLocaleLowerCase()); + } - // const newAdmin = privateKeyWrapper('//Alice'); - // const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - // await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send(); - // { - // const adminList = await api.rpc.unique.adminlist(collectionId); - // expect(adminList[0].asSubstrate.toString().toLocaleLowerCase()) - // .to.be.eq(newAdmin.address.toLocaleLowerCase()); - // } - - // await collectionEvm.methods.removeCollectionAdminSubstrate(newAdmin.addressRaw).send(); - // const adminList = await api.rpc.unique.adminlist(collectionId); - // expect(adminList.length).to.be.eq(0); - // }); + await collectionEvm.methods.removeCollectionAdminSubstrate(newAdmin.addressRaw).send(); + const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); + expect(adminList.length).to.be.eq(0); + }); - itWeb3('(!negative tests!) Remove admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionHelper = evmCollectionHelpers(web3, owner); - - const result = await collectionHelper.methods - .createNonfungibleCollection('A', 'B', 'C') - .send({value: Number(2n * UNIQUE)}); - const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + itEth('(!negative tests!) Remove admin by ADMIN is not allowed', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); - const collectionEvm = evmCollection(web3, owner, collectionIdAddress); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); - const admin0 = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const admin0 = await helper.eth.createAccountWithBalance(donor); await collectionEvm.methods.addCollectionAdmin(admin0).send(); - const admin1 = createEthAccount(web3); + const admin1 = await helper.eth.createAccountWithBalance(donor); await collectionEvm.methods.addCollectionAdmin(admin1).send(); await expect(collectionEvm.methods.removeCollectionAdmin(admin1).call({from: admin0})) .to.be.rejectedWith('NoPermission'); { - const adminList = await api.rpc.unique.adminlist(collectionId); + const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); expect(adminList.length).to.be.eq(2); expect(adminList.toString().toLocaleLowerCase()) .to.be.deep.contains(admin0.toLocaleLowerCase()) @@ -243,179 +208,150 @@ } }); - itWeb3('(!negative tests!) Remove admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionHelper = evmCollectionHelpers(web3, owner); - - const result = await collectionHelper.methods - .createNonfungibleCollection('A', 'B', 'C') - .send({value: Number(2n * UNIQUE)}); - const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + itEth('(!negative tests!) Remove admin by USER is not allowed', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); - const collectionEvm = evmCollection(web3, owner, collectionIdAddress); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); - const admin = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const admin = await helper.eth.createAccountWithBalance(donor); await collectionEvm.methods.addCollectionAdmin(admin).send(); - const notAdmin = createEthAccount(web3); + const notAdmin = helper.eth.createAccount(); await expect(collectionEvm.methods.removeCollectionAdmin(admin).call({from: notAdmin})) .to.be.rejectedWith('NoPermission'); { - const adminList = await api.rpc.unique.adminlist(collectionId); + const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); expect(adminList[0].asEthereum.toString().toLocaleLowerCase()) .to.be.eq(admin.toLocaleLowerCase()); expect(adminList.length).to.be.eq(1); } }); - // TODO: Temprorary off. Need refactor - // itWeb3('(!negative tests!) Remove substrate admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => { - // const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - // const collectionHelper = evmCollectionHelpers(web3, owner); - - // const result = await collectionHelper.methods - // .createNonfungibleCollection('A', 'B', 'C') - // .send(); - // const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + itEth.skip('(!negative tests!) Remove substrate admin by ADMIN is not allowed', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); - // const adminSub = privateKeyWrapper('//Alice'); - // const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - // await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send(); - // const adminEth = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - // await collectionEvm.methods.addCollectionAdmin(adminEth).send(); + const [adminSub] = await helper.arrange.createAccounts([10n], donor); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send(); + const adminEth = await helper.eth.createAccountWithBalance(donor); + await collectionEvm.methods.addCollectionAdmin(adminEth).send(); - // await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: adminEth})) - // .to.be.rejectedWith('NoPermission'); + await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: adminEth})) + .to.be.rejectedWith('NoPermission'); - // const adminList = await api.rpc.unique.adminlist(collectionId); - // expect(adminList.length).to.be.eq(2); - // expect(adminList.toString().toLocaleLowerCase()) - // .to.be.deep.contains(adminSub.address.toLocaleLowerCase()) - // .to.be.deep.contains(adminEth.toLocaleLowerCase()); - // }); + const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); + expect(adminList.length).to.be.eq(2); + expect(adminList.toString().toLocaleLowerCase()) + .to.be.deep.contains(adminSub.address.toLocaleLowerCase()) + .to.be.deep.contains(adminEth.toLocaleLowerCase()); + }); - // TODO: Temprorary off. Need refactor - // itWeb3('(!negative tests!) Remove substrate admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => { - // const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - // const collectionHelper = evmCollectionHelpers(web3, owner); - - // const result = await collectionHelper.methods - // .createNonfungibleCollection('A', 'B', 'C') - // .send(); - // const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result); + itEth.skip('(!negative tests!) Remove substrate admin by USER is not allowed', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress, collectionId} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); - // const adminSub = privateKeyWrapper('//Alice'); - // const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - // await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send(); - // const notAdminEth = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const [adminSub] = await helper.arrange.createAccounts([10n], donor); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send(); + const notAdminEth = await helper.eth.createAccountWithBalance(donor); - // await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: notAdminEth})) - // .to.be.rejectedWith('NoPermission'); + await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: notAdminEth})) + .to.be.rejectedWith('NoPermission'); - // const adminList = await api.rpc.unique.adminlist(collectionId); - // expect(adminList.length).to.be.eq(1); - // expect(adminList[0].asSubstrate.toString().toLocaleLowerCase()) - // .to.be.eq(adminSub.address.toLocaleLowerCase()); - // }); + const adminList = await helper.callRpc('api.rpc.unique.adminlist', [collectionId]); + expect(adminList.length).to.be.eq(1); + expect(adminList[0].asSubstrate.toString().toLocaleLowerCase()) + .to.be.eq(adminSub.address.toLocaleLowerCase()); + }); }); describe('Change owner tests', () => { - itWeb3('Change owner', async ({api, web3, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const newOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionHelper = evmCollectionHelpers(web3, owner); - const result = await collectionHelper.methods - .createNonfungibleCollection('A', 'B', 'C') - .send({value: Number(2n * UNIQUE)}); - const {collectionIdAddress} = await getCollectionAddressFromResult(api, result); - const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - + let donor: IKeyringPair; + + before(async function() { + await usingEthPlaygrounds(async (_helper, privateKey) => { + donor = privateKey('//Alice'); + }); + }); + + itEth('Change owner', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const newOwner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + await collectionEvm.methods.setOwner(newOwner).send(); - + expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false; expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.true; }); - itWeb3('change owner call fee', async ({web3, api, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const newOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionHelper = evmCollectionHelpers(web3, owner); - const result = await collectionHelper.methods - .createNonfungibleCollection('A', 'B', 'C') - .send({value: Number(2n * UNIQUE)}); - const {collectionIdAddress} = await getCollectionAddressFromResult(api, result); - const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - - const cost = await recordEthFee(api, owner, () => collectionEvm.methods.setOwner(newOwner).send()); - expect(cost < BigInt(0.2 * Number(UNIQUE))); + itEth('change owner call fee', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const newOwner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.setOwner(newOwner).send()); + expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal()))); expect(cost > 0); }); - itWeb3('(!negative tests!) call setOwner by non owner', async ({api, web3, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const newOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionHelper = evmCollectionHelpers(web3, owner); - const result = await collectionHelper.methods - .createNonfungibleCollection('A', 'B', 'C') - .send({value: Number(2n * UNIQUE)}); - const {collectionIdAddress} = await getCollectionAddressFromResult(api, result); - const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - + itEth('(!negative tests!) call setOwner by non owner', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const newOwner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + await expect(collectionEvm.methods.setOwner(newOwner).send({from: newOwner})).to.be.rejected; expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.false; }); }); describe('Change substrate owner tests', () => { - // TODO: Temprorary off. Need refactor - // itWeb3('Change owner', async ({api, web3, privateKeyWrapper}) => { - // const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - // const newOwner = privateKeyWrapper('//Alice'); - // const collectionHelper = evmCollectionHelpers(web3, owner); - // const result = await collectionHelper.methods - // .createNonfungibleCollection('A', 'B', 'C') - // .send(); - // const {collectionIdAddress} = await getCollectionAddressFromResult(api, result); - // const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - - // expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.true; - // expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false; - - // await collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send(); - - // expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false; - // expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.true; - // }); + let donor: IKeyringPair; - // TODO: Temprorary off. Need refactor - // itWeb3('change owner call fee', async ({web3, api, privateKeyWrapper}) => { - // const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - // const newOwner = privateKeyWrapper('//Alice'); - // const collectionHelper = evmCollectionHelpers(web3, owner); - // const result = await collectionHelper.methods - // .createNonfungibleCollection('A', 'B', 'C') - // .send(); - // const {collectionIdAddress} = await getCollectionAddressFromResult(api, result); - // const collectionEvm = evmCollection(web3, owner, collectionIdAddress); + before(async function() { + await usingEthPlaygrounds(async (_helper, privateKey) => { + donor = privateKey('//Alice'); + }); + }); - // const cost = await recordEthFee(api, owner, () => collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send()); - // expect(cost < BigInt(0.2 * Number(UNIQUE))); - // expect(cost > 0); - // }); + itEth.skip('Change owner', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const [newOwner] = await helper.arrange.createAccounts([10n], donor); + const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); - // TODO: Temprorary off. Need refactor - // itWeb3('(!negative tests!) call setOwner by non owner', async ({api, web3, privateKeyWrapper}) => { - // const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - // const otherReceiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - // const newOwner = privateKeyWrapper('//Alice'); - // const collectionHelper = evmCollectionHelpers(web3, owner); - // const result = await collectionHelper.methods - // .createNonfungibleCollection('A', 'B', 'C') - // .send(); - // const {collectionIdAddress} = await getCollectionAddressFromResult(api, result); - // const collectionEvm = evmCollection(web3, owner, collectionIdAddress); - - // await expect(collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send({from: otherReceiver})).to.be.rejected; - // expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false; - // }); -}); \ No newline at end of file + expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.true; + expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false; + + await collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send(); + + expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false; + expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.true; + }); + + itEth.skip('change owner call fee', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const [newOwner] = await helper.arrange.createAccounts([10n], donor); + const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + + const cost = await recordEthFee(helper, owner, () => collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send()); + expect(cost < BigInt(0.2 * Number(helper.balance.getOneTokenNominal()))); + expect(cost > 0); + }); + + itEth.skip('(!negative tests!) call setOwner by non owner', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const otherReceiver = await helper.eth.createAccountWithBalance(donor); + const [newOwner] = await helper.arrange.createAccounts([10n], donor); + const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'B', 'C'); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + + await expect(collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send({from: otherReceiver})).to.be.rejected; + expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false; + }); +}); --- a/tests/src/eth/collectionProperties.test.ts +++ b/tests/src/eth/collectionProperties.test.ts @@ -1,53 +1,56 @@ -import {addCollectionAdminExpectSuccess, createCollectionExpectSuccess} from '../util/helpers'; -import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3} from './util/helpers'; -import nonFungibleAbi from './nonFungibleAbi.json'; -import {expect} from 'chai'; -import {executeTransaction} from '../substrate/substrate-api'; +import {itEth, usingEthPlaygrounds, expect} from './util/playgrounds'; +import {IKeyringPair} from '@polkadot/types/types'; describe('EVM collection properties', () => { - itWeb3('Can be set', async({web3, api, privateKeyWrapper}) => { - const alice = privateKeyWrapper('//Alice'); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); + let donor: IKeyringPair; + let alice: IKeyringPair; + + before(async function() { + await usingEthPlaygrounds(async (_helper, privateKey) => { + donor = privateKey('//Alice'); + [alice] = await _helper.arrange.createAccounts([10n], donor); + }); + }); - await addCollectionAdminExpectSuccess(alice, collection, {Ethereum: caller}); + itEth('Can be set', async({helper}) => { + const caller = await helper.eth.createAccountWithBalance(donor); + const collection = await helper.nft.mintCollection(alice, {name: 'name', description: 'test', tokenPrefix: 'test'}); + await collection.addAdmin(alice, {Ethereum: caller}); - const address = collectionIdToAddress(collection); - const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const contract = helper.ethNativeContract.collection(address, 'nft', caller); await contract.methods.setCollectionProperty('testKey', Buffer.from('testValue')).send({from: caller}); - const [{value}] = (await api.rpc.unique.collectionProperties(collection, ['testKey'])).toHuman()! as any; - expect(value).to.equal('testValue'); + const raw = (await collection.getData())?.raw; + + expect(raw.properties[0].value).to.equal('testValue'); }); - itWeb3('Can be deleted', async({web3, api, privateKeyWrapper}) => { - const alice = privateKeyWrapper('//Alice'); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}}); - await executeTransaction(api, alice, api.tx.unique.setCollectionProperties(collection, [{key: 'testKey', value: 'testValue'}])); + itEth('Can be deleted', async({helper}) => { + const caller = await helper.eth.createAccountWithBalance(donor); + const collection = await helper.nft.mintCollection(alice, {name: 'name', description: 'test', tokenPrefix: 'test', properties: [{key: 'testKey', value: 'testValue'}]}); - await addCollectionAdminExpectSuccess(alice, collection, {Ethereum: caller}); + await collection.addAdmin(alice, {Ethereum: caller}); - const address = collectionIdToAddress(collection); - const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const contract = helper.ethNativeContract.collection(address, 'nft', caller); await contract.methods.deleteCollectionProperty('testKey').send({from: caller}); - const result = (await api.rpc.unique.collectionProperties(collection, ['testKey'])).toJSON()! as any; - expect(result.length).to.equal(0); + const raw = (await collection.getData())?.raw; + + expect(raw.properties.length).to.equal(0); }); - itWeb3('Can be read', async({web3, api, privateKeyWrapper}) => { - const alice = privateKeyWrapper('//Alice'); - const caller = createEthAccount(web3); - const collection = await createCollectionExpectSuccess({mode: {type:'NFT'}}); - await executeTransaction(api, alice, api.tx.unique.setCollectionProperties(collection, [{key: 'testKey', value: 'testValue'}])); + itEth('Can be read', async({helper}) => { + const caller = helper.eth.createAccount(); + const collection = await helper.nft.mintCollection(alice, {name: 'name', description: 'test', tokenPrefix: 'test', properties: [{key: 'testKey', value: 'testValue'}]}); - const address = collectionIdToAddress(collection); - const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const contract = helper.ethNativeContract.collection(address, 'nft', caller); const value = await contract.methods.collectionProperty('testKey').call(); - expect(value).to.equal(web3.utils.toHex('testValue')); + expect(value).to.equal(helper.getWeb3().utils.toHex('testValue')); }); }); --- a/tests/src/eth/proxy/fungibleProxy.test.ts +++ b/tests/src/eth/proxy/fungibleProxy.test.ts @@ -14,18 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Unique Network. If not, see . -import {createCollectionExpectSuccess, createFungibleItemExpectSuccess} from '../../util/helpers'; -import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents} from '../util/helpers'; -import fungibleAbi from '../fungibleAbi.json'; +import {GAS_ARGS, normalizeEvents} from '../util/helpers'; import {expect} from 'chai'; -import {ApiPromise} from '@polkadot/api'; -import Web3 from 'web3'; import {readFile} from 'fs/promises'; import {IKeyringPair} from '@polkadot/types/types'; +import {EthUniqueHelper, itEth, usingEthPlaygrounds} from '../util/playgrounds'; -async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any, privateKeyWrapper: (account: string) => IKeyringPair) { +async function proxyWrap(helper: EthUniqueHelper, wrapped: any, donor: IKeyringPair) { // Proxy owner has no special privilegies, we don't need to reuse them - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const owner = await helper.eth.createAccountWithBalance(donor); + const web3 = helper.getWeb3(); const proxyContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueFungibleProxy.abi`)).toString()), undefined, { from: owner, ...GAS_ARGS, @@ -35,35 +33,38 @@ } describe('Fungible (Via EVM proxy): Information getting', () => { - itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => { - const collection = await createCollectionExpectSuccess({ - name: 'token name', - mode: {type: 'Fungible', decimalPoints: 0}, + let alice: IKeyringPair; + let donor: IKeyringPair; + + before(async function() { + await usingEthPlaygrounds(async (helper, privateKey) => { + donor = privateKey('//Alice'); + [alice] = await helper.arrange.createAccounts([10n], donor); }); - const alice = privateKeyWrapper('//Alice'); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + }); - await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Substrate: alice.address}); + itEth('totalSupply', async ({helper}) => { + const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}, 0); + const caller = await helper.eth.createAccountWithBalance(donor); + await collection.mint(alice, 200n, {Substrate: alice.address}); - const address = collectionIdToAddress(collection); - const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const evmCollection = helper.ethNativeContract.collection(address, 'ft', caller); + const contract = await proxyWrap(helper, evmCollection, donor); const totalSupply = await contract.methods.totalSupply().call(); expect(totalSupply).to.equal('200'); }); - itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => { - const collection = await createCollectionExpectSuccess({ - name: 'token name', - mode: {type: 'Fungible', decimalPoints: 0}, - }); - const alice = privateKeyWrapper('//Alice'); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + itEth('balanceOf', async ({helper}) => { + const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}, 0); + const caller = await helper.eth.createAccountWithBalance(donor); - await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: caller}); + await collection.mint(alice, 200n, {Ethereum: caller}); - const address = collectionIdToAddress(collection); - const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const evmCollection = helper.ethNativeContract.collection(address, 'ft', caller); + const contract = await proxyWrap(helper, evmCollection, donor); const balance = await contract.methods.balanceOf(caller).call(); expect(balance).to.equal('200'); @@ -71,19 +72,26 @@ }); describe('Fungible (Via EVM proxy): Plain calls', () => { - itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => { - const collection = await createCollectionExpectSuccess({ - name: 'token name', - mode: {type: 'Fungible', decimalPoints: 0}, + let alice: IKeyringPair; + let donor: IKeyringPair; + + before(async function() { + await usingEthPlaygrounds(async (helper, privateKey) => { + donor = privateKey('//Alice'); + [alice] = await helper.arrange.createAccounts([10n], donor); }); - const alice = privateKeyWrapper('//Alice'); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const spender = createEthAccount(web3); + }); - const address = collectionIdToAddress(collection); - const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper); - await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: contract.options.address}); + itEth('Can perform approve()', async ({helper}) => { + const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}, 0); + const caller = await helper.eth.createAccountWithBalance(donor); + const spender = helper.eth.createAccount(); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const evmCollection = helper.ethNativeContract.collection(address, 'ft', caller); + const contract = await proxyWrap(helper, evmCollection, donor); + await collection.mint(alice, 200n, {Ethereum: contract.options.address}); + { const result = await contract.methods.approve(spender, 100).send({from: caller}); const events = normalizeEvents(result.events); @@ -107,22 +115,17 @@ } }); - itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => { - const collection = await createCollectionExpectSuccess({ - name: 'token name', - mode: {type: 'Fungible', decimalPoints: 0}, - }); - const alice = privateKeyWrapper('//Alice'); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - - await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: owner}); + itEth('Can perform transferFrom()', async ({helper}) => { + const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}, 0); + const caller = await helper.eth.createAccountWithBalance(donor); + const owner = await helper.eth.createAccountWithBalance(donor); - const receiver = createEthAccount(web3); + await collection.mint(alice, 200n, {Ethereum: owner}); + const receiver = helper.eth.createAccount(); - const address = collectionIdToAddress(collection); - const evmCollection = new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}); - const contract = await proxyWrap(api, web3, evmCollection, privateKeyWrapper); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const evmCollection = helper.ethNativeContract.collection(address, 'ft', caller); + const contract = await proxyWrap(helper, evmCollection, donor); await evmCollection.methods.approve(contract.options.address, 100).send({from: owner}); @@ -162,18 +165,15 @@ } }); - itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => { - const collection = await createCollectionExpectSuccess({ - name: 'token name', - mode: {type: 'Fungible', decimalPoints: 0}, - }); - const alice = privateKeyWrapper('//Alice'); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const receiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + itEth('Can perform transfer()', async ({helper}) => { + const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}, 0); + const caller = await helper.eth.createAccountWithBalance(donor); + const receiver = await helper.eth.createAccountWithBalance(donor); - const address = collectionIdToAddress(collection); - const contract = await proxyWrap(api, web3, new web3.eth.Contract(fungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper); - await createFungibleItemExpectSuccess(alice, collection, {Value: 200n}, {Ethereum: contract.options.address}); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const evmCollection = helper.ethNativeContract.collection(address, 'ft', caller); + const contract = await proxyWrap(helper, evmCollection, donor); + await collection.mint(alice, 200n, {Ethereum: contract.options.address}); { const result = await contract.methods.transfer(receiver, 50).send({from: caller}); --- a/tests/src/eth/proxy/nonFungibleProxy.test.ts +++ b/tests/src/eth/proxy/nonFungibleProxy.test.ts @@ -14,19 +14,16 @@ // You should have received a copy of the GNU General Public License // along with Unique Network. If not, see . -import {createCollectionExpectSuccess, createItemExpectSuccess, UNIQUE} from '../../util/helpers'; -import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, evmCollection, evmCollectionHelpers, GAS_ARGS, getCollectionAddressFromResult, itWeb3, normalizeEvents} from '../util/helpers'; -import nonFungibleAbi from '../nonFungibleAbi.json'; +import {GAS_ARGS, itWeb3, normalizeEvents} from '../util/helpers'; import {expect} from 'chai'; -import {submitTransactionAsync} from '../../substrate/substrate-api'; -import Web3 from 'web3'; import {readFile} from 'fs/promises'; -import {ApiPromise} from '@polkadot/api'; import {IKeyringPair} from '@polkadot/types/types'; +import {EthUniqueHelper, itEth, usingEthPlaygrounds} from '../util/playgrounds'; -async function proxyWrap(api: ApiPromise, web3: Web3, wrapped: any, privateKeyWrapper: (account: string) => IKeyringPair) { +async function proxyWrap(helper: EthUniqueHelper, wrapped: any, donor: IKeyringPair) { // Proxy owner has no special privilegies, we don't need to reuse them - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + const owner = await helper.eth.createAccountWithBalance(donor); + const web3 = helper.getWeb3(); const proxyContract = new web3.eth.Contract(JSON.parse((await readFile(`${__dirname}/UniqueNFTProxy.abi`)).toString()), undefined, { from: owner, ...GAS_ARGS, @@ -36,51 +33,56 @@ } describe('NFT (Via EVM proxy): Information getting', () => { - itWeb3('totalSupply', async ({api, web3, privateKeyWrapper}) => { - const collection = await createCollectionExpectSuccess({ - mode: {type: 'NFT'}, + let alice: IKeyringPair; + let donor: IKeyringPair; + + before(async function() { + await usingEthPlaygrounds(async (helper, privateKey) => { + donor = privateKey('//Alice'); + [alice] = await helper.arrange.createAccounts([10n], donor); }); - const alice = privateKeyWrapper('//Alice'); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + }); - await createItemExpectSuccess(alice, collection, 'NFT', {Substrate: alice.address}); + itEth('totalSupply', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); + const caller = await helper.eth.createAccountWithBalance(donor); + await collection.mintToken(alice, {Substrate: alice.address}); - const address = collectionIdToAddress(collection); - const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const evmCollection = helper.ethNativeContract.collection(address, 'nft', caller); + const contract = await proxyWrap(helper, evmCollection, donor); const totalSupply = await contract.methods.totalSupply().call(); expect(totalSupply).to.equal('1'); }); - itWeb3('balanceOf', async ({api, web3, privateKeyWrapper}) => { - const collection = await createCollectionExpectSuccess({ - mode: {type: 'NFT'}, - }); - const alice = privateKeyWrapper('//Alice'); + itEth('balanceOf', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller}); - await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller}); - await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller}); + const caller = await helper.eth.createAccountWithBalance(donor); + await collection.mintMultipleTokens(alice, [ + {owner: {Ethereum: caller}}, + {owner: {Ethereum: caller}}, + {owner: {Ethereum: caller}}, + ]); - const address = collectionIdToAddress(collection); - const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const evmCollection = helper.ethNativeContract.collection(address, 'nft', caller); + const contract = await proxyWrap(helper, evmCollection, donor); const balance = await contract.methods.balanceOf(caller).call(); expect(balance).to.equal('3'); }); - itWeb3('ownerOf', async ({api, web3, privateKeyWrapper}) => { - const collection = await createCollectionExpectSuccess({ - mode: {type: 'NFT'}, - }); - const alice = privateKeyWrapper('//Alice'); + itEth('ownerOf', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: caller}); + const caller = await helper.eth.createAccountWithBalance(donor); + const {tokenId} = await collection.mintToken(alice, {Ethereum: caller}); - const address = collectionIdToAddress(collection); - const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const evmCollection = helper.ethNativeContract.collection(address, 'nft', caller); + const contract = await proxyWrap(helper, evmCollection, donor); const owner = await contract.methods.ownerOf(tokenId).call(); expect(owner).to.equal(caller); @@ -88,18 +90,25 @@ }); describe('NFT (Via EVM proxy): Plain calls', () => { - itWeb3('Can perform mint()', async ({web3, api, privateKeyWrapper}) => { - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const collectionHelper = evmCollectionHelpers(web3, owner); - const result = await collectionHelper.methods - .createNonfungibleCollection('A', 'A', 'A') - .send({value: Number(2n * UNIQUE)}); - const {collectionIdAddress} = await getCollectionAddressFromResult(api, result); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const receiver = createEthAccount(web3); - const collectionEvmOwned = evmCollection(web3, owner, collectionIdAddress); - const collectionEvm = evmCollection(web3, caller, collectionIdAddress); - const contract = await proxyWrap(api, web3, collectionEvm, privateKeyWrapper); + let alice: IKeyringPair; + let donor: IKeyringPair; + + before(async function() { + await usingEthPlaygrounds(async (helper, privateKey) => { + donor = privateKey('//Alice'); + [alice] = await helper.arrange.createAccounts([10n], donor); + }); + }); + + itEth('Can perform mint()', async ({helper}) => { + const owner = await helper.eth.createAccountWithBalance(donor); + const {collectionAddress} = await helper.eth.createNonfungibleCollection(owner, 'A', 'A', 'A'); + const caller = await helper.eth.createAccountWithBalance(donor); + const receiver = helper.eth.createAccount(); + + const collectionEvmOwned = helper.ethNativeContract.collection(collectionAddress, 'nft', owner); + const collectionEvm = helper.ethNativeContract.collection(collectionAddress, 'nft', caller); + const contract = await proxyWrap(helper, collectionEvm, donor); await collectionEvmOwned.methods.addCollectionAdmin(contract.options.address).send(); { @@ -115,7 +124,7 @@ expect(events).to.be.deep.equal([ { - address: collectionIdAddress.toLocaleLowerCase(), + address: collectionAddress.toLocaleLowerCase(), event: 'Transfer', args: { from: '0x0000000000000000000000000000000000000000', @@ -128,9 +137,10 @@ expect(await contract.methods.tokenURI(nextTokenId).call()).to.be.equal('Test URI'); } }); - + //TODO: CORE-302 add eth methods itWeb3.skip('Can perform mintBulk()', async ({web3, api, privateKeyWrapper}) => { + /* const collection = await createCollectionExpectSuccess({ mode: {type: 'NFT'}, }); @@ -191,21 +201,18 @@ expect(await contract.methods.tokenURI(+nextTokenId + 1).call()).to.be.equal('Test URI 1'); expect(await contract.methods.tokenURI(+nextTokenId + 2).call()).to.be.equal('Test URI 2'); } + */ }); - - itWeb3('Can perform burn()', async ({web3, api, privateKeyWrapper}) => { - const collection = await createCollectionExpectSuccess({ - mode: {type: 'NFT'}, - }); - const alice = privateKeyWrapper('//Alice'); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const address = collectionIdToAddress(collection); - const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper); - const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address}); + itEth('Can perform burn()', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); + const caller = await helper.eth.createAccountWithBalance(donor); - const changeAdminTx = api.tx.unique.addCollectionAdmin(collection, {Ethereum: contract.options.address}); - await submitTransactionAsync(alice, changeAdminTx); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const evmCollection = helper.ethNativeContract.collection(address, 'nft', caller); + const contract = await proxyWrap(helper, evmCollection, donor); + const {tokenId} = await collection.mintToken(alice, {Ethereum: contract.options.address}); + await collection.addAdmin(alice, {Ethereum: contract.options.address}); { const result = await contract.methods.burn(tokenId).send({from: caller}); @@ -225,17 +232,15 @@ } }); - itWeb3('Can perform approve()', async ({web3, api, privateKeyWrapper}) => { - const collection = await createCollectionExpectSuccess({ - mode: {type: 'NFT'}, - }); - const alice = privateKeyWrapper('//Alice'); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const spender = createEthAccount(web3); + itEth('Can perform approve()', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); + const caller = await helper.eth.createAccountWithBalance(donor); + const spender = helper.eth.createAccount(); - const address = collectionIdToAddress(collection); - const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address), privateKeyWrapper); - const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address}); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const evmCollection = helper.ethNativeContract.collection(address, 'nft', caller); + const contract = await proxyWrap(helper, evmCollection, donor); + const {tokenId} = await collection.mintToken(alice, {Ethereum: contract.options.address}); { const result = await contract.methods.approve(spender, tokenId).send({from: caller, ...GAS_ARGS}); @@ -255,20 +260,17 @@ } }); - itWeb3('Can perform transferFrom()', async ({web3, api, privateKeyWrapper}) => { - const collection = await createCollectionExpectSuccess({ - mode: {type: 'NFT'}, - }); - const alice = privateKeyWrapper('//Alice'); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper); + itEth('Can perform transferFrom()', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); + const caller = await helper.eth.createAccountWithBalance(donor); + const owner = await helper.eth.createAccountWithBalance(donor); - const receiver = createEthAccount(web3); + const receiver = helper.eth.createAccount(); - const address = collectionIdToAddress(collection); - const evmCollection = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}); - const contract = await proxyWrap(api, web3, evmCollection, privateKeyWrapper); - const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner}); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const evmCollection = helper.ethNativeContract.collection(address, 'nft', caller); + const contract = await proxyWrap(helper, evmCollection, donor); + const {tokenId} = await collection.mintToken(alice, {Ethereum: owner}); await evmCollection.methods.approve(contract.options.address, tokenId).send({from: owner}); @@ -299,17 +301,15 @@ } }); - itWeb3('Can perform transfer()', async ({web3, api, privateKeyWrapper}) => { - const collection = await createCollectionExpectSuccess({ - mode: {type: 'NFT'}, - }); - const alice = privateKeyWrapper('//Alice'); - const caller = await createEthAccountWithBalance(api, web3, privateKeyWrapper); - const receiver = createEthAccount(web3); + itEth('Can perform transfer()', async ({helper}) => { + const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'}); + const caller = await helper.eth.createAccountWithBalance(donor); + const receiver = helper.eth.createAccount(); - const address = collectionIdToAddress(collection); - const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}), privateKeyWrapper); - const tokenId = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address}); + const address = helper.ethAddress.fromCollectionId(collection.collectionId); + const evmCollection = helper.ethNativeContract.collection(address, 'nft', caller); + const contract = await proxyWrap(helper, evmCollection, donor); + const {tokenId} = await collection.mintToken(alice, {Ethereum: contract.options.address}); { const result = await contract.methods.transfer(receiver, tokenId).send({from: caller}); -- gitstuff