git.delta.rocks / unique-network / refs/commits / 3a01a5229f7a

difftreelog

Merge pull request #622 from UniqueNetwork/test/playground-migration

ut-akuznetsov2022-10-04parents: #d3b796f #686b7bd.patch.diff
in: master
Test/playground migration

13 files changed

modifiedtests/src/check-event/burnItemEvent.test.tsdiffbeforeafterboth
--- 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 <http://www.gnu.org/licenses/>.
 
 // 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');
   });
 });
modifiedtests/src/check-event/createCollectionEvent.test.tsdiffbeforeafterboth
--- 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 <http://www.gnu.org/licenses/>.
 
 // 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');
   });
 });
modifiedtests/src/check-event/createItemEvent.test.tsdiffbeforeafterboth
--- 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 <http://www.gnu.org/licenses/>.
 
 // 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');
   });
 });
modifiedtests/src/check-event/createMultipleItemsEvent.test.tsdiffbeforeafterboth
--- 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 <http://www.gnu.org/licenses/>.
 
 // 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');
   });
 });
modifiedtests/src/check-event/destroyCollectionEvent.test.tsdiffbeforeafterboth
--- 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 <http://www.gnu.org/licenses/>.
 
 // 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');
   });
 });
modifiedtests/src/check-event/transferEvent.test.tsdiffbeforeafterboth
--- 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 <http://www.gnu.org/licenses/>.
 
 // 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');
   });
 });
modifiedtests/src/check-event/transferFromEvent.test.tsdiffbeforeafterboth
--- 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 <http://www.gnu.org/licenses/>.
 
 // 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');
   });
 });
modifiedtests/src/eth/allowlist.test.tsdiffbeforeafterboth
--- 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 <http://www.gnu.org/licenses/>.
 
 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;
modifiedtests/src/eth/base.test.tsdiffbeforeafterboth
--- 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 <http://www.gnu.org/licenses/>.
 
 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;
   });
 });
modifiedtests/src/eth/collectionAdmin.test.tsdiffbeforeafterboth
before · tests/src/eth/collectionAdmin.test.ts
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.3// Unique Network is free software: you can redistribute it and/or modify4// it under the terms of the GNU General Public License as published by5// the Free Software Foundation, either version 3 of the License, or6// (at your option) any later version.7//8// Unique Network is distributed in the hope that it will be useful,9// but WITHOUT ANY WARRANTY; without even the implied warranty of10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the11// GNU General Public License for more details.1213// You should have received a copy of the GNU General Public License14// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1516import {expect} from 'chai';17import privateKey from '../substrate/privateKey';18import {UNIQUE} from '../util/helpers';19import {20  createEthAccount,21  createEthAccountWithBalance, 22  evmCollection, 23  evmCollectionHelpers, 24  getCollectionAddressFromResult, 25  itWeb3,26  recordEthFee,27} from './util/helpers';2829describe('Add collection admins', () => {30  itWeb3('Add admin by owner', async ({api, web3, privateKeyWrapper}) => {31    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);32    const collectionHelper = evmCollectionHelpers(web3, owner);3334    const result = await collectionHelper.methods35      .createNonfungibleCollection('A', 'B', 'C')36      .send({value: Number(2n * UNIQUE)});37    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);3839    const newAdmin = createEthAccount(web3);40    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);41    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();42    const adminList = await api.rpc.unique.adminlist(collectionId);43    expect(adminList[0].asEthereum.toString().toLocaleLowerCase())44      .to.be.eq(newAdmin.toLocaleLowerCase());45  });4647  // TODO: Temprorary off. Need refactor48  // itWeb3('Add substrate admin by owner', async ({api, web3, privateKeyWrapper}) => {49  //   const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);50  //   const collectionHelper = evmCollectionHelpers(web3, owner);51        52  //   const result = await collectionHelper.methods53  //     .createNonfungibleCollection('A', 'B', 'C')54  //     .send();55  //   const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);5657  //   const newAdmin = privateKeyWrapper('//Alice');58  //   const collectionEvm = evmCollection(web3, owner, collectionIdAddress);59  //   await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();6061  //   const adminList = await api.rpc.unique.adminlist(collectionId);62  //   expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())63  //     .to.be.eq(newAdmin.address.toLocaleLowerCase());64  // });65  66  itWeb3('Verify owner or admin', async ({api, web3, privateKeyWrapper}) => {67    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);68    const collectionHelper = evmCollectionHelpers(web3, owner);69        70    const result = await collectionHelper.methods71      .createNonfungibleCollection('A', 'B', 'C')72      .send({value: Number(2n * UNIQUE)});73    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);7475    const newAdmin = createEthAccount(web3);76    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);77    expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.false;78    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();79    expect(await collectionEvm.methods.isOwnerOrAdmin(newAdmin).call()).to.be.true;80  });8182  itWeb3('(!negative tests!) Add admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {83    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);84    const collectionHelper = evmCollectionHelpers(web3, owner);85        86    const result = await collectionHelper.methods87      .createNonfungibleCollection('A', 'B', 'C')88      .send({value: Number(2n * UNIQUE)});89    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);9091    const admin = await createEthAccountWithBalance(api, web3, privateKeyWrapper);92    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);93    await collectionEvm.methods.addCollectionAdmin(admin).send();94    95    const user = createEthAccount(web3);96    await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: admin}))97      .to.be.rejectedWith('NoPermission');9899    const adminList = await api.rpc.unique.adminlist(collectionId);100    expect(adminList.length).to.be.eq(1);101    expect(adminList[0].asEthereum.toString().toLocaleLowerCase())102      .to.be.eq(admin.toLocaleLowerCase());103  });104105  itWeb3('(!negative tests!) Add admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => {106    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);107    const collectionHelper = evmCollectionHelpers(web3, owner);108        109    const result = await collectionHelper.methods110      .createNonfungibleCollection('A', 'B', 'C')111      .send({value: Number(2n * UNIQUE)});112    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);113114    const notAdmin = await createEthAccountWithBalance(api, web3, privateKeyWrapper);115    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);116    117    const user = createEthAccount(web3);118    await expect(collectionEvm.methods.addCollectionAdmin(user).call({from: notAdmin}))119      .to.be.rejectedWith('NoPermission');120121    const adminList = await api.rpc.unique.adminlist(collectionId);122    expect(adminList.length).to.be.eq(0);123  });124125  // TODO: Temprorary off. Need refactor126  // itWeb3('(!negative tests!) Add substrate admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {127  //   const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);128  //   const collectionHelper = evmCollectionHelpers(web3, owner);129        130  //   const result = await collectionHelper.methods131  //     .createNonfungibleCollection('A', 'B', 'C')132  //     .send();133  //   const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);134135  //   const admin = await createEthAccountWithBalance(api, web3, privateKeyWrapper);136  //   const collectionEvm = evmCollection(web3, owner, collectionIdAddress);137  //   await collectionEvm.methods.addCollectionAdmin(admin).send();138139  //   const notAdmin = privateKey('//Alice');140  //   await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin.addressRaw).call({from: admin}))141  //     .to.be.rejectedWith('NoPermission');142143  //   const adminList = await api.rpc.unique.adminlist(collectionId);144  //   expect(adminList.length).to.be.eq(1);145  //   expect(adminList[0].asEthereum.toString().toLocaleLowerCase())146  //     .to.be.eq(admin.toLocaleLowerCase());147  // });148  149  // TODO: Temprorary off. Need refactor150  // itWeb3('(!negative tests!) Add substrate admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => {151  //   const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);152  //   const collectionHelper = evmCollectionHelpers(web3, owner);153        154  //   const result = await collectionHelper.methods155  //     .createNonfungibleCollection('A', 'B', 'C')156  //     .send();157  //   const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);158159  //   const notAdmin0 = await createEthAccountWithBalance(api, web3, privateKeyWrapper);160  //   const collectionEvm = evmCollection(web3, owner, collectionIdAddress);161  //   const notAdmin1 = privateKey('//Alice');162  //   await expect(collectionEvm.methods.addCollectionAdminSubstrate(notAdmin1.addressRaw).call({from: notAdmin0}))163  //     .to.be.rejectedWith('NoPermission');164165  //   const adminList = await api.rpc.unique.adminlist(collectionId);166  //   expect(adminList.length).to.be.eq(0);167  // });168});169170describe('Remove collection admins', () => {171  itWeb3('Remove admin by owner', async ({api, web3, privateKeyWrapper}) => {172    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);173    const collectionHelper = evmCollectionHelpers(web3, owner);174        175    const result = await collectionHelper.methods176      .createNonfungibleCollection('A', 'B', 'C')177      .send({value: Number(2n * UNIQUE)});178    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);179180    const newAdmin = createEthAccount(web3);181    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);182    await collectionEvm.methods.addCollectionAdmin(newAdmin).send();183    {184      const adminList = await api.rpc.unique.adminlist(collectionId);185      expect(adminList.length).to.be.eq(1);186      expect(adminList[0].asEthereum.toString().toLocaleLowerCase())187        .to.be.eq(newAdmin.toLocaleLowerCase());188    }189190    await collectionEvm.methods.removeCollectionAdmin(newAdmin).send();191    const adminList = await api.rpc.unique.adminlist(collectionId);192    expect(adminList.length).to.be.eq(0);193  });194195  // TODO: Temprorary off. Need refactor196  // itWeb3('Remove substrate admin by owner', async ({api, web3, privateKeyWrapper}) => {197  //   const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);198  //   const collectionHelper = evmCollectionHelpers(web3, owner);199        200  //   const result = await collectionHelper.methods201  //     .createNonfungibleCollection('A', 'B', 'C')202  //     .send();203  //   const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);204205  //   const newAdmin = privateKeyWrapper('//Alice');206  //   const collectionEvm = evmCollection(web3, owner, collectionIdAddress);207  //   await collectionEvm.methods.addCollectionAdminSubstrate(newAdmin.addressRaw).send();208  //   {209  //     const adminList = await api.rpc.unique.adminlist(collectionId);210  //     expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())211  //       .to.be.eq(newAdmin.address.toLocaleLowerCase());212  //   }213    214  //   await collectionEvm.methods.removeCollectionAdminSubstrate(newAdmin.addressRaw).send();215  //   const adminList = await api.rpc.unique.adminlist(collectionId);216  //   expect(adminList.length).to.be.eq(0);217  // });218219  itWeb3('(!negative tests!) Remove admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {220    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);221    const collectionHelper = evmCollectionHelpers(web3, owner);222        223    const result = await collectionHelper.methods224      .createNonfungibleCollection('A', 'B', 'C')225      .send({value: Number(2n * UNIQUE)});226    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);227228    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);229230    const admin0 = await createEthAccountWithBalance(api, web3, privateKeyWrapper);231    await collectionEvm.methods.addCollectionAdmin(admin0).send();232    const admin1 = createEthAccount(web3);233    await collectionEvm.methods.addCollectionAdmin(admin1).send();234235    await expect(collectionEvm.methods.removeCollectionAdmin(admin1).call({from: admin0}))236      .to.be.rejectedWith('NoPermission');237    {238      const adminList = await api.rpc.unique.adminlist(collectionId);239      expect(adminList.length).to.be.eq(2);240      expect(adminList.toString().toLocaleLowerCase())241        .to.be.deep.contains(admin0.toLocaleLowerCase())242        .to.be.deep.contains(admin1.toLocaleLowerCase());243    }244  });245246  itWeb3('(!negative tests!) Remove admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => {247    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);248    const collectionHelper = evmCollectionHelpers(web3, owner);249        250    const result = await collectionHelper.methods251      .createNonfungibleCollection('A', 'B', 'C')252      .send({value: Number(2n * UNIQUE)});253    const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);254255    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);256257    const admin = await createEthAccountWithBalance(api, web3, privateKeyWrapper);258    await collectionEvm.methods.addCollectionAdmin(admin).send();259    const notAdmin = createEthAccount(web3);260261    await expect(collectionEvm.methods.removeCollectionAdmin(admin).call({from: notAdmin}))262      .to.be.rejectedWith('NoPermission');263    {264      const adminList = await api.rpc.unique.adminlist(collectionId);265      expect(adminList[0].asEthereum.toString().toLocaleLowerCase())266        .to.be.eq(admin.toLocaleLowerCase());267      expect(adminList.length).to.be.eq(1);268    }269  });270271  // TODO: Temprorary off. Need refactor272  // itWeb3('(!negative tests!) Remove substrate admin by ADMIN is not allowed', async ({api, web3, privateKeyWrapper}) => {273  //   const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);274  //   const collectionHelper = evmCollectionHelpers(web3, owner);275        276  //   const result = await collectionHelper.methods277  //     .createNonfungibleCollection('A', 'B', 'C')278  //     .send();279  //   const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);280281  //   const adminSub = privateKeyWrapper('//Alice');282  //   const collectionEvm = evmCollection(web3, owner, collectionIdAddress);283  //   await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();284  //   const adminEth = await createEthAccountWithBalance(api, web3, privateKeyWrapper);285  //   await collectionEvm.methods.addCollectionAdmin(adminEth).send();286287  //   await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: adminEth}))288  //     .to.be.rejectedWith('NoPermission');289290  //   const adminList = await api.rpc.unique.adminlist(collectionId);291  //   expect(adminList.length).to.be.eq(2);292  //   expect(adminList.toString().toLocaleLowerCase())293  //     .to.be.deep.contains(adminSub.address.toLocaleLowerCase())294  //     .to.be.deep.contains(adminEth.toLocaleLowerCase());295  // });296297  // TODO: Temprorary off. Need refactor298  // itWeb3('(!negative tests!) Remove substrate admin by USER is not allowed', async ({api, web3, privateKeyWrapper}) => {299  //   const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);300  //   const collectionHelper = evmCollectionHelpers(web3, owner);301        302  //   const result = await collectionHelper.methods303  //     .createNonfungibleCollection('A', 'B', 'C')304  //     .send();305  //   const {collectionIdAddress, collectionId} = await getCollectionAddressFromResult(api, result);306307  //   const adminSub = privateKeyWrapper('//Alice');308  //   const collectionEvm = evmCollection(web3, owner, collectionIdAddress);309  //   await collectionEvm.methods.addCollectionAdminSubstrate(adminSub.addressRaw).send();310  //   const notAdminEth = await createEthAccountWithBalance(api, web3, privateKeyWrapper);311312  //   await expect(collectionEvm.methods.removeCollectionAdminSubstrate(adminSub.addressRaw).call({from: notAdminEth}))313  //     .to.be.rejectedWith('NoPermission');314315  //   const adminList = await api.rpc.unique.adminlist(collectionId);316  //   expect(adminList.length).to.be.eq(1);317  //   expect(adminList[0].asSubstrate.toString().toLocaleLowerCase())318  //     .to.be.eq(adminSub.address.toLocaleLowerCase());319  // });320});321322describe('Change owner tests', () => {323  itWeb3('Change owner', async ({api, web3, privateKeyWrapper}) => {324    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);325    const newOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);326    const collectionHelper = evmCollectionHelpers(web3, owner);327    const result = await collectionHelper.methods328      .createNonfungibleCollection('A', 'B', 'C')329      .send({value: Number(2n * UNIQUE)});330    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);331    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);332  333    await collectionEvm.methods.setOwner(newOwner).send();334  335    expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;336    expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.true;337  });338339  itWeb3('change owner call fee', async ({web3, api, privateKeyWrapper}) => {340    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);341    const newOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);342    const collectionHelper = evmCollectionHelpers(web3, owner);343    const result = await collectionHelper.methods344      .createNonfungibleCollection('A', 'B', 'C')345      .send({value: Number(2n * UNIQUE)});346    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);347    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);348349    const cost = await recordEthFee(api, owner, () => collectionEvm.methods.setOwner(newOwner).send());350    expect(cost < BigInt(0.2 * Number(UNIQUE)));351    expect(cost > 0);352  });353354  itWeb3('(!negative tests!) call setOwner by non owner', async ({api, web3, privateKeyWrapper}) => {355    const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);356    const newOwner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);357    const collectionHelper = evmCollectionHelpers(web3, owner);358    const result = await collectionHelper.methods359      .createNonfungibleCollection('A', 'B', 'C')360      .send({value: Number(2n * UNIQUE)});361    const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);362    const collectionEvm = evmCollection(web3, owner, collectionIdAddress);363  364    await expect(collectionEvm.methods.setOwner(newOwner).send({from: newOwner})).to.be.rejected;365    expect(await collectionEvm.methods.isOwnerOrAdmin(newOwner).call()).to.be.false;366  });367});368369describe('Change substrate owner tests', () => {370  // TODO: Temprorary off. Need refactor371  // itWeb3('Change owner', async ({api, web3, privateKeyWrapper}) => {372  //   const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);373  //   const newOwner = privateKeyWrapper('//Alice');374  //   const collectionHelper = evmCollectionHelpers(web3, owner);375  //   const result = await collectionHelper.methods376  //     .createNonfungibleCollection('A', 'B', 'C')377  //     .send();378  //   const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);379  //   const collectionEvm = evmCollection(web3, owner, collectionIdAddress);380  381  //   expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.true;382  //   expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;383    384  //   await collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send();385  386  //   expect(await collectionEvm.methods.isOwnerOrAdmin(owner).call()).to.be.false;387  //   expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.true;388  // });389390  // TODO: Temprorary off. Need refactor391  // itWeb3('change owner call fee', async ({web3, api, privateKeyWrapper}) => {392  //   const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);393  //   const newOwner = privateKeyWrapper('//Alice');394  //   const collectionHelper = evmCollectionHelpers(web3, owner);395  //   const result = await collectionHelper.methods396  //     .createNonfungibleCollection('A', 'B', 'C')397  //     .send();398  //   const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);399  //   const collectionEvm = evmCollection(web3, owner, collectionIdAddress);400401  //   const cost = await recordEthFee(api, owner, () => collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send());402  //   expect(cost < BigInt(0.2 * Number(UNIQUE)));403  //   expect(cost > 0);404  // });405406  // TODO: Temprorary off. Need refactor407  // itWeb3('(!negative tests!) call setOwner by non owner', async ({api, web3, privateKeyWrapper}) => {408  //   const owner = await createEthAccountWithBalance(api, web3, privateKeyWrapper);409  //   const otherReceiver = await createEthAccountWithBalance(api, web3, privateKeyWrapper);410  //   const newOwner = privateKeyWrapper('//Alice');411  //   const collectionHelper = evmCollectionHelpers(web3, owner);412  //   const result = await collectionHelper.methods413  //     .createNonfungibleCollection('A', 'B', 'C')414  //     .send();415  //   const {collectionIdAddress} = await getCollectionAddressFromResult(api, result);416  //   const collectionEvm = evmCollection(web3, owner, collectionIdAddress);417  418  //   await expect(collectionEvm.methods.setOwnerSubstrate(newOwner.addressRaw).send({from: otherReceiver})).to.be.rejected;419  //   expect(await collectionEvm.methods.isOwnerOrAdminSubstrate(newOwner.addressRaw).call()).to.be.false;420  // });421});
modifiedtests/src/eth/collectionProperties.test.tsdiffbeforeafterboth
--- 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'));
   });
 });
modifiedtests/src/eth/proxy/fungibleProxy.test.tsdiffbeforeafterboth
--- 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 <http://www.gnu.org/licenses/>.
 
-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});
modifiedtests/src/eth/proxy/nonFungibleProxy.test.tsdiffbeforeafterboth
--- 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 <http://www.gnu.org/licenses/>.
 
-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});