git.delta.rocks / unique-network / refs/commits / a371005c4391

difftreelog

Merge pull request #576 from UniqueNetwork/tests/intermediate-refactor

ut-akuznetsov2022-09-12parents: #c4493f1 #f5b44a9.patch.diff
in: master

33 files changed

modifiedtests/package.jsondiffbeforeafterboth
--- a/tests/package.json
+++ b/tests/package.json
@@ -71,6 +71,7 @@
     "testRemoveFromContractAllowList": "mocha --timeout 9999999 -r ts-node/register ./**/removeFromContractAllowList.test.ts",
     "testSetContractSponsoringRateLimit": "mocha --timeout 9999999 -r ts-node/register ./**/setContractSponsoringRateLimit.test.ts",
     "testSetOffchainSchema": "mocha --timeout 9999999 -r ts-node/register ./**/setOffchainSchema.test.ts",
+    "testNextSponsoring": "mocha --timeout 9999999 -r ts-node/register ./**/nextSponsoring.test.ts",
     "testOverflow": "mocha --timeout 9999999 -r ts-node/register ./**/overflow.test.ts",
     "testInflation": "mocha --timeout 9999999 -r ts-node/register ./**/inflation.test.ts",
     "testScheduler": "mocha --timeout 9999999 -r ts-node/register ./**/scheduler.test.ts",
@@ -97,7 +98,7 @@
   "dependencies": {
     "@polkadot/api": "9.2.2",
     "@polkadot/api-contract": "9.2.2",
-    "@polkadot/util-crypto": "10.1.1",
+    "@polkadot/util-crypto": "10.1.7",
     "bignumber.js": "^9.0.2",
     "chai-as-promised": "^7.1.1",
     "chai-like": "^1.1.1",
modifiedtests/src/addCollectionAdmin.test.tsdiffbeforeafterboth
--- a/tests/src/addCollectionAdmin.test.ts
+++ b/tests/src/addCollectionAdmin.test.ts
@@ -15,121 +15,111 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 import {IKeyringPair} from '@polkadot/types/types';
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-import {usingPlaygrounds} from './util/playgrounds';
+import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
 
-chai.use(chaiAsPromised);
-const expect = chai.expect;
+describe('Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {
+  let donor: IKeyringPair;
 
-let donor: IKeyringPair;
-
-before(async () => {
-  await usingPlaygrounds(async (_, privateKeyWrapper) => {
-    donor = privateKeyWrapper('//Alice');
+  before(async () => {
+    await usingPlaygrounds(async (_, privateKeyWrapper) => {
+      donor = privateKeyWrapper('//Alice');
+    });
   });
-});
 
-describe('Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {
-  it('Add collection admin.', async () => {
-    await usingPlaygrounds(async (helper) => {
-      const [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
-      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
+  itSub('Add collection admin.', async ({helper}) => {
+    const [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
+    const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
 
-      const collection = await helper.collection.getData(collectionId);
-      expect(collection!.normalizedOwner!).to.be.equal(alice.address);
+    const collection = await helper.collection.getData(collectionId);
+    expect(collection!.normalizedOwner!).to.be.equal(helper.address.normalizeSubstrate(alice.address));
 
-      await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address});
+    await helper.nft.addAdmin(alice, collectionId, {Substrate: bob.address});
 
-      const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);
-      expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
-    });
+    const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);
+    expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
   });
 });
 
 describe('Negative Integration Test addCollectionAdmin(collection_id, new_admin_id):', () => {
-  it("Not owner can't add collection admin.", async () => {
-    await usingPlaygrounds(async (helper) => {
-      const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
-      const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
+  let donor: IKeyringPair;
+
+  before(async () => {
+    await usingPlaygrounds(async (_, privateKeyWrapper) => {
+      donor = privateKeyWrapper('//Alice');
+    });
+  });
 
-      const collection = await helper.collection.getData(collectionId);
-      expect(collection?.normalizedOwner).to.be.equal(alice.address);
+  itSub("Not owner can't add collection admin.", async ({helper}) => {
+    const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
+    const {collectionId} = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
 
-      const changeAdminTxBob = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: bob.address});
-      const changeAdminTxCharlie = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: charlie.address});
-      await expect(changeAdminTxCharlie()).to.be.rejected;
-      await expect(changeAdminTxBob()).to.be.rejected;
+    const collection = await helper.collection.getData(collectionId);
+    expect(collection?.normalizedOwner).to.be.equal(helper.address.normalizeSubstrate(alice.address));
+
+    const changeAdminTxBob = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: bob.address});
+    const changeAdminTxCharlie = async () => helper.collection.addAdmin(bob, collectionId, {Substrate: charlie.address});
+    await expect(changeAdminTxCharlie()).to.be.rejectedWith(/common\.NoPermission/);
+    await expect(changeAdminTxBob()).to.be.rejectedWith(/common\.NoPermission/);
 
-      const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);
-      expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: charlie.address});
-      expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: bob.address});
-    });
+    const adminListAfterAddAdmin = await helper.collection.getAdmins(collectionId);
+    expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: charlie.address});
+    expect(adminListAfterAddAdmin).to.be.not.deep.contains({Substrate: bob.address});
   });
 
-  it("Admin can't add collection admin.", async () => {
-    await usingPlaygrounds(async (helper) => {
-      const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
-      const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
+  itSub("Admin can't add collection admin.", async ({helper}) => {
+    const [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
+    const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
 
-      await collection.addAdmin(alice, {Substrate: bob.address});
+    await collection.addAdmin(alice, {Substrate: bob.address});
 
-      const adminListAfterAddAdmin = await collection.getAdmins();
-      expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
+    const adminListAfterAddAdmin = await collection.getAdmins();
+    expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
 
-      const changeAdminTxCharlie = async () => collection.addAdmin(bob, {Substrate: charlie.address});
-      await expect(changeAdminTxCharlie()).to.be.rejected;
+    const changeAdminTxCharlie = async () => collection.addAdmin(bob, {Substrate: charlie.address});
+    await expect(changeAdminTxCharlie()).to.be.rejectedWith(/common\.NoPermission/);
 
-      const adminListAfterAddNewAdmin = await collection.getAdmins();
-      expect(adminListAfterAddNewAdmin).to.be.deep.contains({Substrate: bob.address});
-      expect(adminListAfterAddNewAdmin).to.be.not.deep.contains({Substrate: charlie.address});
-    });
+    const adminListAfterAddNewAdmin = await collection.getAdmins();
+    expect(adminListAfterAddNewAdmin).to.be.deep.contains({Substrate: bob.address});
+    expect(adminListAfterAddNewAdmin).to.be.not.deep.contains({Substrate: charlie.address});
   });
 
-  it("Can't add collection admin of not existing collection.", async () => {
-    await usingPlaygrounds(async (helper) => {
-      const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
-      // tslint:disable-next-line: no-bitwise
-      const collectionId = (1 << 32) - 1;
+  itSub("Can't add collection admin of not existing collection.", async ({helper}) => {
+    const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
+    const collectionId = (1 << 32) - 1;
 
-      const addAdminTx = async () => helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});
-      await expect(addAdminTx()).to.be.rejected;
+    const addAdminTx = async () => helper.collection.addAdmin(alice, collectionId, {Substrate: bob.address});
+    await expect(addAdminTx()).to.be.rejectedWith(/common\.CollectionNotFound/);
 
-      // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
-      await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
-    });
+    // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
+    await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
   });
 
-  it("Can't add an admin to a destroyed collection.", async () => {
-    await usingPlaygrounds(async (helper) => {
-      const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
-      const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
+  itSub("Can't add an admin to a destroyed collection.", async ({helper}) => {
+    const [alice, bob] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
+    const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
 
-      await collection.burn(alice);
-      const addAdminTx = async () => collection.addAdmin(alice, {Substrate: bob.address});
-      await expect(addAdminTx()).to.be.rejected;
+    await collection.burn(alice);
+    const addAdminTx = async () => collection.addAdmin(alice, {Substrate: bob.address});
+    await expect(addAdminTx()).to.be.rejectedWith(/common\.CollectionNotFound/);
 
-      // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
-      await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
-    });
+    // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
+    await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
   });
 
-  it('Add an admin to a collection that has reached the maximum number of admins limit', async () => {
-    await usingPlaygrounds(async (helper) => {
-      const [alice, ...accounts] = await helper.arrange.createAccounts([10n, 0n, 0n, 0n, 0n, 0n, 0n, 0n], donor);
-      const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
+  itSub('Add an admin to a collection that has reached the maximum number of admins limit', async ({helper}) => {
+    const [alice, ...accounts] = await helper.arrange.createAccounts([10n, 0n, 0n, 0n, 0n, 0n, 0n, 0n], donor);
+    const collection = await helper.nft.mintCollection(alice, {name: 'Collection Name', description: 'Collection Description', tokenPrefix: 'COL'});
 
-      const chainAdminLimit = (helper.api!.consts.common.collectionAdminsLimit as any).toNumber();
-      expect(chainAdminLimit).to.be.equal(5);
+    const chainAdminLimit = (helper.api!.consts.common.collectionAdminsLimit as any).toNumber();
+    expect(chainAdminLimit).to.be.equal(5);
 
-      for (let i = 0; i < chainAdminLimit; i++) {
-        await collection.addAdmin(alice, {Substrate: accounts[i].address});
-        const adminListAfterAddAdmin = await collection.getAdmins();
-        expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: accounts[i].address});
-      }
+    for (let i = 0; i < chainAdminLimit; i++) {
+      await collection.addAdmin(alice, {Substrate: accounts[i].address});
+      const adminListAfterAddAdmin = await collection.getAdmins();
+      expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: accounts[i].address});
+    }
 
-      const addExtraAdminTx = async () => collection.addAdmin(alice, {Substrate: accounts[chainAdminLimit].address});
-      await expect(addExtraAdminTx()).to.be.rejected;
-    });
+    const addExtraAdminTx = async () => collection.addAdmin(alice, {Substrate: accounts[chainAdminLimit].address});
+    await expect(addExtraAdminTx()).to.be.rejectedWith(/common\.CollectionAdminCountExceeded/);
   });
 });
modifiedtests/src/eth/contractSponsoring.test.tsdiffbeforeafterboth
--- a/tests/src/eth/contractSponsoring.test.ts
+++ b/tests/src/eth/contractSponsoring.test.ts
@@ -15,7 +15,7 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 import {expect} from 'chai';
-import { expectSubstrateEventsAtBlock } from '../util/helpers';
+import {expectSubstrateEventsAtBlock} from '../util/helpers';
 import {
   contractHelpers,
   createEthAccountWithBalance,
modifiedtests/src/eth/nesting/nest.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nesting/nest.test.ts
+++ b/tests/src/eth/nesting/nest.test.ts
@@ -20,7 +20,7 @@
   let donor: IKeyringPair;
 
   before(async function() {
-    await usingEthPlaygrounds(async (helper, privateKey) => {
+    await usingEthPlaygrounds(async (_, privateKey) => {
       donor = privateKey('//Alice');
     });
   });
modifiedtests/src/eth/payable.test.tsdiffbeforeafterboth
--- a/tests/src/eth/payable.test.ts
+++ b/tests/src/eth/payable.test.ts
@@ -22,7 +22,7 @@
   let donor: IKeyringPair;
 
   before(async function() {
-    await usingEthPlaygrounds(async (helper, privateKey) => {
+    await usingEthPlaygrounds(async (_, privateKey) => {
       donor = privateKey('//Alice');
     });
   });
addedtests/src/eth/util/playgrounds/unique.dev.d.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/util/playgrounds/unique.dev.d.ts
@@ -0,0 +1,17 @@
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
+
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
+
+declare module 'solc';
\ No newline at end of file
modifiedtests/src/eth/util/playgrounds/unique.dev.tsdiffbeforeafterboth
--- a/tests/src/eth/util/playgrounds/unique.dev.ts
+++ b/tests/src/eth/util/playgrounds/unique.dev.ts
@@ -2,6 +2,8 @@
 // SPDX-License-Identifier: Apache-2.0
 
 /* eslint-disable function-call-argument-newline */
+// eslint-disable-next-line @typescript-eslint/triple-slash-reference
+/// <reference path="unique.dev.d.ts" />
 
 import {readFile} from 'fs/promises';
 
modifiedtests/src/fungible.test.tsdiffbeforeafterboth
--- a/tests/src/fungible.test.ts
+++ b/tests/src/fungible.test.ts
@@ -16,14 +16,9 @@
 
 import {IKeyringPair} from '@polkadot/types/types';
 import {U128_MAX} from './util/helpers';
+import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
 
-import {usingPlaygrounds} from './util/playgrounds';
-
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-chai.use(chaiAsPromised);
-const expect = chai.expect;
-
+// todo:playgrounds get rid of globals
 let alice: IKeyringPair;
 let bob: IKeyringPair;
 
@@ -35,131 +30,117 @@
     });
   });
 
-  it('Create fungible collection and token', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'trest'});
-      const defaultTokenId = await collection.getLastTokenId();
-      expect(defaultTokenId).to.be.equal(0);
+  itSub('Create fungible collection and token', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'trest'});
+    const defaultTokenId = await collection.getLastTokenId();
+    expect(defaultTokenId).to.be.equal(0);
 
-      await collection.mint(alice, {Substrate: alice.address}, U128_MAX);
-      const aliceBalance = await collection.getBalance({Substrate: alice.address});
-      const itemCountAfter = await collection.getLastTokenId();
+    await collection.mint(alice, U128_MAX);
+    const aliceBalance = await collection.getBalance({Substrate: alice.address});
+    const itemCountAfter = await collection.getLastTokenId();
 
-      expect(itemCountAfter).to.be.equal(defaultTokenId);
-      expect(aliceBalance).to.be.equal(U128_MAX);
-    });
+    expect(itemCountAfter).to.be.equal(defaultTokenId);
+    expect(aliceBalance).to.be.equal(U128_MAX);
   });
   
-  it('RPC method tokenOnewrs for fungible collection and token', async () => {
-    await usingPlaygrounds(async (helper, privateKey) => {
-      const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
-      const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
+  itSub('RPC method tokenOnewrs for fungible collection and token', async ({helper, privateKey}) => {
+    const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
+    const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
 
-      const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
 
-      await collection.mint(alice, {Substrate: alice.address}, U128_MAX);
+    await collection.mint(alice, U128_MAX);
 
-      await collection.transfer(alice, {Substrate: bob.address}, 1000n);
-      await collection.transfer(alice, ethAcc, 900n);
-      
-      for (let i = 0; i < 7; i++) {
-        await collection.transfer(alice, facelessCrowd[i], 1n);
-      } 
+    await collection.transfer(alice, {Substrate: bob.address}, 1000n);
+    await collection.transfer(alice, ethAcc, 900n);
+    
+    for (let i = 0; i < 7; i++) {
+      await collection.transfer(alice, facelessCrowd[i], 1n);
+    } 
 
-      const owners = await collection.getTop10Owners();
+    const owners = await collection.getTop10Owners();
 
-      // What to expect
-      expect(owners).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
-      expect(owners.length).to.be.equal(10);
-      
-      const eleven = privateKey('//ALice+11');
-      expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
-      expect((await collection.getTop10Owners()).length).to.be.equal(10);
-    });
+    // What to expect
+    expect(owners).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
+    expect(owners.length).to.be.equal(10);
+    
+    const eleven = privateKey('//ALice+11');
+    expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
+    expect((await collection.getTop10Owners()).length).to.be.equal(10);
   });
   
-  it('Transfer token', async () => {
-    await usingPlaygrounds(async helper => {
-      const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
-      const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      await collection.mint(alice, {Substrate: alice.address}, 500n);
+  itSub('Transfer token', async ({helper}) => {
+    const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
+    const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    await collection.mint(alice, 500n);
 
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
-      expect(await collection.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
-      expect(await collection.transfer(alice, ethAcc, 140n)).to.be.true;
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
+    expect(await collection.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
+    expect(await collection.transfer(alice, ethAcc, 140n)).to.be.true;
 
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(300n);
-      expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(60n);
-      expect(await collection.getBalance(ethAcc)).to.be.equal(140n);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(300n);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(60n);
+    expect(await collection.getBalance(ethAcc)).to.be.equal(140n);
 
-      await expect(collection.transfer(alice, {Substrate: bob.address}, 350n)).to.eventually.be.rejected;
-    });
+    await expect(collection.transfer(alice, {Substrate: bob.address}, 350n)).to.eventually.be.rejected;
   });
 
-  it('Tokens multiple creation', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+  itSub('Tokens multiple creation', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
 
-      await collection.mintWithOneOwner(alice, {Substrate: alice.address}, [
-        {value: 500n},
-        {value: 400n},
-        {value: 300n},
-      ]);
+    await collection.mintWithOneOwner(alice, [
+      {value: 500n},
+      {value: 400n},
+      {value: 300n},
+    ]);
 
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1200n);
-    });
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1200n);
   });
 
-  it('Burn some tokens ', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      await collection.mint(alice, {Substrate: alice.address}, 500n);
+  itSub('Burn some tokens ', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    await collection.mint(alice, 500n);
 
-      expect(await collection.isTokenExists(0)).to.be.true;
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
-      expect(await collection.burnTokens(alice, 499n)).to.be.true;
-      expect(await collection.isTokenExists(0)).to.be.true;
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
-    });
+    expect(await collection.isTokenExists(0)).to.be.true;
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(500n);
+    expect(await collection.burnTokens(alice, 499n)).to.be.true;
+    expect(await collection.isTokenExists(0)).to.be.true;
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
   
-  it('Burn all tokens ', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      await collection.mint(alice, {Substrate: alice.address}, 500n);
+  itSub('Burn all tokens ', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    await collection.mint(alice, 500n);
 
-      expect(await collection.isTokenExists(0)).to.be.true;
-      expect(await collection.burnTokens(alice, 500n)).to.be.true;
-      expect(await collection.isTokenExists(0)).to.be.true;
+    expect(await collection.isTokenExists(0)).to.be.true;
+    expect(await collection.burnTokens(alice, 500n)).to.be.true;
+    expect(await collection.isTokenExists(0)).to.be.true;
 
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(0n);
-      expect(await collection.getTotalPieces()).to.be.equal(0n);
-    });
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(0n);
+    expect(await collection.getTotalPieces()).to.be.equal(0n);
   });
 
-  it('Set allowance for token', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
-      await collection.mint(alice, {Substrate: alice.address}, 100n);
+  itSub('Set allowance for token', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
+    await collection.mint(alice, 100n);
 
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(100n);
-      
-      expect(await collection.approveTokens(alice, {Substrate: bob.address}, 60n)).to.be.true;
-      expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(60n);
-      expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(100n);
+    
+    expect(await collection.approveTokens(alice, {Substrate: bob.address}, 60n)).to.be.true;
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(60n);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);
 
-      expect(await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: bob.address}, 20n)).to.be.true;
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(80n);
-      expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(20n);
-      expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);
+    expect(await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: bob.address}, 20n)).to.be.true;
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(80n);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(20n);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);
 
-      await collection.burnTokensFrom(bob, {Substrate: alice.address}, 10n);
+    await collection.burnTokensFrom(bob, {Substrate: alice.address}, 10n);
 
-      expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(70n);
-      expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(30n);
-      expect(await collection.transferFrom(bob, {Substrate: alice.address}, ethAcc, 10n)).to.be.true;
-      expect(await collection.getBalance(ethAcc)).to.be.equal(10n);
-    });
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(70n);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(30n);
+    expect(await collection.transferFrom(bob, {Substrate: alice.address}, ethAcc, 10n)).to.be.true;
+    expect(await collection.getBalance(ethAcc)).to.be.equal(10n);
   });
 });
modifiedtests/src/limits.test.tsdiffbeforeafterboth
--- a/tests/src/limits.test.ts
+++ b/tests/src/limits.test.ts
@@ -15,54 +15,41 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 import {IKeyringPair} from '@polkadot/types/types';
-import usingApi from './substrate/substrate-api';
-import {
-  createCollectionExpectSuccess,
-  destroyCollectionExpectSuccess,
-  setCollectionLimitsExpectSuccess,
-  setCollectionSponsorExpectSuccess,
-  confirmSponsorshipExpectSuccess,
-  createItemExpectSuccess,
-  createItemExpectFailure,
-  transferExpectSuccess,
-  getFreeBalance,
-  waitNewBlocks, burnItemExpectSuccess,
-  requirePallets,
-  Pallets,
-} from './util/helpers';
-import {expect} from 'chai';
+import {expect, itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds} from './util/playgrounds';
 
 describe('Number of tokens per address (NFT)', () => {
   let alice: IKeyringPair;
 
   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.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {
-
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 20});
+  itSub.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {});
+    await collection.setLimits(alice, {accountTokenOwnershipLimit: 20});
+    
     for(let i = 0; i < 10; i++){
-      await createItemExpectSuccess(alice, collectionId, 'NFT');
+      await expect(collection.mintToken(alice)).to.be.not.rejected;
     }
-    await createItemExpectFailure(alice, collectionId, 'NFT');
+    await expect(collection.mintToken(alice)).to.be.rejectedWith(/common\.AccountTokenLimitExceeded/);
     for(let i = 1; i < 11; i++) {
-      await burnItemExpectSuccess(alice, collectionId, i);
+      await expect(collection.burnToken(alice, i)).to.be.not.rejected;
     }
-    await destroyCollectionExpectSuccess(collectionId);
+    await collection.burn(alice);
   });
-
-  it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {
+  
+  itSub('Collection limits allow lower number than chain limits, collection limits are enforced', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {});
+    await collection.setLimits(alice, {accountTokenOwnershipLimit: 1});
 
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 1});
-    await createItemExpectSuccess(alice, collectionId, 'NFT');
-    await createItemExpectFailure(alice, collectionId, 'NFT');
-    await burnItemExpectSuccess(alice, collectionId, 1);
-    await destroyCollectionExpectSuccess(collectionId);
+    await collection.mintToken(alice);
+    await expect(collection.mintToken(alice)).to.be.rejectedWith(/common\.AccountTokenLimitExceeded/);
+    
+    await collection.burnToken(alice, 1);
+    await expect(collection.burn(alice)).to.be.not.rejected;
   });
 });
 
@@ -70,38 +57,43 @@
   let alice: IKeyringPair;
 
   before(async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+    await usingPlaygrounds(async (helper, privateKey) => {
+      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
 
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
+      const donor = privateKey('//Alice');
+      [alice] = await helper.arrange.createAccounts([10n], donor);
     });
   });
 
-  it.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async () => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 20});
+  itSub.skip('Collection limits allow greater number than chain limits, chain limits are enforced', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {});
+    await collection.setLimits(alice, {accountTokenOwnershipLimit: 20});
+    
     for(let i = 0; i < 10; i++){
-      await createItemExpectSuccess(alice, collectionId, 'ReFungible');
+      await expect(collection.mintToken(alice, 10n)).to.be.not.rejected;
     }
-    await createItemExpectFailure(alice, collectionId, 'ReFungible');
+    await expect(collection.mintToken(alice, 10n)).to.be.rejectedWith(/common\.AccountTokenLimitExceeded/);
     for(let i = 1; i < 11; i++) {
-      await burnItemExpectSuccess(alice, collectionId, i, 100);
+      await expect(collection.burnToken(alice, i, 10n)).to.be.not.rejected;
     }
-    await destroyCollectionExpectSuccess(collectionId);
+    await collection.burn(alice);
   });
 
-  it('Collection limits allow lower number than chain limits, collection limits are enforced', async () => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 1});
-    await createItemExpectSuccess(alice, collectionId, 'ReFungible');
-    await createItemExpectFailure(alice, collectionId, 'ReFungible');
-    await burnItemExpectSuccess(alice, collectionId, 1, 100);
-    await destroyCollectionExpectSuccess(collectionId);
+  itSub('Collection limits allow lower number than chain limits, collection limits are enforced', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {});
+    await collection.setLimits(alice, {accountTokenOwnershipLimit: 1});
+
+    await collection.mintToken(alice);
+    await expect(collection.mintToken(alice)).to.be.rejectedWith(/common\.AccountTokenLimitExceeded/);
+    
+    await collection.burnToken(alice, 1);
+    await expect(collection.burn(alice)).to.be.not.rejected;
   });
 });
 
+// todo:playgrounds skipped ~ postponed
 describe.skip('Sponsor timeout (NFT) (only for special chain limits test)', () => {
-  let alice: IKeyringPair;
+  /*let alice: IKeyringPair;
   let bob: IKeyringPair;
   let charlie: IKeyringPair;
 
@@ -113,7 +105,7 @@
     });
   });
 
-  it.skip('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {
+  itSub.skip('Collection limits have greater timeout value than chain limits, collection limits are enforced', async ({helper}) => {
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
     await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});
     const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
@@ -137,7 +129,7 @@
     await destroyCollectionExpectSuccess(collectionId);
   });
 
-  it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {
+  itSub('Collection limits have lower timeout value than chain limits, chain limits are enforced', async ({helper}) => {
 
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
     await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});
@@ -176,7 +168,7 @@
     });
   });
 
-  it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {
+  itSub('Collection limits have greater timeout value than chain limits, collection limits are enforced', async ({helper}) => {
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
     await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});
     const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');
@@ -202,7 +194,7 @@
     await destroyCollectionExpectSuccess(collectionId);
   });
 
-  it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {
+  itSub('Collection limits have lower timeout value than chain limits, chain limits are enforced', async ({helper}) => {
 
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
     await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});
@@ -243,7 +235,7 @@
     });
   });
 
-  it('Collection limits have greater timeout value than chain limits, collection limits are enforced', async () => {
+  itSub('Collection limits have greater timeout value than chain limits, collection limits are enforced', async ({helper}) => {
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
     await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 7});
     const tokenId = await createItemExpectSuccess(alice, collectionId, 'ReFungible');
@@ -267,7 +259,7 @@
     await destroyCollectionExpectSuccess(collectionId);
   });
 
-  it('Collection limits have lower timeout value than chain limits, chain limits are enforced', async () => {
+  itSub('Collection limits have lower timeout value than chain limits, chain limits are enforced', async ({helper}) => {
 
     const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
     await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 1});
@@ -290,7 +282,7 @@
     expect(aliceBalanceAfterSponsoredTransaction < aliceBalanceBefore).to.be.true;
     //expect(aliceBalanceAfterSponsoredTransaction).to.be.lessThan(aliceBalanceBefore);
     await destroyCollectionExpectSuccess(collectionId);
-  });
+  });*/
 });
 
 describe('Collection zero limits (NFT)', () => {
@@ -299,38 +291,38 @@
   let charlie: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      charlie = privateKeyWrapper('//Charlie');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
     });
   });
 
-  it.skip('Limits have 0 in tokens per address field, the chain limits are applied', async () => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 0});
+  itSub.skip('Limits have 0 in tokens per address field, the chain limits are applied', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {});
+    await collection.setLimits(alice, {accountTokenOwnershipLimit: 0});
+
     for(let i = 0; i < 10; i++){
-      await createItemExpectSuccess(alice, collectionId, 'NFT');
+      await collection.mintToken(alice);
     }
-    await createItemExpectFailure(alice, collectionId, 'NFT');
+    await expect(collection.mintToken(alice)).to.be.rejectedWith(/common\.AccountTokenLimitExceeded/);
   });
 
-  it('Limits have 0 in sponsor timeout, no limits are applied', async () => {
+  itSub('Limits have 0 in sponsor timeout, no limits are applied', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {});
+    await collection.setLimits(alice, {sponsorTransferTimeout: 0});
+    const token = await collection.mintToken(alice);
 
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});
-    const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
-    await setCollectionSponsorExpectSuccess(collectionId, alice.address);
-    await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
-    await transferExpectSuccess(collectionId, tokenId, alice, bob);
-    const aliceBalanceBefore = await getFreeBalance(alice);
+    await collection.setSponsor(alice, alice.address);
+    await collection.confirmSponsorship(alice);
+    
+    await token.transfer(alice, {Substrate: bob.address});
+    const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);
 
     // check setting SponsorTimeout = 0, success with next block
-    await waitNewBlocks(1);
-    await transferExpectSuccess(collectionId, tokenId, bob, charlie);
-    const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);
+    await helper.wait.newBlocks(1);
+    await token.transfer(bob, {Substrate: charlie.address});
+    const aliceBalanceAfterSponsoredTransaction1 = await helper.balance.getSubstrate(alice.address);
     expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;
-    //expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);
   });
 });
 
@@ -340,29 +332,28 @@
   let charlie: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      charlie = privateKeyWrapper('//Charlie');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
     });
   });
 
-  it('Limits have 0 in sponsor timeout, no limits are applied', async () => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});
-    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible');
-    await setCollectionSponsorExpectSuccess(collectionId, alice.address);
-    await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
-    await transferExpectSuccess(collectionId, tokenId, alice, bob, 10, 'Fungible');
-    const aliceBalanceBefore = await getFreeBalance(alice);
-    await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');
+  itSub('Limits have 0 in sponsor timeout, no limits are applied', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {});
+    await collection.setLimits(alice, {sponsorTransferTimeout: 0});
+    await collection.mint(alice, 3n);
+
+    await collection.setSponsor(alice, alice.address);
+    await collection.confirmSponsorship(alice);
+    
+    await collection.transfer(alice, {Substrate: bob.address}, 2n);
+    const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);
 
     // check setting SponsorTimeout = 0, success with next block
-    await waitNewBlocks(1);
-    await transferExpectSuccess(collectionId, tokenId, bob, charlie, 2, 'Fungible');
-    const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);
+    await helper.wait.newBlocks(1);
+    await collection.transfer(bob, {Substrate: charlie.address});
+    const aliceBalanceAfterSponsoredTransaction1 = await helper.balance.getSubstrate(alice.address);
     expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;
-    //expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);
   });
 });
 
@@ -372,110 +363,112 @@
   let charlie: IKeyringPair;
 
   before(async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+    await usingPlaygrounds(async (helper, privateKey) => {
+      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
 
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      charlie = privateKeyWrapper('//Charlie');
+      const donor = privateKey('//Alice');
+      [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
     });
   });
 
-  it.skip('Limits have 0 in tokens per address field, the chain limits are applied', async () => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {accountTokenOwnershipLimit: 0});
+  itSub.skip('Limits have 0 in tokens per address field, the chain limits are applied', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {});
+    await collection.setLimits(alice, {accountTokenOwnershipLimit: 0});
     for(let i = 0; i < 10; i++){
-      await createItemExpectSuccess(alice, collectionId, 'ReFungible');
+      await collection.mintToken(alice);
     }
-    await createItemExpectFailure(alice, collectionId, 'ReFungible');
+    await expect(collection.mintToken(alice)).to.be.rejectedWith(/common\.AccountTokenLimitExceeded/);
   });
 
-  it('Limits have 0 in sponsor timeout, no limits are applied', async () => {
+  itSub('Limits have 0 in sponsor timeout, no limits are applied', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {});
+    await collection.setLimits(alice, {sponsorTransferTimeout: 0});
+    const token = await collection.mintToken(alice, 3n);
 
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsorTransferTimeout: 0});
-    const tokenId = await createItemExpectSuccess(alice, collectionId, 'ReFungible');
-    await setCollectionSponsorExpectSuccess(collectionId, alice.address);
-    await confirmSponsorshipExpectSuccess(collectionId, '//Alice');
-    await transferExpectSuccess(collectionId, tokenId, alice, bob, 100, 'ReFungible');
-    await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');
-    const aliceBalanceBefore = await getFreeBalance(alice);
+    await collection.setSponsor(alice, alice.address);
+    await collection.confirmSponsorship(alice);
+    
+    await token.transfer(alice, {Substrate: bob.address}, 2n);
+    const aliceBalanceBefore = await helper.balance.getSubstrate(alice.address);
 
     // check setting SponsorTimeout = 0, success with next block
-    await waitNewBlocks(1);
-    await transferExpectSuccess(collectionId, tokenId, bob, charlie, 20, 'ReFungible');
-    const aliceBalanceAfterSponsoredTransaction1 = await getFreeBalance(alice);
+    await helper.wait.newBlocks(1);
+    await token.transfer(bob, {Substrate: charlie.address});
+    const aliceBalanceAfterSponsoredTransaction1 = await helper.balance.getSubstrate(alice.address);
     expect(aliceBalanceAfterSponsoredTransaction1 < aliceBalanceBefore).to.be.true;
-    //expect(aliceBalanceAfterSponsoredTransaction1).to.be.lessThan(aliceBalanceBefore);
   });
-  
-  it('Effective collection limits', async () => {
-    await usingApi(async (api) => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
-      
-      { // Check that limits is undefined
-        const collection = await api.rpc.unique.collectionById(collectionId);
-        expect(collection.isSome).to.be.true;
-        const limits = collection.unwrap().limits;
-        expect(limits).to.be.any;
-        
-        expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.null;
-        expect(limits.sponsoredDataSize.toHuman()).to.be.null;
-        expect(limits.sponsoredDataRateLimit.toHuman()).to.be.null;
-        expect(limits.tokenLimit.toHuman()).to.be.null;
-        expect(limits.sponsorTransferTimeout.toHuman()).to.be.null;
-        expect(limits.sponsorApproveTimeout.toHuman()).to.be.null;
-        expect(limits.ownerCanTransfer.toHuman()).to.be.true;
-        expect(limits.ownerCanDestroy.toHuman()).to.be.null;
-        expect(limits.transfersEnabled.toHuman()).to.be.null;
-      }
-  
-      { // Check that limits is undefined for non-existent collection
-        const limits = await api.rpc.unique.effectiveCollectionLimits(11111);
-        expect(limits.toHuman()).to.be.null;
-      }
-  
-      { // Check that default values defined for collection limits
-        const limitsOpt = await api.rpc.unique.effectiveCollectionLimits(collectionId);
-        expect(limitsOpt.isNone).to.be.false;
-        const limits = limitsOpt.unwrap();
-  
-        expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.eq('100,000');
-        expect(limits.sponsoredDataSize.toHuman()).to.be.eq('2,048');
-        expect(limits.sponsoredDataRateLimit.toHuman()).to.be.eq('SponsoringDisabled');
-        expect(limits.tokenLimit.toHuman()).to.be.eq('4,294,967,295');
-        expect(limits.sponsorTransferTimeout.toHuman()).to.be.eq('5');
-        expect(limits.sponsorApproveTimeout.toHuman()).to.be.eq('5');
-        expect(limits.ownerCanTransfer.toHuman()).to.be.true;
-        expect(limits.ownerCanDestroy.toHuman()).to.be.true;
-        expect(limits.transfersEnabled.toHuman()).to.be.true;
-      }
+});
 
-      { //Check the values for collection limits
-        await setCollectionLimitsExpectSuccess(alice, collectionId, {
-          accountTokenOwnershipLimit: 99_999,
-          sponsoredDataSize: 1024,
-          tokenLimit: 123,
-          transfersEnabled: false,
-        });
+describe('Effective collection limits (NFT)', () => {
+  let alice: IKeyringPair;
 
-        const limitsOpt = await api.rpc.unique.effectiveCollectionLimits(collectionId);
-        expect(limitsOpt.isNone).to.be.false;
-        const limits = limitsOpt.unwrap();
-  
-        expect(limits.accountTokenOwnershipLimit.toHuman()).to.be.eq('99,999');
-        expect(limits.sponsoredDataSize.toHuman()).to.be.eq('1,024');
-        expect(limits.sponsoredDataRateLimit.toHuman()).to.be.eq('SponsoringDisabled');
-        expect(limits.tokenLimit.toHuman()).to.be.eq('123');
-        expect(limits.sponsorTransferTimeout.toHuman()).to.be.eq('5');
-        expect(limits.sponsorApproveTimeout.toHuman()).to.be.eq('5');
-        expect(limits.ownerCanTransfer.toHuman()).to.be.true;
-        expect(limits.ownerCanDestroy.toHuman()).to.be.true;
-        expect(limits.transfersEnabled.toHuman()).to.be.false;
-      }
+  before(async () => {
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice] = await helper.arrange.createAccounts([10n], donor);
     });
   });
-});
+  
+  itSub('Effective collection limits', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {});
+    await collection.setLimits(alice, {ownerCanTransfer: true});    
+    
+    { 
+      // Check that limits are undefined
+      const collectionInfo = await collection.getData();
+      const limits = collectionInfo?.raw.limits;
+      expect(limits).to.be.any;
+      
+      expect(limits.accountTokenOwnershipLimit).to.be.null;
+      expect(limits.sponsoredDataSize).to.be.null;
+      expect(limits.sponsoredDataRateLimit).to.be.null;
+      expect(limits.tokenLimit).to.be.null;
+      expect(limits.sponsorTransferTimeout).to.be.null;
+      expect(limits.sponsorApproveTimeout).to.be.null;
+      expect(limits.ownerCanTransfer).to.be.true;
+      expect(limits.ownerCanDestroy).to.be.null;
+      expect(limits.transfersEnabled).to.be.null;
+    }
+
+    { // Check that limits is undefined for non-existent collection
+      const limits = await helper.collection.getEffectiveLimits(999999);
+      expect(limits).to.be.null;
+    }
 
+    { // Check that default values defined for collection limits
+      const limits = await collection.getEffectiveLimits();
 
+      expect(limits.accountTokenOwnershipLimit).to.be.eq(100000);
+      expect(limits.sponsoredDataSize).to.be.eq(2048);
+      expect(limits.sponsoredDataRateLimit).to.be.deep.eq({sponsoringDisabled: null});
+      expect(limits.tokenLimit).to.be.eq(4294967295);
+      expect(limits.sponsorTransferTimeout).to.be.eq(5);
+      expect(limits.sponsorApproveTimeout).to.be.eq(5);
+      expect(limits.ownerCanTransfer).to.be.true;
+      expect(limits.ownerCanDestroy).to.be.true;
+      expect(limits.transfersEnabled).to.be.true;
+    }
+
+    { 
+      // Check the values for collection limits
+      await collection.setLimits(alice, {
+        accountTokenOwnershipLimit: 99_999,
+        sponsoredDataSize: 1024,
+        tokenLimit: 123,
+        transfersEnabled: false,
+      });
+
+      const limits = await collection.getEffectiveLimits();
+
+      expect(limits.accountTokenOwnershipLimit).to.be.eq(99999);
+      expect(limits.sponsoredDataSize).to.be.eq(1024);
+      expect(limits.sponsoredDataRateLimit).to.be.deep.eq({sponsoringDisabled: null});
+      expect(limits.tokenLimit).to.be.eq(123);
+      expect(limits.sponsorTransferTimeout).to.be.eq(5);
+      expect(limits.sponsorApproveTimeout).to.be.eq(5);
+      expect(limits.ownerCanTransfer).to.be.true;
+      expect(limits.ownerCanDestroy).to.be.true;
+      expect(limits.transfersEnabled).to.be.false;
+    }
+  });
+});
modifiedtests/src/nextSponsoring.test.tsdiffbeforeafterboth
--- a/tests/src/nextSponsoring.test.ts
+++ b/tests/src/nextSponsoring.test.ts
@@ -14,100 +14,84 @@
 // 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 {ApiPromise} from '@polkadot/api';
 import {IKeyringPair} from '@polkadot/types/types';
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-import {default as usingApi} from './substrate/substrate-api';
-import {
-  createCollectionExpectSuccess,
-  setCollectionSponsorExpectSuccess,
-  confirmSponsorshipExpectSuccess,
-  createItemExpectSuccess,
-  transferExpectSuccess,
-  normalizeAccountId,
-  getNextSponsored,
-  requirePallets,
-  Pallets,
-} from './util/helpers';
-
-chai.use(chaiAsPromised);
-const expect = chai.expect;
+import {expect, itSub, Pallets, usingPlaygrounds} from './util/playgrounds';
 
+const SPONSORING_TIMEOUT = 5;
 
-
 describe('Integration Test getNextSponsored(collection_id, owner, item_id):', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
 
   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([20n, 10n], donor);
     });
   });
 
-  it('NFT', async () => {
-    await usingApi(async (api: ApiPromise) => {
+  itSub('NFT', async ({helper}) => {
+    // Non-existing collection
+    expect(await helper.collection.getTokenNextSponsored(0, 0, {Substrate: alice.address})).to.be.null;
 
-      // Not existing collection 
-      expect(await getNextSponsored(api, 0, normalizeAccountId(alice), 0)).to.be.equal(-1);
+    const collection = await helper.nft.mintCollection(alice, {});
+    const token = await collection.mintToken(alice);
 
-      const collectionId = await createCollectionExpectSuccess();
-      const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', alice.address);
+    // Check with Disabled sponsoring state
+    expect(await token.getNextSponsored({Substrate: alice.address})).to.be.null;
+    
+    // Check with Unconfirmed sponsoring state
+    await collection.setSponsor(alice, bob.address);
+    expect(await token.getNextSponsored({Substrate: alice.address})).to.be.null;
 
-      // Check with Disabled sponsoring state
-      expect(await getNextSponsored(api, collectionId, normalizeAccountId(alice), itemId)).to.be.equal(-1);
-      await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+    // Check with Confirmed sponsoring state
+    await collection.confirmSponsorship(bob);
+    expect(await token.getNextSponsored({Substrate: alice.address})).to.be.equal(0);
 
-      // Check with Unconfirmed sponsoring state
-      expect(await getNextSponsored(api, collectionId, normalizeAccountId(alice), itemId)).to.be.equal(-1);
-      await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
+    // Check after transfer
+    await token.transfer(alice, {Substrate: bob.address});
+    expect(await token.getNextSponsored({Substrate: alice.address})).to.be.lessThanOrEqual(SPONSORING_TIMEOUT);
 
-      // Check with Confirmed sponsoring state
-      expect(await getNextSponsored(api, collectionId, normalizeAccountId(alice), itemId)).to.be.equal(0);
+    // Non-existing token 
+    expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.null;
+  });
 
-      // After transfer
-      await transferExpectSuccess(collectionId, itemId, alice, bob, 1);
-      expect(await getNextSponsored(api, collectionId, normalizeAccountId(alice), itemId)).to.be.lessThanOrEqual(5);
+  itSub('Fungible', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {});
+    await collection.mint(alice, 10n);
 
-      // Not existing token 
-      expect(await getNextSponsored(api, collectionId, normalizeAccountId(alice), itemId+1)).to.be.equal(-1);
-    });
-  });
+    // Check with Disabled sponsoring state
+    expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.null;
 
-  it('Fungible', async () => {
-    await usingApi(async (api: ApiPromise) => {
-
-      const createMode = 'Fungible';
-      const funCollectionId = await createCollectionExpectSuccess({mode: {type: createMode, decimalPoints: 0}});
-      await createItemExpectSuccess(alice, funCollectionId, createMode);
-      await setCollectionSponsorExpectSuccess(funCollectionId, bob.address);
-      await confirmSponsorshipExpectSuccess(funCollectionId, '//Bob');
-      expect(await getNextSponsored(api, funCollectionId, normalizeAccountId(alice), 0)).to.be.equal(0);
+    await collection.setSponsor(alice, bob.address);
+    await collection.confirmSponsorship(bob);
+    
+    // Check with Confirmed sponsoring state
+    expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.equal(0);
 
-      await transferExpectSuccess(funCollectionId, 0, alice, bob, 10, 'Fungible');
-      expect(await getNextSponsored(api, funCollectionId, normalizeAccountId(alice), 0)).to.be.lessThanOrEqual(5);
-    });
+    // Check after transfer
+    await collection.transfer(alice, {Substrate: bob.address});
+    expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.lessThanOrEqual(SPONSORING_TIMEOUT);
   });
 
-  it('ReFungible', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub.ifWithPallets('ReFungible', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {});
+    const token = await collection.mintToken(alice, 10n);
 
-    await usingApi(async (api: ApiPromise) => {
+    // Check with Disabled sponsoring state
+    expect(await token.getNextSponsored({Substrate: alice.address})).to.be.null;
 
-      const createMode = 'ReFungible';
-      const refunCollectionId = await createCollectionExpectSuccess({mode: {type: createMode}});
-      const refunItemId = await createItemExpectSuccess(alice, refunCollectionId, createMode);
-      await setCollectionSponsorExpectSuccess(refunCollectionId, bob.address);
-      await confirmSponsorshipExpectSuccess(refunCollectionId, '//Bob');
-      expect(await getNextSponsored(api, refunCollectionId, normalizeAccountId(alice), refunItemId)).to.be.equal(0);
+    await collection.setSponsor(alice, bob.address);
+    await collection.confirmSponsorship(bob);
+
+    // Check with Confirmed sponsoring state
+    expect(await token.getNextSponsored({Substrate: alice.address})).to.be.equal(0);
 
-      await transferExpectSuccess(refunCollectionId, refunItemId, alice, bob, 10, 'ReFungible');
-      expect(await getNextSponsored(api, refunCollectionId, normalizeAccountId(alice), refunItemId)).to.be.lessThanOrEqual(5);
+    // Check after transfer
+    await token.transfer(alice, {Substrate: bob.address});
+    expect(await token.getNextSponsored({Substrate: alice.address})).to.be.lessThanOrEqual(SPONSORING_TIMEOUT);
 
-      // Not existing token 
-      expect(await getNextSponsored(api, refunCollectionId, normalizeAccountId(alice), refunItemId+1)).to.be.equal(-1);
-    });
+    // Non-existing token 
+    expect(await collection.getTokenNextSponsored(0, {Substrate: alice.address})).to.be.null;
   });
 });
modifiedtests/src/overflow.test.tsdiffbeforeafterboth
--- a/tests/src/overflow.test.ts
+++ b/tests/src/overflow.test.ts
@@ -23,6 +23,7 @@
 chai.use(chaiAsPromised);
 const expect = chai.expect;
 
+// todo:playgrounds skipped ~ postponed
 describe.skip('Integration Test fungible overflows', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
modifiedtests/src/pallet-presence.test.tsdiffbeforeafterboth
--- a/tests/src/pallet-presence.test.ts
+++ b/tests/src/pallet-presence.test.ts
@@ -14,13 +14,7 @@
 // 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 {ApiPromise} from '@polkadot/api';
-import {expect} from 'chai';
-import usingApi from './substrate/substrate-api';
-
-function getModuleNames(api: ApiPromise): string[] {
-  return api.runtimeMetadata.asLatest.pallets.map(m => m.name.toString().toLowerCase());
-}
+import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
 
 // Pallets that must always be present
 const requiredPallets = [
@@ -62,8 +56,8 @@
 
 describe('Pallet presence', () => {
   before(async () => {
-    await usingApi(async api => {
-      const chain = await api.rpc.system.chain();
+    await usingPlaygrounds(async helper => {
+      const chain = await helper.api!.rpc.system.chain();
 
       const refungible = 'refungible';
       const scheduler = 'scheduler';
@@ -80,23 +74,15 @@
     });
   });
 
-  it('Required pallets are present', async () => {
-    await usingApi(async api => {
-      for (let i=0; i<requiredPallets.length; i++) {
-        expect(getModuleNames(api)).to.include(requiredPallets[i]);
-      }
-    });
+  itSub('Required pallets are present', async ({helper}) => {
+    expect(helper.fetchAllPalletNames()).to.contain.members([...requiredPallets]);
   });
-  it('Governance and consensus pallets are present', async () => {
-    await usingApi(async api => {
-      for (let i=0; i<consensusPallets.length; i++) {
-        expect(getModuleNames(api)).to.include(consensusPallets[i]);
-      }
-    });
+
+  itSub('Governance and consensus pallets are present', async ({helper}) => {
+    expect(helper.fetchAllPalletNames()).to.contain.members([...consensusPallets]);
   });
-  it('No extra pallets are included', async () => {
-    await usingApi(async api => {
-      expect(getModuleNames(api).sort()).to.be.deep.equal([...requiredPallets, ...consensusPallets].sort());
-    });
+
+  itSub('No extra pallets are included', async ({helper}) => {
+    expect(helper.fetchAllPalletNames().sort()).to.be.deep.equal([...requiredPallets, ...consensusPallets].sort());
   });
 });
modifiedtests/src/refungible.test.tsdiffbeforeafterboth
--- a/tests/src/refungible.test.ts
+++ b/tests/src/refungible.test.ts
@@ -15,18 +15,7 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 import {IKeyringPair} from '@polkadot/types/types';
-
-import {usingPlaygrounds} from './util/playgrounds';
-import {
-  getModuleNames,
-  Pallets,
-  requirePallets,
-} from './util/helpers';
-
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-chai.use(chaiAsPromised);
-const expect = chai.expect;
+import {itSub, Pallets, requirePalletsOrSkip, usingPlaygrounds, expect} from './util/playgrounds';
 
 let alice: IKeyringPair;
 let bob: IKeyringPair;
@@ -34,255 +23,231 @@
 
 describe('integration test: Refungible functionality:', async () => {
   before(async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+    await usingPlaygrounds(async (helper, privateKey) => {
+      requirePalletsOrSkip(this, helper, [Pallets.ReFungible]);
 
-    await usingPlaygrounds(async (helper, privateKey) => {
       alice = privateKey('//Alice');
       bob = privateKey('//Bob');
-      if (!getModuleNames(helper.api!).includes(Pallets.ReFungible)) this.skip();
     });
   });
   
-  it('Create refungible collection and token', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+  itSub('Create refungible collection and token', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
 
-      const itemCountBefore = await collection.getLastTokenId();
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
-      
-      const itemCountAfter = await collection.getLastTokenId();
-      
-      // What to expect
-      expect(token?.tokenId).to.be.gte(itemCountBefore);
-      expect(itemCountAfter).to.be.equal(itemCountBefore + 1);
-      expect(itemCountAfter.toString()).to.be.equal(token?.tokenId.toString());
-    });
+    const itemCountBefore = await collection.getLastTokenId();
+    const token = await collection.mintToken(alice, 100n);
+    
+    const itemCountAfter = await collection.getLastTokenId();
+    
+    // What to expect
+    expect(token?.tokenId).to.be.gte(itemCountBefore);
+    expect(itemCountAfter).to.be.equal(itemCountBefore + 1);
+    expect(itemCountAfter.toString()).to.be.equal(token?.tokenId.toString());
   });
   
-  it('Checking RPC methods when interacting with maximum allowed values (MAX_REFUNGIBLE_PIECES)', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, MAX_REFUNGIBLE_PIECES);
-      
-      expect(await collection.getTokenBalance(token.tokenId, {Substrate: alice.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);
-      
-      await collection.transferToken(alice, token.tokenId, {Substrate: bob.address}, MAX_REFUNGIBLE_PIECES);
-      expect(await collection.getTokenBalance(token.tokenId, {Substrate: bob.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);
-      expect(await token.getTotalPieces()).to.be.equal(MAX_REFUNGIBLE_PIECES);
-      
-      await expect(collection.mintToken(alice, {Substrate: alice.address}, MAX_REFUNGIBLE_PIECES + 1n)).to.eventually.be.rejected;
-    });
+  itSub('Checking RPC methods when interacting with maximum allowed values (MAX_REFUNGIBLE_PIECES)', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    
+    const token = await collection.mintToken(alice, MAX_REFUNGIBLE_PIECES);
+    
+    expect(await collection.getTokenBalance(token.tokenId, {Substrate: alice.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);
+    
+    await collection.transferToken(alice, token.tokenId, {Substrate: bob.address}, MAX_REFUNGIBLE_PIECES);
+    expect(await collection.getTokenBalance(token.tokenId, {Substrate: bob.address})).to.be.equal(MAX_REFUNGIBLE_PIECES);
+    expect(await token.getTotalPieces()).to.be.equal(MAX_REFUNGIBLE_PIECES);
+    
+    await expect(collection.mintToken(alice, MAX_REFUNGIBLE_PIECES + 1n))
+      .to.eventually.be.rejectedWith(/refungible\.WrongRefungiblePieces/);
   });
   
-  it('RPC method tokenOnewrs for refungible collection and token', async () => {
-    await usingPlaygrounds(async (helper, privateKey) => {
-      const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
-      const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
+  itSub('RPC method tokenOnewrs for refungible collection and token', async ({helper, privateKey}) => {
+    const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
+    const facelessCrowd = Array(7).fill(0).map((_, i) => ({Substrate: privateKey(`//Alice+${i}`).address}));
 
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
 
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 10_000n);
+    const token = await collection.mintToken(alice, 10_000n);
 
-      await token.transfer(alice, {Substrate: bob.address}, 1000n);
-      await token.transfer(alice, ethAcc, 900n);
-      
-      for (let i = 0; i < 7; i++) {
-        await token.transfer(alice, facelessCrowd[i], 50n * BigInt(i + 1));
-      } 
+    await token.transfer(alice, {Substrate: bob.address}, 1000n);
+    await token.transfer(alice, ethAcc, 900n);
+    
+    for (let i = 0; i < 7; i++) {
+      await token.transfer(alice, facelessCrowd[i], 50n * BigInt(i + 1));
+    } 
 
-      const owners = await token.getTop10Owners();
+    const owners = await token.getTop10Owners();
 
-      // What to expect
-      expect(owners).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
-      expect(owners.length).to.be.equal(10);
-      
-      const eleven = privateKey('//ALice+11');
-      expect(await token.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
-      expect((await token.getTop10Owners()).length).to.be.equal(10);
-    });
+    // What to expect
+    expect(owners).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
+    expect(owners.length).to.be.equal(10);
+    
+    const eleven = privateKey('//ALice+11');
+    expect(await token.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
+    expect((await token.getTop10Owners()).length).to.be.equal(10);
   });
   
-  it('Transfer token pieces', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+  itSub('Transfer token pieces', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, 100n);
 
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
-      expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
-      
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
-      expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
-      
-      await expect(token.transfer(alice, {Substrate: bob.address}, 41n)).to.eventually.be.rejected;
-    });
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
+    expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
+    
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
+    expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
+    
+    await expect(token.transfer(alice, {Substrate: bob.address}, 41n))
+      .to.eventually.be.rejectedWith(/common\.TokenValueTooLow/);
   });
 
-  it('Create multiple tokens', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      // TODO: fix mintMultipleTokens
-      // await collection.mintMultipleTokens(alice, [
-      //   {owner: {Substrate: alice.address}, pieces: 1n},
-      //   {owner: {Substrate: alice.address}, pieces: 2n},
-      //   {owner: {Substrate: alice.address}, pieces: 100n},
-      // ]);
-      await helper.rft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, [
-        {pieces: 1n}, 
-        {pieces: 2n}, 
-        {pieces: 100n},
-      ]);
-      const lastTokenId = await collection.getLastTokenId();
-      expect(lastTokenId).to.be.equal(3);
-      expect(await collection.getTokenBalance(lastTokenId, {Substrate: alice.address})).to.be.equal(100n);
-    });
+  itSub('Create multiple tokens', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    // TODO: fix mintMultipleTokens
+    // await collection.mintMultipleTokens(alice, [
+    //   {owner: {Substrate: alice.address}, pieces: 1n},
+    //   {owner: {Substrate: alice.address}, pieces: 2n},
+    //   {owner: {Substrate: alice.address}, pieces: 100n},
+    // ]);
+    await helper.rft.mintMultipleTokensWithOneOwner(alice, collection.collectionId, {Substrate: alice.address}, [
+      {pieces: 1n}, 
+      {pieces: 2n}, 
+      {pieces: 100n},
+    ]);
+    const lastTokenId = await collection.getLastTokenId();
+    expect(lastTokenId).to.be.equal(3);
+    expect(await collection.getTokenBalance(lastTokenId, {Substrate: alice.address})).to.be.equal(100n);
   });
 
-  it('Burn some pieces', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
-      expect(await collection.isTokenExists(token.tokenId)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
-      expect((await token.burn(alice, 99n)).success).to.be.true;
-      expect(await collection.isTokenExists(token.tokenId)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(1n);
-    });
+  itSub('Burn some pieces', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, 100n);
+    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
+    expect((await token.burn(alice, 99n)).success).to.be.true;
+    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
 
-  it('Burn all pieces', async () => {
-    await usingPlaygrounds(async helper => {   
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
-      
-      expect(await collection.isTokenExists(token.tokenId)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
+  itSub('Burn all pieces', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, 100n);
+    
+    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
 
-      expect((await token.burn(alice, 100n)).success).to.be.true;
-      expect(await collection.isTokenExists(token.tokenId)).to.be.false;
-    });
+    expect((await token.burn(alice, 100n)).success).to.be.true;
+    expect(await collection.isTokenExists(token.tokenId)).to.be.false;
   });
 
-  it('Burn some pieces for multiple users', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+  itSub('Burn some pieces for multiple users', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, 100n);
 
-      expect(await collection.isTokenExists(token.tokenId)).to.be.true;
-      
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
-      expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
+    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
+    expect(await token.transfer(alice, {Substrate: bob.address}, 60n)).to.be.true;
 
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
-      expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(40n);
+    expect(await token.getBalance({Substrate: bob.address})).to.be.equal(60n);
 
-      expect((await token.burn(alice, 40n)).success).to.be.true;
+    expect((await token.burn(alice, 40n)).success).to.be.true;
 
-      expect(await collection.isTokenExists(token.tokenId)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
+    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
 
-      expect((await token.burn(bob, 59n)).success).to.be.true;
+    expect((await token.burn(bob, 59n)).success).to.be.true;
 
-      expect(await token.getBalance({Substrate: bob.address})).to.be.equal(1n);
-      expect(await collection.isTokenExists(token.tokenId)).to.be.true;
+    expect(await token.getBalance({Substrate: bob.address})).to.be.equal(1n);
+    expect(await collection.isTokenExists(token.tokenId)).to.be.true;
 
-      expect((await token.burn(bob, 1n)).success).to.be.true;
+    expect((await token.burn(bob, 1n)).success).to.be.true;
 
-      expect(await collection.isTokenExists(token.tokenId)).to.be.false;
-    });
+    expect(await collection.isTokenExists(token.tokenId)).to.be.false;
   });
 
-  it('Set allowance for token', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
-      
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
+  itSub('Set allowance for token', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, 100n);
+    
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(100n);
 
-      expect(await token.approve(alice, {Substrate: bob.address}, 60n)).to.be.true;
-      expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(60n);
+    expect(await token.approve(alice, {Substrate: bob.address}, 60n)).to.be.true;
+    expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(60n);
 
-      expect(await token.transferFrom(bob, {Substrate: alice.address}, {Substrate: bob.address}, 20n)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(80n);
-      expect(await token.getBalance({Substrate: bob.address})).to.be.equal(20n);
-      expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);
-    });
+    expect(await token.transferFrom(bob, {Substrate: alice.address}, {Substrate: bob.address}, 20n)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(80n);
+    expect(await token.getBalance({Substrate: bob.address})).to.be.equal(20n);
+    expect(await token.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(40n);
   });
 
-  it('Repartition', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
+  itSub('Repartition', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, 100n);
 
-      expect(await token.repartition(alice, 200n)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(200n);
-      expect(await token.getTotalPieces()).to.be.equal(200n);
-      
-      expect(await token.transfer(alice, {Substrate: bob.address}, 110n)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(90n);
-      expect(await token.getBalance({Substrate: bob.address})).to.be.equal(110n);
-      
-      await expect(token.repartition(alice, 80n)).to.eventually.be.rejected;
-      
-      expect(await token.transfer(alice, {Substrate: bob.address}, 90n)).to.be.true;
-      expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
-      expect(await token.getBalance({Substrate: bob.address})).to.be.equal(200n);
-
-      expect(await token.repartition(bob, 150n)).to.be.true;
-      await expect(token.transfer(bob, {Substrate: alice.address}, 160n)).to.eventually.be.rejected;
+    expect(await token.repartition(alice, 200n)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(200n);
+    expect(await token.getTotalPieces()).to.be.equal(200n);
+    
+    expect(await token.transfer(alice, {Substrate: bob.address}, 110n)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(90n);
+    expect(await token.getBalance({Substrate: bob.address})).to.be.equal(110n);
+    
+    await expect(token.repartition(alice, 80n))
+      .to.eventually.be.rejectedWith(/refungible\.RepartitionWhileNotOwningAllPieces/);
+    
+    expect(await token.transfer(alice, {Substrate: bob.address}, 90n)).to.be.true;
+    expect(await token.getBalance({Substrate: alice.address})).to.be.equal(0n);
+    expect(await token.getBalance({Substrate: bob.address})).to.be.equal(200n);
 
-    });
+    expect(await token.repartition(bob, 150n)).to.be.true;
+    await expect(token.transfer(bob, {Substrate: alice.address}, 160n))
+      .to.eventually.be.rejectedWith(/common\.TokenValueTooLow/);
   });
 
-  it('Repartition with increased amount', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
-      await token.repartition(alice, 200n);
-      const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);
-      expect(chainEvents).to.include.deep.members([{
-        method: 'ItemCreated',
-        section: 'common',
-        index: '0x4202',
-        data: [ 
-          helper.api!.createType('u32', collection.collectionId).toHuman(), 
-          helper.api!.createType('u32', token.tokenId).toHuman(),
-          {Substrate: alice.address}, 
-          '100',
-        ],
-      }]);
-    });
+  itSub('Repartition with increased amount', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, 100n);
+    await token.repartition(alice, 200n);
+    const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);
+    expect(chainEvents).to.include.deep.members([{
+      method: 'ItemCreated',
+      section: 'common',
+      index: '0x4202',
+      data: [ 
+        helper.api!.createType('u32', collection.collectionId).toHuman(), 
+        helper.api!.createType('u32', token.tokenId).toHuman(),
+        {Substrate: alice.address}, 
+        '100',
+      ],
+    }]);
   });
 
-  it('Repartition with decreased amount', async () => {
-    await usingPlaygrounds(async helper => {
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      const token = await collection.mintToken(alice, {Substrate: alice.address}, 100n);
-      await token.repartition(alice, 50n);
-      const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);
-      expect(chainEvents).to.include.deep.members([{
-        method: 'ItemDestroyed',
-        section: 'common',
-        index: '0x4203',
-        data: [ 
-          helper.api!.createType('u32', collection.collectionId).toHuman(), 
-          helper.api!.createType('u32', token.tokenId).toHuman(),
-          {Substrate: alice.address}, 
-          '50',
-        ],
-      }]);
-    });
+  itSub('Repartition with decreased amount', async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+    const token = await collection.mintToken(alice, 100n);
+    await token.repartition(alice, 50n);
+    const chainEvents = helper.chainLog.slice(-1)[0].events.map((x: any) => x.event);
+    expect(chainEvents).to.include.deep.members([{
+      method: 'ItemDestroyed',
+      section: 'common',
+      index: '0x4203',
+      data: [ 
+        helper.api!.createType('u32', collection.collectionId).toHuman(), 
+        helper.api!.createType('u32', token.tokenId).toHuman(),
+        {Substrate: alice.address}, 
+        '50',
+      ],
+    }]);
   });
   
-  it('Create new collection with properties', async () => {
-    await usingPlaygrounds(async helper => {
-      const properties = [{key: 'key1', value: 'val1'}];
-      const tokenPropertyPermissions = [{key: 'key1', permission: {tokenOwner: true, mutable: false, collectionAdmin: true}}];
-      const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test', properties, tokenPropertyPermissions});
-      const info = await collection.getData();
-      expect(info?.raw.properties).to.be.deep.equal(properties);
-      expect(info?.raw.tokenPropertyPermissions).to.be.deep.equal(tokenPropertyPermissions);
-    });
+  itSub('Create new collection with properties', async ({helper}) => {
+    const properties = [{key: 'key1', value: 'val1'}];
+    const tokenPropertyPermissions = [{key: 'key1', permission: {tokenOwner: true, mutable: false, collectionAdmin: true}}];
+    const collection = await helper.rft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test', properties, tokenPropertyPermissions});
+    const info = await collection.getData();
+    expect(info?.raw.properties).to.be.deep.equal(properties);
+    expect(info?.raw.tokenPropertyPermissions).to.be.deep.equal(tokenPropertyPermissions);
   });
 });
 
modifiedtests/src/removeCollectionAdmin.test.tsdiffbeforeafterboth
--- a/tests/src/removeCollectionAdmin.test.ts
+++ b/tests/src/removeCollectionAdmin.test.ts
@@ -14,115 +14,99 @@
 // 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 chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-import {usingPlaygrounds} from './util/playgrounds';
+import {IKeyringPair} from '@polkadot/types/types';
+import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
 
-chai.use(chaiAsPromised);
-const expect = chai.expect;
+describe('Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
 
-describe('Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
-  it('Remove collection admin.', async () => {
+  before(async () => {
     await usingPlaygrounds(async (helper, privateKey) => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-      const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      
-      const collectionInfo = await collection.getData();
-      expect(collectionInfo?.raw.owner.toString()).to.be.deep.eq(alice.address);
-      // first - add collection admin Bob
-      await collection.addAdmin(alice, {Substrate: bob.address});
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
+    });
+  });
+
+  itSub('Remove collection admin', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-1', tokenPrefix: 'RCA'});
+    const collectionInfo = await collection.getData();
+    expect(collectionInfo?.raw.owner.toString()).to.be.deep.eq(alice.address);
+    // first - add collection admin Bob
+    await collection.addAdmin(alice, {Substrate: bob.address});
 
-      const adminListAfterAddAdmin = await collection.getAdmins();
-      expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
+    const adminListAfterAddAdmin = await collection.getAdmins();
+    expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
 
-      // then remove bob from admins of collection
-      await collection.removeAdmin(alice, {Substrate: bob.address});
+    // then remove bob from admins of collection
+    await collection.removeAdmin(alice, {Substrate: bob.address});
 
-      const adminListAfterRemoveAdmin = await collection.getAdmins();
-      expect(adminListAfterRemoveAdmin).not.to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
-    });
+    const adminListAfterRemoveAdmin = await collection.getAdmins();
+    expect(adminListAfterRemoveAdmin).not.to.be.deep.contains({Substrate: bob.address});
   });
 
-  it('Remove admin from collection that has no admins', async () => {
-    await usingPlaygrounds(async (helper, privateKey) => {
-      const alice = privateKey('//Alice');
-      const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+  itSub('Remove admin from collection that has no admins', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-2', tokenPrefix: 'RCA'});
 
-      const adminListBeforeAddAdmin = await collection.getAdmins();
-      expect(adminListBeforeAddAdmin).to.have.lengthOf(0);
+    const adminListBeforeAddAdmin = await collection.getAdmins();
+    expect(adminListBeforeAddAdmin).to.have.lengthOf(0);
 
-      // await expect(collection.removeAdmin(alice, {Substrate: alice.address})).to.be.rejectedWith('Unable to remove collection admin');
-      await collection.removeAdmin(alice, {Substrate: alice.address});
-    });
+    await collection.removeAdmin(alice, {Substrate: alice.address});
   });
 });
 
 describe('Negative Integration Test removeCollectionAdmin(collection_id, account_id):', () => {
-  it('Can\'t remove collection admin from not existing collection', async () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+  let charlie: IKeyringPair;
+
+  before(async () => {
     await usingPlaygrounds(async (helper, privateKey) => {
-      // tslint:disable-next-line: no-bitwise
-      const collectionId = (1 << 32) - 1;
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
+      const donor = privateKey('//Alice');
+      [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
+    });
+  });
 
-      await expect(helper.collection.removeAdmin(alice, collectionId, {Substrate: bob.address})).to.be.rejected;
+  itSub('Can\'t remove collection admin from not existing collection', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
 
-      // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
-      await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-    });
+    await expect(helper.collection.removeAdmin(alice, collectionId, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('Can\'t remove collection admin from deleted collection', async () => {
-    await usingPlaygrounds(async (helper, privateKey) => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-      const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+  itSub('Can\'t remove collection admin from deleted collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-Neg-2', tokenPrefix: 'RCA'});
 
-      expect(await collection.burn(alice)).to.be.true;
+    expect(await collection.burn(alice)).to.be.true;
 
-      await expect(helper.collection.removeAdmin(alice, collection.collectionId, {Substrate: bob.address})).to.be.rejected;
-
-      // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
-      await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-    });
+    await expect(helper.collection.removeAdmin(alice, collection.collectionId, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('Regular user can\'t remove collection admin', async () => {
-    await usingPlaygrounds(async (helper, privateKey) => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-      const charlie = privateKey('//Charlie');
-      const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
+  itSub('Regular user can\'t remove collection admin', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-Neg-3', tokenPrefix: 'RCA'});
 
-      await collection.addAdmin(alice, {Substrate: bob.address});
+    await collection.addAdmin(alice, {Substrate: bob.address});
 
-      await expect(collection.removeAdmin(charlie, {Substrate: bob.address})).to.be.rejected;
-
-      // Verifying that nothing bad happened (network is live, new collections can be created, etc.)
-      await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-    });
+    await expect(collection.removeAdmin(charlie, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.NoPermission/);
   });
 
-  it('Admin can\'t remove collection admin.', async () => {
-    await usingPlaygrounds(async (helper, privateKey) => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-      const charlie = privateKey('//Charlie');
-      const collection = await helper.nft.mintCollection(alice, {name: 'test', description: 'test', tokenPrefix: 'test'});
-      
-      await collection.addAdmin(alice, {Substrate: bob.address});
-      await collection.addAdmin(alice, {Substrate: charlie.address});
+  itSub('Admin can\'t remove collection admin.', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionAdmin-Neg-4', tokenPrefix: 'RCA'});
+    
+    await collection.addAdmin(alice, {Substrate: bob.address});
+    await collection.addAdmin(alice, {Substrate: charlie.address});
 
-      const adminListAfterAddAdmin = await collection.getAdmins();
-      expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
-      expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(charlie.address)});
+    const adminListAfterAddAdmin = await collection.getAdmins();
+    expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: bob.address});
+    expect(adminListAfterAddAdmin).to.be.deep.contains({Substrate: charlie.address});
 
-      await expect(collection.removeAdmin(charlie, {Substrate: bob.address})).to.be.rejected;
+    await expect(collection.removeAdmin(charlie, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.NoPermission/);
 
-      const adminListAfterRemoveAdmin = await collection.getAdmins();
-      expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(bob.address)});
-      expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: helper.address.normalizeSubstrate(charlie.address)});
-    });
+    const adminListAfterRemoveAdmin = await collection.getAdmins();
+    expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: bob.address});
+    expect(adminListAfterRemoveAdmin).to.be.deep.contains({Substrate: charlie.address});
   });
 });
modifiedtests/src/removeCollectionSponsor.test.tsdiffbeforeafterboth
--- a/tests/src/removeCollectionSponsor.test.ts
+++ b/tests/src/removeCollectionSponsor.test.ts
@@ -14,138 +14,112 @@
 // 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 chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-import {default as usingApi, submitTransactionExpectFailAsync} from './substrate/substrate-api';
-import {
-  createCollectionExpectSuccess,
-  setCollectionSponsorExpectSuccess,
-  destroyCollectionExpectSuccess,
-  confirmSponsorshipExpectSuccess,
-  confirmSponsorshipExpectFailure,
-  createItemExpectSuccess,
-  findUnusedAddress,
-  removeCollectionSponsorExpectSuccess,
-  removeCollectionSponsorExpectFailure,
-  normalizeAccountId,
-  addCollectionAdminExpectSuccess,
-  getCreatedCollectionCount,
-} from './util/helpers';
 import {IKeyringPair} from '@polkadot/types/types';
-
-chai.use(chaiAsPromised);
-const expect = chai.expect;
+import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
 
-let alice: IKeyringPair;
-let bob: IKeyringPair;
-
 describe('integration test: ext. removeCollectionSponsor():', () => {
+  let donor: IKeyringPair;
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
     });
   });
 
-  it('Removing NFT collection sponsor stops sponsorship', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
-    await removeCollectionSponsorExpectSuccess(collectionId);
+  itSub('Removing NFT collection sponsor stops sponsorship', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-1', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await collection.confirmSponsorship(bob);
+    await collection.removeSponsor(alice);
 
-    await usingApi(async (api, privateKeyWrapper) => {
-      // Find unused address
-      const zeroBalance = await findUnusedAddress(api, privateKeyWrapper);
+    // Find unused address
+    const [zeroBalance] = await helper.arrange.createAccounts([0n], donor);
 
-      // Mint token for unused address
-      const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', zeroBalance.address);
+    // Mint token for unused address
+    const token = await collection.mintToken(alice, {Substrate: zeroBalance.address});
 
-      // Transfer this tokens from unused address to Alice - should fail
-      const sponsorBalanceBefore = (await api.query.system.account(bob.address)).data.free.toBigInt();
-      const zeroToAlice = api.tx.unique.transfer(normalizeAccountId(alice.address), collectionId, itemId, 0);
-      const badTransaction = async function () {
-        await submitTransactionExpectFailAsync(zeroBalance, zeroToAlice);
-      };
-      await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees');
-      const sponsorBalanceAfter = (await api.query.system.account(bob.address)).data.free.toBigInt();
+    // Transfer this tokens from unused address to Alice - should fail
+    const sponsorBalanceBefore = await helper.balance.getSubstrate(bob.address);
+    await expect(token.transfer(zeroBalance, {Substrate: alice.address}))
+      .to.be.rejectedWith('Inability to pay some fees');
+    const sponsorBalanceAfter = await helper.balance.getSubstrate(bob.address);
 
-      expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
-    });
+    expect(sponsorBalanceAfter).to.be.equal(sponsorBalanceBefore);
   });
 
-  it('Remove a sponsor after it was already removed', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
-    await removeCollectionSponsorExpectSuccess(collectionId);
-    await removeCollectionSponsorExpectSuccess(collectionId);
+  itSub('Remove a sponsor after it was already removed', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-2', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await collection.confirmSponsorship(bob);
+    await expect(collection.removeSponsor(alice)).to.not.be.rejected;
+    await expect(collection.removeSponsor(alice)).to.not.be.rejected;
   });
 
-  it('Remove sponsor in a collection that never had the sponsor set', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await removeCollectionSponsorExpectSuccess(collectionId);
+  itSub('Remove sponsor in a collection that never had the sponsor set', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-3', tokenPrefix: 'RCS'});
+    await expect(collection.removeSponsor(alice)).to.not.be.rejected;
   });
 
-  it('Remove sponsor for a collection that had the sponsor set, but not confirmed', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await removeCollectionSponsorExpectSuccess(collectionId);
+  itSub('Remove sponsor for a collection that had the sponsor set, but not confirmed', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-4', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await expect(collection.removeSponsor(alice)).to.not.be.rejected;
   });
 
 });
 
 describe('(!negative test!) integration test: ext. removeCollectionSponsor():', () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+  let charlie: IKeyringPair;
+
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
     });
   });
 
-  it('(!negative test!) Remove sponsor for a collection that never existed', async () => {
-    // Find the collection that never existed
-    let collectionId = 0;
-    await usingApi(async (api) => {
-      collectionId = await getCreatedCollectionCount(api) + 1;
-    });
-
-    await removeCollectionSponsorExpectFailure(collectionId);
+  itSub('(!negative test!) Remove sponsor for a collection that never existed', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.collection.removeSponsor(alice, collectionId)).to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('(!negative test!) Remove sponsor for a collection with collection admin permissions', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-    await removeCollectionSponsorExpectFailure(collectionId, '//Bob');
+  itSub('(!negative test!) Remove sponsor for a collection with collection admin permissions', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-1', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await collection.addAdmin(alice, {Substrate: charlie.address});
+    await expect(collection.removeSponsor(charlie)).to.be.rejectedWith(/common\.NoPermission/);
   });
 
-  it('(!negative test!) Remove sponsor for a collection by regular user', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await removeCollectionSponsorExpectFailure(collectionId, '//Bob');
+  itSub('(!negative test!) Remove sponsor for a collection by regular user', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-2', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await expect(collection.removeSponsor(charlie)).to.be.rejectedWith(/common\.NoPermission/);
   });
 
-  it('(!negative test!) Remove sponsor in a destroyed collection', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await destroyCollectionExpectSuccess(collectionId);
-    await removeCollectionSponsorExpectFailure(collectionId);
+  itSub('(!negative test!) Remove sponsor in a destroyed collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-3', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await collection.burn(alice);
+    await expect(collection.removeSponsor(alice)).to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('Set - remove - confirm: fails', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await removeCollectionSponsorExpectSuccess(collectionId);
-    await confirmSponsorshipExpectFailure(collectionId, '//Bob');
+  itSub('Set - remove - confirm: fails', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-4', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await collection.removeSponsor(alice);
+    await expect(collection.confirmSponsorship(bob)).to.be.rejectedWith(/unique\.ConfirmUnsetSponsorFail/);
   });
 
-  it('Set - confirm - remove - confirm: Sponsor cannot come back', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await confirmSponsorshipExpectSuccess(collectionId, '//Bob');
-    await removeCollectionSponsorExpectSuccess(collectionId);
-    await confirmSponsorshipExpectFailure(collectionId, '//Bob');
+  itSub('Set - confirm - remove - confirm: Sponsor cannot come back', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'RemoveCollectionSponsor-Neg-5', tokenPrefix: 'RCS'});
+    await collection.setSponsor(alice, bob.address);
+    await collection.confirmSponsorship(bob);
+    await collection.removeSponsor(alice);
+    await expect(collection.confirmSponsorship(bob)).to.be.rejectedWith(/unique\.ConfirmUnsetSponsorFail/);
   });
-
 });
modifiedtests/src/removeFromAllowList.test.tsdiffbeforeafterboth
14// You should have received a copy of the GNU General Public License14// You should have received a copy of the GNU General Public License
15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
1616
17import chai from 'chai';
18import chaiAsPromised from 'chai-as-promised';
19import {default as usingApi} from './substrate/substrate-api';17import {IKeyringPair} from '@polkadot/types/types';
20import {18import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
21 createCollectionExpectSuccess,
22 destroyCollectionExpectSuccess,
23 enableAllowListExpectSuccess,
24 addToAllowListExpectSuccess,
25 removeFromAllowListExpectSuccess,
26 isAllowlisted,
27 findNotExistingCollection,
28 removeFromAllowListExpectFailure,
29 disableAllowListExpectSuccess,
30 normalizeAccountId,
31 addCollectionAdminExpectSuccess,
32} from './util/helpers';
33import {IKeyringPair} from '@polkadot/types/types';
34
35chai.use(chaiAsPromised);
36const expect = chai.expect;
3719
38describe('Integration Test removeFromAllowList', () => {20describe('Integration Test removeFromAllowList', () => {
39 let alice: IKeyringPair;21 let alice: IKeyringPair;
40 let bob: IKeyringPair;22 let bob: IKeyringPair;
4123
42 before(async () => {24 before(async () => {
43 await usingApi(async (api, privateKeyWrapper) => {25 await usingPlaygrounds(async (helper, privateKey) => {
44 alice = privateKeyWrapper('//Alice');26 const donor = privateKey('//Alice');
45 bob = privateKeyWrapper('//Bob');27 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
46 });28 });
47 });29 });
4830
49 it('ensure bob is not in allowlist after removal', async () => {31 itSub('ensure bob is not in allowlist after removal', async ({helper}) => {
50 await usingApi(async api => {32 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-1', tokenPrefix: 'RFAL'});
33
34 const collectionInfo = await collection.getData();
51 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});35 expect(collectionInfo!.raw.permissions.access).to.not.equal('AllowList');
36
52 await enableAllowListExpectSuccess(alice, collectionId);37 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
53 await addToAllowListExpectSuccess(alice, collectionId, bob.address);38 await collection.addToAllowList(alice, {Substrate: bob.address});
5439 expect(await collection.getAllowList()).to.deep.contains({Substrate: bob.address});
40
55 await removeFromAllowListExpectSuccess(alice, collectionId, normalizeAccountId(bob.address));41 await collection.removeFromAllowList(alice, {Substrate: bob.address});
56 expect(await isAllowlisted(api, collectionId, bob.address)).to.be.false;42 expect(await collection.getAllowList()).to.be.empty;
57 });
58 });43 });
5944
60 it('allows removal from collection with unset allowlist status', async () => {45 itSub('allows removal from collection with unset allowlist status', async ({helper}) => {
61 await usingApi(async () => {46 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-2', tokenPrefix: 'RFAL'});
47
62 const collectionWithoutAllowlistId = await createCollectionExpectSuccess();48 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
63 await enableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);49 await collection.addToAllowList(alice, {Substrate: bob.address});
64 await addToAllowListExpectSuccess(alice, collectionWithoutAllowlistId, bob.address);50 expect(await collection.getAllowList()).to.deep.contains({Substrate: bob.address});
51
65 await disableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);52 await collection.setPermissions(alice, {access: 'Normal'});
6653
67 await removeFromAllowListExpectSuccess(alice, collectionWithoutAllowlistId, normalizeAccountId(bob.address));54 await collection.removeFromAllowList(alice, {Substrate: bob.address});
68 });55 expect(await collection.getAllowList()).to.be.empty;
69 });56 });
70});57});
7158
74 let bob: IKeyringPair;61 let bob: IKeyringPair;
7562
76 before(async () => {63 before(async () => {
77 await usingApi(async (api, privateKeyWrapper) => {64 await usingPlaygrounds(async (helper, privateKey) => {
78 alice = privateKeyWrapper('//Alice');65 const donor = privateKey('//Alice');
79 bob = privateKeyWrapper('//Bob');66 [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
80 });67 });
81 });68 });
8269
83 it('fails on removal from not existing collection', async () => {70 itSub('fails on removal from not existing collection', async ({helper}) => {
71 const nonExistentCollectionId = (1 << 32) - 1;
84 await usingApi(async (api) => {72 await expect(helper.collection.removeFromAllowList(alice, nonExistentCollectionId, {Substrate: alice.address}))
85 const collectionId = await findNotExistingCollection(api);
86
87 await removeFromAllowListExpectFailure(alice, collectionId, normalizeAccountId(bob.address));
88 });73 .to.be.rejectedWith(/common\.CollectionNotFound/);
89 });74 });
9075
91 it('fails on removal from removed collection', async () => {76 itSub('fails on removal from removed collection', async ({helper}) => {
92 await usingApi(async () => {77 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-3', tokenPrefix: 'RFAL'});
93 const collectionId = await createCollectionExpectSuccess();78 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
94 await enableAllowListExpectSuccess(alice, collectionId);
95 await addToAllowListExpectSuccess(alice, collectionId, bob.address);79 await collection.addToAllowList(alice, {Substrate: bob.address});
80
96 await destroyCollectionExpectSuccess(collectionId);81 await collection.burn(alice);
97
98 await removeFromAllowListExpectFailure(alice, collectionId, normalizeAccountId(bob.address));82 await expect(collection.removeFromAllowList(alice, {Substrate: bob.address}))
99 });83 .to.be.rejectedWith(/common\.CollectionNotFound/);
100 });84 });
101});85});
10286
106 let charlie: IKeyringPair;90 let charlie: IKeyringPair;
10791
108 before(async () => {92 before(async () => {
109 await usingApi(async (api, privateKeyWrapper) => {93 await usingPlaygrounds(async (helper, privateKey) => {
110 alice = privateKeyWrapper('//Alice');94 const donor = privateKey('//Alice');
111 bob = privateKeyWrapper('//Bob');95 [alice, bob, charlie] = await helper.arrange.createAccounts([10n, 10n, 10n], donor);
112 charlie = privateKeyWrapper('//Charlie');
113 });96 });
114 });97 });
11598
116 it('ensure address is not in allowlist after removal', async () => {99 itSub('ensure address is not in allowlist after removal', async ({helper}) => {
117 await usingApi(async api => {100 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-4', tokenPrefix: 'RFAL'});
101
118 const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});102 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
119 await enableAllowListExpectSuccess(alice, collectionId);
120 await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);103 await collection.addAdmin(alice, {Substrate: bob.address});
104
121 await addToAllowListExpectSuccess(alice, collectionId, charlie.address);105 await collection.addToAllowList(bob, {Substrate: charlie.address});
122 await removeFromAllowListExpectSuccess(bob, collectionId, normalizeAccountId(charlie.address));106 await collection.removeFromAllowList(bob, {Substrate: charlie.address});
107
123 expect(await isAllowlisted(api, collectionId, charlie.address)).to.be.false;108 expect(await collection.getAllowList()).to.be.empty;
124 });
125 });109 });
126110
127 it('Collection admin allowed to remove from allowlist with unset allowlist status', async () => {111 itSub('Collection admin allowed to remove from allowlist with unset allowlist status', async ({helper}) => {
128 await usingApi(async () => {112 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-5', tokenPrefix: 'RFAL'});
113
129 const collectionWithoutAllowlistId = await createCollectionExpectSuccess();114 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
130 await enableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);
131 await addCollectionAdminExpectSuccess(alice, collectionWithoutAllowlistId, bob.address);115 await collection.addAdmin(alice, {Substrate: bob.address});
132 await addToAllowListExpectSuccess(alice, collectionWithoutAllowlistId, charlie.address);116 await collection.addToAllowList(alice, {Substrate: charlie.address});
117
133 await disableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);118 await collection.setPermissions(bob, {access: 'Normal'});
134 await removeFromAllowListExpectSuccess(bob, collectionWithoutAllowlistId, normalizeAccountId(charlie.address));119 await collection.removeFromAllowList(bob, {Substrate: charlie.address});
120
135 });121 expect(await collection.getAllowList()).to.be.empty;
136 });122 });
137123
138 it('Regular user can`t remove from allowlist', async () => {124 itSub('Regular user can`t remove from allowlist', async ({helper}) => {
139 await usingApi(async () => {125 const collection = await helper.nft.mintCollection(alice, {name: 'RemoveFromAllowList-6', tokenPrefix: 'RFAL'});
126
140 const collectionWithoutAllowlistId = await createCollectionExpectSuccess();127 await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
141 await enableAllowListExpectSuccess(alice, collectionWithoutAllowlistId);128 await collection.addToAllowList(alice, {Substrate: charlie.address});
129
142 await addToAllowListExpectSuccess(alice, collectionWithoutAllowlistId, charlie.address);130 await expect(collection.removeFromAllowList(bob, {Substrate: charlie.address}))
131 .to.be.rejectedWith(/common\.NoPermission/);
143 await removeFromAllowListExpectFailure(bob, collectionWithoutAllowlistId, normalizeAccountId(charlie.address));132 expect(await collection.getAllowList()).to.deep.contain({Substrate: charlie.address});
144 });
145 });133 });
146});134});
147135
modifiedtests/src/removeFromContractAllowList.test.tsdiffbeforeafterboth
--- a/tests/src/removeFromContractAllowList.test.ts
+++ b/tests/src/removeFromContractAllowList.test.ts
@@ -20,6 +20,7 @@
 import {IKeyringPair} from '@polkadot/types/types';
 import {expect} from 'chai';
 
+// todo:playgrounds skipped again
 describe.skip('Integration Test removeFromContractAllowList', () => {
   let bob: IKeyringPair;
 
modifiedtests/src/rpc.test.tsdiffbeforeafterboth
--- a/tests/src/rpc.test.ts
+++ b/tests/src/rpc.test.ts
@@ -1,57 +1,68 @@
-import {IKeyringPair} from '@polkadot/types/types';
-import {expect} from 'chai';
-import usingApi from './substrate/substrate-api';
-import {createCollection, createCollectionExpectSuccess, createFungibleItemExpectSuccess, CrossAccountId, getTokenOwner, normalizeAccountId, transfer, U128_MAX} from './util/helpers';
+// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
+// This file is part of Unique Network.
 
-let alice: IKeyringPair;
-let bob: IKeyringPair;
+// Unique Network is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
 
+// Unique Network is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// 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 {IKeyringPair} from '@polkadot/types/types';
+import {usingPlaygrounds, itSub, expect} from './util/playgrounds';
+import {crossAccountIdFromLower} from './util/playgrounds/unique';
+
 describe('integration test: RPC methods', () => {
+  let donor: IKeyringPair;
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
     });
   });
 
-  
-  it('returns None for fungible collection', async () => {
-    await usingApi(async api => {
-      const collection = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      await expect(getTokenOwner(api, collection, 0)).to.be.rejectedWith(/^owner == null$/);
-    });
+  itSub('returns None for fungible collection', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'RPC-1', tokenPrefix: 'RPC'});
+    const owner = (await helper.callRpc('api.rpc.unique.tokenOwner', [collection.collectionId, 0])).toJSON() as any;
+    expect(owner).to.be.null;
   });
   
-  it('RPC method tokenOwners for fungible collection and token', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
-      const facelessCrowd = Array.from(Array(7).keys()).map(i => normalizeAccountId(privateKeyWrapper(i.toString())));
-      
-      const createCollectionResult = await createCollection(api, alice, {mode: {type: 'Fungible', decimalPoints: 0}});
-      const collectionId = createCollectionResult.collectionId;
-      const aliceTokenId = await createFungibleItemExpectSuccess(alice, collectionId, {Value: U128_MAX}, alice.address);
-     
-      await transfer(api, collectionId, aliceTokenId, alice, bob, 1000n);
-      await transfer(api, collectionId, aliceTokenId, alice, ethAcc, 900n);
-            
-      for (let i = 0; i < 7; i++) {
-        await transfer(api, collectionId, aliceTokenId, alice, facelessCrowd[i], 1);
-      } 
-      
-      const owners = await api.rpc.unique.tokenOwners(collectionId, aliceTokenId);
-      const ids = (owners.toJSON() as CrossAccountId[]).map(s => normalizeAccountId(s));
-      const aliceID = normalizeAccountId(alice);
-      const bobId = normalizeAccountId(bob);
+  itSub('RPC method tokenOwners for fungible collection and token', async ({helper}) => {
+    // Set-up a few token owners of all stripes
+    const ethAcc = {Ethereum: '0x67fb3503a61b284dc83fa96dceec4192db47dc7c'};
+    const facelessCrowd = (await helper.arrange.createAccounts([0n, 0n, 0n, 0n, 0n, 0n, 0n], donor))
+      .map(i => {return {Substrate: i.address};});
+    
+    const collection = await helper.ft.mintCollection(alice, {name: 'RPC-2', tokenPrefix: 'RPC'});
+    // mint some maximum (u128) amounts of tokens possible
+    await collection.mint(alice, (1n << 128n) - 1n);
+    
+    await collection.transfer(alice, {Substrate: bob.address}, 1000n);
+    await collection.transfer(alice, ethAcc, 900n);
+          
+    for (let i = 0; i < facelessCrowd.length; i++) {
+      await collection.transfer(alice, facelessCrowd[i], 1n);
+    }
+    // Set-up over
+
+    const owners = await helper.callRpc('api.rpc.unique.tokenOwners', [collection.collectionId, 0]);
+    const ids = (owners.toJSON() as any[]).map(crossAccountIdFromLower);
 
-      // What to expect
-      // tslint:disable-next-line:no-unused-expression
-      expect(ids).to.deep.include.members([aliceID, ethAcc, bobId, ...facelessCrowd]);
-      expect(owners.length == 10).to.be.true;
-      
-      const eleven = privateKeyWrapper('11');
-      expect(await transfer(api, collectionId, aliceTokenId, alice, eleven, 10n)).to.be.true;
-      expect((await api.rpc.unique.tokenOwners(collectionId, aliceTokenId)).length).to.be.equal(10);
-    });
+    expect(ids).to.deep.include.members([{Substrate: alice.address}, ethAcc, {Substrate: bob.address}, ...facelessCrowd]);
+    expect(owners.length == 10).to.be.true;
+    
+    // Make sure only 10 results are returned with this RPC
+    const [eleven] = await helper.arrange.createAccounts([0n], donor);
+    expect(await collection.transfer(alice, {Substrate: eleven.address}, 10n)).to.be.true;
+    expect((await helper.callRpc('api.rpc.unique.tokenOwners', [collection.collectionId, 0])).length).to.be.equal(10);
   });
 });
\ No newline at end of file
modifiedtests/src/scheduler.test.tsdiffbeforeafterboth
--- a/tests/src/scheduler.test.ts
+++ b/tests/src/scheduler.test.ts
@@ -44,6 +44,7 @@
 
 chai.use(chaiAsPromised);
 
+// todo:playgrounds skipped ~ postponed
 describe.skip('Scheduling token and balance transfers', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
modifiedtests/src/setChainLimits.test.tsdiffbeforeafterboth
--- a/tests/src/setChainLimits.test.ts
+++ b/tests/src/setChainLimits.test.ts
@@ -23,6 +23,7 @@
   IChainLimits,
 } from './util/helpers';
 
+// todo:playgrounds skipped ~ postponed
 describe.skip('Negative Integration Test setChainLimits', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
modifiedtests/src/setCollectionLimits.test.tsdiffbeforeafterboth
--- a/tests/src/setCollectionLimits.test.ts
+++ b/tests/src/setCollectionLimits.test.ts
@@ -15,26 +15,8 @@
 // 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, submitTransactionExpectFailAsync} from './substrate/substrate-api';
-import {
-  createCollectionExpectSuccess, getCreatedCollectionCount,
-  getCreateItemResult,
-  setCollectionLimitsExpectFailure,
-  setCollectionLimitsExpectSuccess,
-  addCollectionAdminExpectSuccess,
-  queryCollectionExpectSuccess,
-} from './util/helpers';
-
-chai.use(chaiAsPromised);
-const expect = chai.expect;
-
-let alice: IKeyringPair;
-let bob: IKeyringPair;
-let collectionIdForTesting: number;
+import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
 
 const accountTokenOwnershipLimit = 0;
 const sponsoredDataSize = 0;
@@ -42,197 +24,177 @@
 const tokenLimit = 10;
 
 describe('setCollectionLimits positive', () => {
-  let tx;
-  before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
-    });
-  });
-  it('execute setCollectionLimits with predefined params ', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      tx = api.tx.unique.setCollectionLimits(
-        collectionIdForTesting,
-        {
-          accountTokenOwnershipLimit: accountTokenOwnershipLimit,
-          sponsoredDataSize: sponsoredDataSize,
-          tokenLimit: tokenLimit,
-          sponsorTransferTimeout,
-          ownerCanTransfer: true,
-          ownerCanDestroy: true,
-        },
-      );
-      const events = await submitTransactionAsync(alice, tx);
-      const result = getCreateItemResult(events);
-
-      // get collection limits defined previously
-      const collectionInfo = await queryCollectionExpectSuccess(api, collectionIdForTesting);
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
 
-      // tslint:disable-next-line:no-unused-expression
-      expect(result.success).to.be.true;
-      expect(collectionInfo.limits.accountTokenOwnershipLimit.unwrap().toNumber()).to.be.equal(accountTokenOwnershipLimit);
-      expect(collectionInfo.limits.sponsoredDataSize.unwrap().toNumber()).to.be.equal(sponsoredDataSize);
-      expect(collectionInfo.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);
-      expect(collectionInfo.limits.sponsorTransferTimeout.unwrap().toNumber()).to.be.equal(sponsorTransferTimeout);
-      expect(collectionInfo.limits.ownerCanTransfer.unwrap().toJSON()).to.be.true;
-      expect(collectionInfo.limits.ownerCanDestroy.unwrap().toJSON()).to.be.true;
+  before(async () => {
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
     });
   });
 
-  it('Set the same token limit twice', async () => {
-    await usingApi(async (api: ApiPromise) => {
+  itSub('execute setCollectionLimits with predefined params', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-1', tokenPrefix: 'SCL'});
 
-      const collectionLimits = {
-        accountTokenOwnershipLimit: accountTokenOwnershipLimit,
-        sponsoredMintSize: sponsoredDataSize,
-        tokenLimit: tokenLimit,
+    await collection.setLimits(
+      alice,
+      {
+        accountTokenOwnershipLimit,
+        sponsoredDataSize,
+        tokenLimit,
         sponsorTransferTimeout,
         ownerCanTransfer: true,
         ownerCanDestroy: true,
-      };
+      },
+    );
 
-      // The first time
-      const tx1 = api.tx.unique.setCollectionLimits(
-        collectionIdForTesting,
-        collectionLimits,
-      );
-      const events1 = await submitTransactionAsync(alice, tx1);
-      const result1 = getCreateItemResult(events1);
-      expect(result1.success).to.be.true;
-      const collectionInfo1 = await queryCollectionExpectSuccess(api, collectionIdForTesting);
-      expect(collectionInfo1.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);
+    // get collection limits defined previously
+    const collectionInfo = await collection.getEffectiveLimits();
+
+    expect(collectionInfo.accountTokenOwnershipLimit).to.be.equal(accountTokenOwnershipLimit);
+    expect(collectionInfo.sponsoredDataSize).to.be.equal(sponsoredDataSize);
+    expect(collectionInfo.tokenLimit).to.be.equal(tokenLimit);
+    expect(collectionInfo.sponsorTransferTimeout).to.be.equal(sponsorTransferTimeout);
+    expect(collectionInfo.ownerCanTransfer).to.be.true;
+    expect(collectionInfo.ownerCanDestroy).to.be.true;
+  });
+
+  itSub('Set the same token limit twice', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-2', tokenPrefix: 'SCL'});
+
+    const collectionLimits = {
+      accountTokenOwnershipLimit,
+      sponsoredDataSize,
+      tokenLimit,
+      sponsorTransferTimeout,
+      ownerCanTransfer: true,
+      ownerCanDestroy: true,
+    };
+
+    await collection.setLimits(alice, collectionLimits);
+
+    const collectionInfo1 = await collection.getEffectiveLimits();
+      
+    expect(collectionInfo1.tokenLimit).to.be.equal(tokenLimit);
 
-      // The second time
-      const tx2 = api.tx.unique.setCollectionLimits(
-        collectionIdForTesting,
-        collectionLimits,
-      );
-      const events2 = await submitTransactionAsync(alice, tx2);
-      const result2 = getCreateItemResult(events2);
-      expect(result2.success).to.be.true;
-      const collectionInfo2 = await queryCollectionExpectSuccess(api, collectionIdForTesting);
-      expect(collectionInfo2.limits.tokenLimit.unwrap().toNumber()).to.be.equal(tokenLimit);
-    });
+    await collection.setLimits(alice, collectionLimits);
+    const collectionInfo2 = await collection.getEffectiveLimits();
+    expect(collectionInfo2.tokenLimit).to.be.equal(tokenLimit);
   });
 
-  it('execute setCollectionLimits from admin collection', async () => {
-    await addCollectionAdminExpectSuccess(alice, collectionIdForTesting, bob.address);
-    await usingApi(async (api: ApiPromise) => {
-      tx = api.tx.unique.setCollectionLimits(
-        collectionIdForTesting,
-        {
-          accountTokenOwnershipLimit,
-          sponsoredDataSize,
-          // sponsoredMintSize,
-          tokenLimit,
-        },
-      );
-      await expect(submitTransactionAsync(bob, tx)).to.be.not.rejected;
-    });
+  itSub('execute setCollectionLimits from admin collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-3', tokenPrefix: 'SCL'});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+
+    const collectionLimits = {
+      accountTokenOwnershipLimit,
+      sponsoredDataSize,
+      // sponsoredMintSize,
+      tokenLimit,
+    };
+
+    await expect(collection.setLimits(alice, collectionLimits)).to.not.be.rejected;
   });
 });
 
 describe('setCollectionLimits negative', () => {
-  let tx;
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      collectionIdForTesting = await createCollectionExpectSuccess({name: 'A', description: 'B', tokenPrefix: 'C', mode: {type: 'NFT'}});
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([20n, 10n], donor);
     });
   });
-  it('execute setCollectionLimits for not exists collection', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      const collectionCount = await getCreatedCollectionCount(api);
-      const nonExistedCollectionId = collectionCount + 1;
-      tx = api.tx.unique.setCollectionLimits(
-        nonExistedCollectionId,
-        {
-          accountTokenOwnershipLimit,
-          sponsoredDataSize,
-          // sponsoredMintSize,
-          tokenLimit,
-        },
-      );
-      await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
-    });
+  
+  itSub('execute setCollectionLimits for not exists collection', async ({helper}) => {
+    const nonExistentCollectionId = (1 << 32) - 1;
+    await expect(helper.collection.setLimits(
+      alice,
+      nonExistentCollectionId,
+      {
+        accountTokenOwnershipLimit,
+        sponsoredDataSize,
+        // sponsoredMintSize,
+        tokenLimit,
+      },
+    )).to.be.rejectedWith(/common\.CollectionNotFound/);
   });
-  it('execute setCollectionLimits from user who is not owner of this collection', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      tx = api.tx.unique.setCollectionLimits(
-        collectionIdForTesting,
-        {
-          accountTokenOwnershipLimit,
-          sponsoredDataSize,
-          // sponsoredMintSize,
-          tokenLimit,
-        },
-      );
-      await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
-    });
+
+  itSub('execute setCollectionLimits from user who is not owner of this collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-1', tokenPrefix: 'SCL'});
+
+    await expect(collection.setLimits(bob, {
+      accountTokenOwnershipLimit,
+      sponsoredDataSize,
+      // sponsoredMintSize,
+      tokenLimit,
+    })).to.be.rejectedWith(/common\.NoPermission/);
   });
 
-  it('fails when trying to enable OwnerCanTransfer after it was disabled', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {
-      accountTokenOwnershipLimit: accountTokenOwnershipLimit,
-      sponsoredMintSize: sponsoredDataSize,
-      tokenLimit: tokenLimit,
+  itSub('fails when trying to enable OwnerCanTransfer after it was disabled', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-2', tokenPrefix: 'SCL'});
+
+    await collection.setLimits(alice, {
+      accountTokenOwnershipLimit,
+      sponsoredDataSize,
+      tokenLimit,
       sponsorTransferTimeout,
       ownerCanTransfer: false,
       ownerCanDestroy: true,
     });
-    await setCollectionLimitsExpectFailure(alice, collectionId, {
-      accountTokenOwnershipLimit: accountTokenOwnershipLimit,
-      sponsoredMintSize: sponsoredDataSize,
-      tokenLimit: tokenLimit,
+
+    await expect(collection.setLimits(alice, {
+      accountTokenOwnershipLimit,
+      sponsoredDataSize,
+      tokenLimit,
       sponsorTransferTimeout,
       ownerCanTransfer: true,
       ownerCanDestroy: true,
-    });
+    })).to.be.rejectedWith(/common\.OwnerPermissionsCantBeReverted/);
   });
 
-  it('fails when trying to enable OwnerCanDestroy after it was disabled', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {
-      accountTokenOwnershipLimit: accountTokenOwnershipLimit,
-      sponsoredMintSize: sponsoredDataSize,
-      tokenLimit: tokenLimit,
+  itSub('fails when trying to enable OwnerCanDestroy after it was disabled', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-3', tokenPrefix: 'SCL'});
+
+    await collection.setLimits(alice, {
+      accountTokenOwnershipLimit,
+      sponsoredDataSize,
+      tokenLimit,
       sponsorTransferTimeout,
       ownerCanTransfer: true,
       ownerCanDestroy: false,
     });
-    await setCollectionLimitsExpectFailure(alice, collectionId, {
+
+    await expect(collection.setLimits(alice, {
+      accountTokenOwnershipLimit,
+      sponsoredDataSize,
+      tokenLimit,
+      sponsorTransferTimeout,
+      ownerCanTransfer: true,
+      ownerCanDestroy: true,
+    })).to.be.rejectedWith(/common\.OwnerPermissionsCantBeReverted/);
+  });
+
+  itSub('Setting the higher token limit fails', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionLimits-Neg-4', tokenPrefix: 'SCL'});
+      
+    const collectionLimits = {
       accountTokenOwnershipLimit: accountTokenOwnershipLimit,
       sponsoredMintSize: sponsoredDataSize,
       tokenLimit: tokenLimit,
       sponsorTransferTimeout,
       ownerCanTransfer: true,
       ownerCanDestroy: true,
-    });
-  });
-
-  it('Setting the higher token limit fails', async () => {
-    await usingApi(async () => {
-
-      const collectionId = await createCollectionExpectSuccess();
-      const collectionLimits = {
-        accountTokenOwnershipLimit: accountTokenOwnershipLimit,
-        sponsoredMintSize: sponsoredDataSize,
-        tokenLimit: tokenLimit,
-        sponsorTransferTimeout,
-        ownerCanTransfer: true,
-        ownerCanDestroy: true,
-      };
+    };
 
-      // The first time
-      await setCollectionLimitsExpectSuccess(alice, collectionId, collectionLimits);
+    // The first time
+    await collection.setLimits(alice, collectionLimits);
 
-      // The second time - higher token limit
-      collectionLimits.tokenLimit += 1;
-      await setCollectionLimitsExpectFailure(alice, collectionId, collectionLimits);
-    });
+    // The second time - higher token limit
+    collectionLimits.tokenLimit += 1;
+    await expect(collection.setLimits(alice, collectionLimits)).to.be.rejectedWith(/common\.CollectionTokenLimitExceeded/);
   });
-
 });
modifiedtests/src/setCollectionSponsor.test.tsdiffbeforeafterboth
--- a/tests/src/setCollectionSponsor.test.ts
+++ b/tests/src/setCollectionSponsor.test.ts
@@ -14,93 +14,106 @@
 // 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 chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-import {default as usingApi} from './substrate/substrate-api';
-import {createCollectionExpectSuccess,
-  setCollectionSponsorExpectSuccess,
-  destroyCollectionExpectSuccess,
-  setCollectionSponsorExpectFailure,
-  addCollectionAdminExpectSuccess,
-  getCreatedCollectionCount,
-  requirePallets,
-  Pallets,
-} from './util/helpers';
 import {IKeyringPair} from '@polkadot/types/types';
-
-chai.use(chaiAsPromised);
-
-let alice: IKeyringPair;
-let bob: IKeyringPair;
-let charlie: IKeyringPair;
+import {itSub, usingPlaygrounds, expect, Pallets} from './util/playgrounds';
 
 describe('integration test: ext. setCollectionSponsor():', () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+  let charlie: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      charlie = privateKeyWrapper('//Charlie');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
     });
   });
 
-  it('Set NFT collection sponsor', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+  itSub('Set NFT collection sponsor', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-1-NFT', tokenPrefix: 'SCS'});
+    await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
+
+    expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
+      Unconfirmed: bob.address,
+    });
   });
-  it('Set Fungible collection sponsor', async () => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+  
+  itSub('Set Fungible collection sponsor', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'SetCollectionSponsor-1-FT', tokenPrefix: 'SCS'});
+    await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
+
+    expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
+      Unconfirmed: bob.address,
+    });
   });
-  it('Set ReFungible collection sponsor', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
 
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+  itSub.ifWithPallets('Set ReFungible collection sponsor', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'SetCollectionSponsor-1-RFT', tokenPrefix: 'SCS'});
+    await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
+
+    expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
+      Unconfirmed: bob.address,
+    });
   });
 
-  it('Set the same sponsor repeatedly', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
+  itSub('Set the same sponsor repeatedly', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-2', tokenPrefix: 'SCS'});
+    await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
+    await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
+
+    expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
+      Unconfirmed: bob.address,
+    });
   });
-  it('Replace collection sponsor', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, bob.address);
-    await setCollectionSponsorExpectSuccess(collectionId, charlie.address);
+
+  itSub('Replace collection sponsor', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-3', tokenPrefix: 'SCS'});
+    await expect(collection.setSponsor(alice, bob.address)).to.be.not.rejected;
+    await expect(collection.setSponsor(alice, charlie.address)).to.be.not.rejected;
+
+    expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
+      Unconfirmed: charlie.address,
+    });
   });
-  it('Collection admin add sponsor', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-    await setCollectionSponsorExpectSuccess(collectionId, charlie.address, '//Bob');
+  
+  itSub('Collection admin add sponsor', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-4', tokenPrefix: 'SCS'});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+    await expect(collection.setSponsor(bob, charlie.address)).to.be.not.rejected;
+
+    expect((await collection.getData())?.raw.sponsorship).to.deep.equal({
+      Unconfirmed: charlie.address,
+    });
   });
 });
 
 describe('(!negative test!) integration test: ext. setCollectionSponsor():', () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      charlie = privateKeyWrapper('//Charlie');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([10n, 5n], donor);
     });
   });
 
-  it('(!negative test!) Add sponsor with a non-owner', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectFailure(collectionId, bob.address, '//Bob');
+  itSub('(!negative test!) Add sponsor with a non-owner', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-Neg-1', tokenPrefix: 'SCS'});
+    await expect(collection.setSponsor(bob, bob.address))
+      .to.be.rejectedWith(/common\.NoPermission/);
   });
-  it('(!negative test!) Add sponsor to a collection that never existed', async () => {
-    // Find the collection that never existed
-    let collectionId = 0;
-    await usingApi(async (api) => {
-      collectionId = await getCreatedCollectionCount(api) + 1;
-    });
 
-    await setCollectionSponsorExpectFailure(collectionId, bob.address);
+  itSub('(!negative test!) Add sponsor to a collection that never existed', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.collection.setSponsor(alice, collectionId, bob.address))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
-  it('(!negative test!) Add sponsor to a collection that was destroyed', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await destroyCollectionExpectSuccess(collectionId);
-    await setCollectionSponsorExpectFailure(collectionId, bob.address);
+
+  itSub('(!negative test!) Add sponsor to a collection that was destroyed', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetCollectionSponsor-Neg-2', tokenPrefix: 'SCS'});
+    await collection.burn(alice);
+    await expect(collection.setSponsor(alice, bob.address))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 });
modifiedtests/src/setContractSponsoringRateLimit.test.tsdiffbeforeafterboth
--- a/tests/src/setContractSponsoringRateLimit.test.ts
+++ b/tests/src/setContractSponsoringRateLimit.test.ts
@@ -25,6 +25,7 @@
   setContractSponsoringRateLimitExpectSuccess,
 } from './util/helpers';
 
+// todo:playgrounds postponed skipped test
 describe.skip('Integration Test setContractSponsoringRateLimit', () => {
   it('ensure sponsored contract can\'t be called twice without pause for free', async () => {
     await usingApi(async (api, privateKeyWrapper) => {
modifiedtests/src/setMintPermission.test.tsdiffbeforeafterboth
--- a/tests/src/setMintPermission.test.ts
+++ b/tests/src/setMintPermission.test.ts
@@ -15,65 +15,57 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 import {IKeyringPair} from '@polkadot/types/types';
-import usingApi from './substrate/substrate-api';
-import {
-  addToAllowListExpectSuccess,
-  createCollectionExpectSuccess,
-  createItemExpectFailure,
-  createItemExpectSuccess,
-  destroyCollectionExpectSuccess,
-  enableAllowListExpectSuccess,
-  findNotExistingCollection,
-  setMintPermissionExpectFailure,
-  setMintPermissionExpectSuccess,
-  addCollectionAdminExpectSuccess,
-} from './util/helpers';
+import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
 
 describe('Integration Test setMintPermission', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
 
   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('ensure allow-listed non-privileged address can mint tokens', async () => {
-    await usingApi(async () => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await enableAllowListExpectSuccess(alice, collectionId);
-      await setMintPermissionExpectSuccess(alice, collectionId, true);
-      await addToAllowListExpectSuccess(alice, collectionId, bob.address);
+  itSub('ensure allow-listed non-privileged address can mint tokens', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-1', description: '', tokenPrefix: 'SMP'});
+    await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
+    await collection.addToAllowList(alice, {Substrate: bob.address});
 
-      await createItemExpectSuccess(bob, collectionId, 'NFT');
-    });
+    await expect(collection.mintToken(bob, {Substrate: bob.address})).to.not.be.rejected;
   });
 
-  it('can be enabled twice', async () => {
-    await usingApi(async () => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await setMintPermissionExpectSuccess(alice, collectionId, true);
-      await setMintPermissionExpectSuccess(alice, collectionId, true);
-    });
+  itSub('can be enabled twice', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-2', description: '', tokenPrefix: 'SMP'});
+    expect((await collection.getData())?.raw.permissions.access).to.not.equal('AllowList');
+
+    await collection.setPermissions(alice, {mintMode: true});
+    await collection.setPermissions(alice, {mintMode: true});
+    expect((await collection.getData())?.raw.permissions.mintMode).to.be.true;
   });
 
-  it('can be disabled twice', async () => {
-    await usingApi(async () => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await setMintPermissionExpectSuccess(alice, collectionId, true);
-      await setMintPermissionExpectSuccess(alice, collectionId, false);
-      await setMintPermissionExpectSuccess(alice, collectionId, false);
-    });
+  itSub('can be disabled twice', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-3', description: '', tokenPrefix: 'SMP'});
+    expect((await collection.getData())?.raw.permissions.access).to.equal('Normal');
+
+    await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
+    expect((await collection.getData())?.raw.permissions.access).to.equal('AllowList');
+    expect((await collection.getData())?.raw.permissions.mintMode).to.equal(true);
+
+    await collection.setPermissions(alice, {access: 'Normal', mintMode: false});
+    await collection.setPermissions(alice, {access: 'Normal', mintMode: false});
+    expect((await collection.getData())?.raw.permissions.access).to.equal('Normal');
+    expect((await collection.getData())?.raw.permissions.mintMode).to.equal(false);
   });
 
-  it('Collection admin success on set', async () => {
-    await usingApi(async () => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-      await setMintPermissionExpectSuccess(bob, collectionId, true);
-    });
+  itSub('Collection admin success on set', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-4', description: '', tokenPrefix: 'SMP'});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+    await collection.setPermissions(bob, {access: 'AllowList', mintMode: true});
+    
+    expect((await collection.getData())?.raw.permissions.access).to.equal('AllowList');
+    expect((await collection.getData())?.raw.permissions.mintMode).to.equal(true);
   });
 });
 
@@ -82,41 +74,38 @@
   let bob: IKeyringPair;
 
   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('fails on not existing collection', async () => {
-    await usingApi(async (api) => {
-      const nonExistingCollection = await findNotExistingCollection(api);
-      await setMintPermissionExpectFailure(alice, nonExistingCollection, true);
-    });
+  itSub('fails on not existing collection', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.collection.setPermissions(alice, collectionId, {mintMode: true}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('fails on removed collection', async () => {
-    await usingApi(async () => {
-      const removedCollectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await destroyCollectionExpectSuccess(removedCollectionId);
+  itSub('fails on removed collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-1', tokenPrefix: 'SMP'});
+    await collection.burn(alice);
 
-      await setMintPermissionExpectFailure(alice, removedCollectionId, true);
-    });
+    await expect(collection.setPermissions(alice, {mintMode: true}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('fails when not collection owner tries to set mint status', async () => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-    await enableAllowListExpectSuccess(alice, collectionId);
-    await setMintPermissionExpectFailure(bob, collectionId, true);
+  itSub('fails when non-owner tries to set mint status', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-2', tokenPrefix: 'SMP'});
+
+    await expect(collection.setPermissions(bob, {mintMode: true}))
+      .to.be.rejectedWith(/common\.NoPermission/);
   });
 
-  it('ensure non-allow-listed non-privileged address can\'t mint tokens', async () => {
-    await usingApi(async () => {
-      const collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await enableAllowListExpectSuccess(alice, collectionId);
-      await setMintPermissionExpectSuccess(alice, collectionId, true);
+  itSub('ensure non-allow-listed non-privileged address can\'t mint tokens', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'SetMintPermission-Neg-3', tokenPrefix: 'SMP'});
+    await collection.setPermissions(alice, {mintMode: true});
 
-      await createItemExpectFailure(bob, collectionId, 'NFT');
-    });
+    await expect(collection.mintToken(bob, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.AddressNotInAllowlist/);
   });
 });
modifiedtests/src/setPublicAccessMode.test.tsdiffbeforeafterboth
--- a/tests/src/setPublicAccessMode.test.ts
+++ b/tests/src/setPublicAccessMode.test.ts
@@ -15,111 +15,79 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 // https://unique-network.readthedocs.io/en/latest/jsapi.html#setschemaversion
-import {ApiPromise} from '@polkadot/api';
 import {IKeyringPair} from '@polkadot/types/types';
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-import usingApi, {submitTransactionExpectFailAsync} from './substrate/substrate-api';
-import {
-  addToAllowListExpectSuccess,
-  createCollectionExpectSuccess,
-  createItemExpectSuccess,
-  destroyCollectionExpectSuccess,
-  enablePublicMintingExpectSuccess,
-  enableAllowListExpectSuccess,
-  normalizeAccountId,
-  addCollectionAdminExpectSuccess,
-  getCreatedCollectionCount,
-} from './util/helpers';
-
-chai.use(chaiAsPromised);
-const expect = chai.expect;
-
-let alice: IKeyringPair;
-let bob: IKeyringPair;
+import {itSub, usingPlaygrounds, expect} from './util/playgrounds';
 
 describe('Integration Test setPublicAccessMode(): ', () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+  
   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('Run extrinsic with collection id parameters, set the allowlist mode for the collection', async () => {
-    await usingApi(async () => {
-      const collectionId: number = await createCollectionExpectSuccess();
-      await enableAllowListExpectSuccess(alice, collectionId);
-      await enablePublicMintingExpectSuccess(alice, collectionId);
-      await addToAllowListExpectSuccess(alice, collectionId, bob.address);
-      await createItemExpectSuccess(bob, collectionId, 'NFT', bob.address);
-    });
+  itSub('Runs extrinsic with collection id parameters, sets the allowlist mode for the collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-1', tokenPrefix: 'TF'});
+    await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
+    await collection.addToAllowList(alice, {Substrate: bob.address});
+    
+    await expect(collection.mintToken(bob, {Substrate: bob.address})).to.be.not.rejected;
+  });
+
+  itSub('Allowlisted collection limits', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-2', tokenPrefix: 'TF'});
+    await collection.setPermissions(alice, {access: 'AllowList', mintMode: true});
+    
+    await expect(collection.mintToken(bob, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.AddressNotInAllowlist/);
   });
 
-  it('Allowlisted collection limits', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      const collectionId = await createCollectionExpectSuccess();
-      await enableAllowListExpectSuccess(alice, collectionId);
-      await enablePublicMintingExpectSuccess(alice, collectionId);
-      const tx = api.tx.unique.createItem(collectionId, normalizeAccountId(bob.address), 'NFT');
-      await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
-    });
+  itSub('setPublicAccessMode by collection admin', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-4', tokenPrefix: 'TF'});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+
+    await expect(collection.setPermissions(bob, {access: 'AllowList'})).to.be.not.rejected;
   });
 });
 
 describe('Negative Integration Test ext. setPublicAccessMode(): ', () => {
-  it('Set a non-existent collection', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      // tslint:disable-next-line: radix
-      const collectionId = await getCreatedCollectionCount(api) + 1;
-      const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});
-      await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+  
+  before(async () => {
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([10n, 10n], donor);
     });
   });
 
-  it('Set the collection that has been deleted', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      // tslint:disable-next-line: no-bitwise
-      const collectionId = await createCollectionExpectSuccess();
-      await destroyCollectionExpectSuccess(collectionId);
-      const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});
-      await expect(submitTransactionExpectFailAsync(alice, tx)).to.be.rejected;
-    });
+  itSub('Sets a non-existent collection', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.collection.setPermissions(alice, collectionId, {access: 'AllowList'}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('Re-set the list mode already set in quantity', async () => {
-    await usingApi(async () => {
-      const collectionId: number = await createCollectionExpectSuccess();
-      await enableAllowListExpectSuccess(alice, collectionId);
-      await enableAllowListExpectSuccess(alice, collectionId);
-    });
-  });
+  itSub('Sets the collection that has been deleted', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-1', tokenPrefix: 'TF'});
+    await collection.burn(alice);
 
-  it('Execute method not on behalf of the collection owner', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      // tslint:disable-next-line: no-bitwise
-      const collectionId = await createCollectionExpectSuccess();
-      const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});
-      await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.rejected;
-    });
+    await expect(collection.setPermissions(alice, {access: 'AllowList'}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('setPublicAccessMode by collection admin', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      // tslint:disable-next-line: no-bitwise
-      const collectionId = await createCollectionExpectSuccess();
-      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-      const tx = api.tx.unique.setCollectionPermissions(collectionId, {access: 'AllowList'});
-      await expect(submitTransactionExpectFailAsync(bob, tx)).to.be.not.rejected;
-    });
+  itSub('Re-sets the list mode already set in quantity', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-2', tokenPrefix: 'TF'});
+    await collection.setPermissions(alice, {access: 'AllowList'});
+    await collection.setPermissions(alice, {access: 'AllowList'});
   });
-});
 
-describe('Negative Integration Test ext. collection admin setPublicAccessMode(): ', () => {
-  before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-    });
+  itSub('Executes method as a malefactor', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'PublicAccess-Neg-3', tokenPrefix: 'TF'});
+
+    await expect(collection.setPermissions(bob, {access: 'AllowList'}))
+      .to.be.rejectedWith(/common\.NoPermission/);
   });
 });
modifiedtests/src/toggleContractAllowList.test.tsdiffbeforeafterboth
--- a/tests/src/toggleContractAllowList.test.ts
+++ b/tests/src/toggleContractAllowList.test.ts
@@ -31,6 +31,7 @@
 const value = 0;
 const gasLimit = 3000n * 1000000n;
 
+// todo:playgrounds skipped ~ postpone
 describe.skip('Integration Test toggleContractAllowList', () => {
 
   it('Enable allow list contract mode', async () => {
modifiedtests/src/transfer.test.tsdiffbeforeafterboth
--- a/tests/src/transfer.test.ts
+++ b/tests/src/transfer.test.ts
@@ -14,387 +14,314 @@
 // 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 {ApiPromise} from '@polkadot/api';
 import {IKeyringPair} from '@polkadot/types/types';
-import {expect} from 'chai';
-import getBalance from './substrate/get-balance';
-import {default as usingApi, submitTransactionAsync} from './substrate/substrate-api';
-import {
-  burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess,
-  destroyCollectionExpectSuccess,
-  findUnusedAddress,
-  getCreateCollectionResult,
-  getCreateItemResult,
-  transferExpectFailure,
-  transferExpectSuccess,
-  addCollectionAdminExpectSuccess,
-  getCreatedCollectionCount,
-  toSubstrateAddress,
-  getTokenOwner,
-  normalizeAccountId,
-  getBalance as getTokenBalance,
-  transferFromExpectSuccess,
-  transferFromExpectFail,
-  requirePallets,
-  Pallets,
-} from './util/helpers';
-import {
-  subToEth,
-  itWeb3, 
-} from './eth/util/helpers';
-import {request} from 'https';
-
-let alice: IKeyringPair;
-let bob: IKeyringPair;
-let charlie: IKeyringPair;
+import {itEth, usingEthPlaygrounds} from './eth/util/playgrounds';
+import {itSub, Pallets, usingPlaygrounds, expect} from './util/playgrounds';
 
 describe('Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+
   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([50n, 10n], donor);
     });
   });
   
-  it('Balance transfers and check balance', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      const [alicesBalanceBefore, bobsBalanceBefore] = await getBalance(api, [alice.address, bob.address]);
+  itSub('Balance transfers and check balance', async ({helper}) => {
+    const alicesBalanceBefore = await helper.balance.getSubstrate(alice.address);
+    const bobsBalanceBefore = await helper.balance.getSubstrate(bob.address);
 
-      const transfer = api.tx.balances.transfer(bob.address, 1n);
-      const events = await submitTransactionAsync(alice, transfer);
-      const result = getCreateItemResult(events);
-      // tslint:disable-next-line:no-unused-expression
-      expect(result.success).to.be.true;
+    expect(await helper.balance.transferToSubstrate(alice, bob.address, 1n)).to.be.true;
 
-      const [alicesBalanceAfter, bobsBalanceAfter] = await getBalance(api, [alice.address, bob.address]);
+    const alicesBalanceAfter = await helper.balance.getSubstrate(alice.address);
+    const bobsBalanceAfter = await helper.balance.getSubstrate(bob.address);
 
-      // tslint:disable-next-line:no-unused-expression
-      expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;
-      // tslint:disable-next-line:no-unused-expression
-      expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;
-    });
+    expect(alicesBalanceAfter < alicesBalanceBefore).to.be.true;
+    expect(bobsBalanceAfter > bobsBalanceBefore).to.be.true;
   });
 
-  it('Inability to pay fees error message is correct', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      // Find unused address
-      const pk = await findUnusedAddress(api, privateKeyWrapper);
+  itSub('Inability to pay fees error message is correct', async ({helper, privateKey}) => {
+    const donor = privateKey('//Alice');
+    const [zero] = await helper.arrange.createAccounts([0n], donor);
 
-      const badTransfer = api.tx.balances.transfer(bob.address, 1n);
-      // const events = await submitTransactionAsync(pk, badTransfer);
-      const badTransaction = async () => {
-        const events = await submitTransactionAsync(pk, badTransfer);
-        const result = getCreateCollectionResult(events);
-        // tslint:disable-next-line:no-unused-expression
-        expect(result.success).to.be.false;
-      };
-      await expect(badTransaction()).to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');
-    });
+    // console.error = () => {};
+    // The following operation throws an error into the console and the logs. Pay it no heed as long as the test succeeds.
+    await expect(helper.balance.transferToSubstrate(zero, donor.address, 1n))
+      .to.be.rejectedWith('Inability to pay some fees , e.g. account balance too low');
   });
 
-  it('[nft] User can transfer owned token', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-    await transferExpectSuccess(nftCollectionId, newNftTokenId, alice, bob, 1, 'NFT');
+  itSub('[nft] User can transfer owned token', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-1-NFT', description: '', tokenPrefix: 'T'});
+    const nft = await collection.mintToken(alice);
+
+    await nft.transfer(alice, {Substrate: bob.address});
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: bob.address});
   });
 
-  it('[fungible] User can transfer owned token', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-    await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob, 1, 'Fungible');
+  itSub('[fungible] User can transfer owned token', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-1-FT', description: '', tokenPrefix: 'T'});
+    await collection.mint(alice, 10n);
+
+    await collection.transfer(alice, {Substrate: bob.address}, 9n);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
 
-  it('[refungible] User can transfer owned token', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub.ifWithPallets('[refungible] User can transfer owned token', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});
+    const rft = await collection.mintToken(alice, 10n);
 
-    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-    await transferExpectSuccess(
-      reFungibleCollectionId,
-      newReFungibleTokenId,
-      alice,
-      bob,
-      100,
-      'ReFungible',
-    );
+    await rft.transfer(alice, {Substrate: bob.address}, 9n);
+    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);
+    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
 
-  it('[nft] Collection admin can transfer owned token', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
-    const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT', bob.address);
-    await transferExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, 1, 'NFT');
+  itSub('[nft] Collection admin can transfer owned token', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-2-NFT', description: '', tokenPrefix: 'T'});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+
+    const nft = await collection.mintToken(bob, {Substrate: bob.address});
+    await nft.transfer(bob, {Substrate: alice.address});
+
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
   });
 
-  it('[fungible] Collection admin can transfer owned token', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    await addCollectionAdminExpectSuccess(alice, fungibleCollectionId, bob.address);
-    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible', bob.address);
-    await transferExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, 1, 'Fungible');
+  itSub('[fungible] Collection admin can transfer owned token', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-2-FT', description: '', tokenPrefix: 'T'});
+    await collection.addAdmin(alice, {Substrate: bob.address});
+
+    await collection.mint(bob, 10n, {Substrate: bob.address});
+    await collection.transfer(bob, {Substrate: alice.address}, 1n);
+
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(9n);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
 
-  it('[refungible] Collection admin can transfer owned token', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub.ifWithPallets('[refungible] Collection admin can transfer owned token', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-2-RFT', description: '', tokenPrefix: 'T'});
+    await collection.addAdmin(alice, {Substrate: bob.address});
 
-    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    await addCollectionAdminExpectSuccess(alice, reFungibleCollectionId, bob.address);
-    const newReFungibleTokenId = await createItemExpectSuccess(bob, reFungibleCollectionId, 'ReFungible', bob.address);
-    await transferExpectSuccess(
-      reFungibleCollectionId,
-      newReFungibleTokenId,
-      bob,
-      alice,
-      100,
-      'ReFungible',
-    );
+    const rft = await collection.mintToken(bob, 10n, {Substrate: bob.address});
+    await rft.transfer(bob, {Substrate: alice.address}, 1n);
+
+    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(9n);
+    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(1n);
   });
 });
 
 describe('Negative Integration Test Transfer(recipient, collection_id, item_id, value)', () => {
+  let alice: IKeyringPair;
+  let bob: IKeyringPair;
+
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      charlie = privateKeyWrapper('//Charlie');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob] = await helper.arrange.createAccounts([50n, 10n], donor);
     });
   });
 
-  it('[nft] Transfer with not existed collection_id', async () => {
-    await usingApi(async (api) => {
-      const nftCollectionCount = await getCreatedCollectionCount(api);
-      await transferExpectFailure(nftCollectionCount + 1, 1, alice, bob, 1);
-    });
+  itSub('[nft] Transfer with not existed collection_id', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.nft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('[fungible] Transfer with not existed collection_id', async () => {
-    await usingApi(async (api) => {
-      const fungibleCollectionCount = await getCreatedCollectionCount(api);
-      await transferExpectFailure(fungibleCollectionCount + 1, 0, alice, bob, 1);
-    });
+  itSub('[fungible] Transfer with not existed collection_id', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.ft.transfer(alice, collectionId, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
+  });
+
+  itSub.ifWithPallets('[refungible] Transfer with not existed collection_id', [Pallets.ReFungible], async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.rft.transferToken(alice, collectionId, 1, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('[refungible] Transfer with not existed collection_id', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub('[nft] Transfer with deleted collection_id', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-1-NFT', description: '', tokenPrefix: 'T'});
+    const nft = await collection.mintToken(alice);
 
-    await usingApi(async (api) => {
-      const reFungibleCollectionCount = await getCreatedCollectionCount(api);
-      await transferExpectFailure(reFungibleCollectionCount + 1, 1, alice, bob, 1);
-    });
-  });
+    await nft.burn(alice);
+    await collection.burn(alice);
 
-  it('[nft] Transfer with deleted collection_id', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-    await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId);
-    await destroyCollectionExpectSuccess(nftCollectionId);
-    await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);
+    await expect(nft.transfer(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('[fungible] Transfer with deleted collection_id', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-    await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
-    await destroyCollectionExpectSuccess(fungibleCollectionId);
-    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);
-  });
+  itSub('[fungible] Transfer with deleted collection_id', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-1-FT', description: '', tokenPrefix: 'T'});
+    await collection.mint(alice, 10n);
 
-  it('[refungible] Transfer with deleted collection_id', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+    await collection.burnTokens(alice, 10n);
+    await collection.burn(alice);
 
-    const reFungibleCollectionId = await
-    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-    await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
-    await destroyCollectionExpectSuccess(reFungibleCollectionId);
-    await transferExpectFailure(
-      reFungibleCollectionId,
-      newReFungibleTokenId,
-      alice,
-      bob,
-      1,
-    );
+    await expect(collection.transfer(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
+  
+  itSub.ifWithPallets('[refungible] Transfer with deleted collection_id', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-1-RFT', description: '', tokenPrefix: 'T'});
+    const rft = await collection.mintToken(alice, 10n);
 
-  it('[nft] Transfer with not existed item_id', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    await transferExpectFailure(nftCollectionId, 2, alice, bob, 1);
+    await rft.burn(alice, 10n);
+    await collection.burn(alice);
+
+    await expect(rft.transfer(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
   });
 
-  it('[fungible] Transfer with not existed item_id', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    await transferExpectFailure(fungibleCollectionId, 2, alice, bob, 1);
+  itSub('[nft] Transfer with not existed item_id', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-2-NFT', description: '', tokenPrefix: 'T'});
+    await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.TokenNotFound/);
   });
 
-  it('[refungible] Transfer with not existed item_id', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub('[fungible] Transfer with not existed item_id', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-2-FT', description: '', tokenPrefix: 'T'});
+    await expect(collection.transfer(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
+  });
 
-    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    await transferExpectFailure(
-      reFungibleCollectionId,
-      2,
-      alice,
-      bob,
-      1,
-    );
+  itSub.ifWithPallets('[refungible] Transfer with not existed item_id', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-2-RFT', description: '', tokenPrefix: 'T'});
+    await expect(collection.transferToken(alice, 1, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
 
-  it('[nft] Transfer with deleted item_id', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-    await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
-    await transferExpectFailure(nftCollectionId, newNftTokenId, alice, bob, 1);
+  itSub('[nft] Transfer with deleted item_id', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-3-NFT', description: '', tokenPrefix: 'T'});
+    const nft = await collection.mintToken(alice);
+
+    await nft.burn(alice);
+
+    await expect(nft.transfer(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.TokenNotFound/);
   });
 
-  it('[fungible] Transfer with deleted item_id', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-    await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
-    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, alice, bob, 1);
+  itSub('[fungible] Transfer with deleted item_id', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-3-FT', description: '', tokenPrefix: 'T'});
+    await collection.mint(alice, 10n);
+
+    await collection.burnTokens(alice, 10n);
+
+    await expect(collection.transfer(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
 
-  it('[refungible] Transfer with deleted item_id', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub.ifWithPallets('[refungible] Transfer with deleted item_id', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-Neg-3-RFT', description: '', tokenPrefix: 'T'});
+    const rft = await collection.mintToken(alice, 10n);
 
-    const reFungibleCollectionId = await
-    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-    await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
-    await transferExpectFailure(
-      reFungibleCollectionId,
-      newReFungibleTokenId,
-      alice,
-      bob,
-      1,
-    );
+    await rft.burn(alice, 10n);
+
+    await expect(rft.transfer(alice, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
 
-  it('[nft] Transfer with recipient that is not owner', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-    await transferExpectFailure(nftCollectionId, newNftTokenId, charlie, bob, 1);
+  itSub('[nft] Transfer with recipient that is not owner', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'Transfer-Neg-4-NFT', description: '', tokenPrefix: 'T'});
+    const nft = await collection.mintToken(alice);
+
+    await expect(nft.transfer(bob, {Substrate: bob.address}))
+      .to.be.rejectedWith(/common\.NoPermission/);
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
   });
 
-  it('[fungible] Transfer with recipient that is not owner', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-    await transferExpectFailure(fungibleCollectionId, newFungibleTokenId, charlie, bob, 1);
+  itSub('[fungible] Transfer with recipient that is not owner', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'Transfer-Neg-4-FT', description: '', tokenPrefix: 'T'});
+    await collection.mint(alice, 10n);
+
+    await expect(collection.transfer(bob, {Substrate: bob.address}, 9n))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.equal(0n);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(10n);
   });
 
-  it('[refungible] Transfer with recipient that is not owner', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub.ifWithPallets('[refungible] Transfer with recipient that is not owner', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'Transfer-1-RFT', description: '', tokenPrefix: 'T'});
+    const rft = await collection.mintToken(alice, 10n);
 
-    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-    await transferExpectFailure(
-      reFungibleCollectionId,
-      newReFungibleTokenId,
-      charlie,
-      bob,
-      1,
-    );
+    await expect(rft.transfer(bob, {Substrate: bob.address}, 9n))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
+    expect(await rft.getBalance({Substrate: bob.address})).to.be.equal(0n);
+    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(10n);
   });
 });
 
-describe('Zero value transfer(From)', () => {
-  before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
+describe('Transfers to self (potentially over substrate-evm boundary)', () => {
+  let donor: IKeyringPair;
+
+  before(async function() {
+    await usingEthPlaygrounds(async (_, privateKey) => {
+      donor = privateKey('//Alice');
     });
   });
+  
+  itEth('Transfers to self. In case of same frontend', async ({helper}) => {
+    const [owner] = await helper.arrange.createAccounts([10n], donor);
+    const collection = await helper.ft.mintCollection(owner, {});
+    await collection.mint(owner, 100n);
 
-  it('NFT', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
+    const ownerProxy = helper.address.substrateToEth(owner.address);
 
-      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), nftCollectionId, newNftTokenId, 0);
-      await submitTransactionAsync(alice, transferTx);
-      const address = normalizeAccountId(await getTokenOwner(api, nftCollectionId, newNftTokenId));
+    // transfer to own proxy
+    await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);
+    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);
+    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);
 
-      expect(toSubstrateAddress(address)).to.be.equal(alice.address);
-    });
+    // transfer-from own proxy to own proxy again
+    await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Ethereum: ownerProxy}, 5n);
+    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);
+    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);
   });
-
-  it('RFT', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
 
-    await usingApi(async (api: ApiPromise) => {
-      const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-      const balanceBeforeAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);
-      const balanceBeforeBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);
+  itEth('Transfers to self. In case of substrate-evm boundary', async ({helper}) => {
+    const [owner] = await helper.arrange.createAccounts([10n], donor);
+    const collection = await helper.ft.mintCollection(owner, {});
+    await collection.mint(owner, 100n);
 
-      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), reFungibleCollectionId, newReFungibleTokenId, 0);
-      await submitTransactionAsync(alice, transferTx);
+    const ownerProxy = helper.address.substrateToEth(owner.address);
 
-      const balanceAfterAlice = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(alice), newReFungibleTokenId);
-      const balanceAfterBob = await getTokenBalance(api, reFungibleCollectionId, normalizeAccountId(bob), newReFungibleTokenId);
+    // transfer to own proxy
+    await collection.transfer(owner, {Ethereum: ownerProxy}, 10n);
+    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(90n);
+    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(10n);
 
-      expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);
-      expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);
-    });
+    // transfer-from own proxy to self
+    await collection.transferFrom(owner, {Ethereum: ownerProxy}, {Substrate: owner.address}, 5n);
+    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(95n);
+    expect(await collection.getBalance({Ethereum: ownerProxy})).to.be.equal(5n);
   });
-
-  it('Fungible', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-      const balanceBeforeAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);
-      const balanceBeforeBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);
 
-      const transferTx = api.tx.unique.transfer(normalizeAccountId(bob), fungibleCollectionId, newFungibleTokenId, 0);
-      await submitTransactionAsync(alice, transferTx);
-
-      const balanceAfterAlice = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(alice), newFungibleTokenId);
-      const balanceAfterBob = await getTokenBalance(api, fungibleCollectionId, normalizeAccountId(bob), newFungibleTokenId);
+  itEth('Transfers to self. In case of inside substrate-evm', async ({helper}) => {
+    const [owner] = await helper.arrange.createAccounts([10n], donor);
+    const collection = await helper.ft.mintCollection(owner, {});
+    await collection.mint(owner, 100n);
 
-      expect((balanceBeforeAlice)).to.be.equal(balanceAfterAlice);
-      expect((balanceBeforeBob)).to.be.equal(balanceAfterBob);
-    });
-  });
-});
+    // transfer to self again
+    await collection.transfer(owner, {Substrate: owner.address}, 10n);
+    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);
 
-describe('Transfers to self (potentially over substrate-evm boundary)', () => {
-  itWeb3('Transfers to self. In case of same frontend', async ({api, privateKeyWrapper}) => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const aliceProxy = subToEth(alice.address);
-    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
-    await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, 10, 'Fungible');
-    const balanceAliceBefore = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);
-    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, {Ethereum: aliceProxy}, 10, 'Fungible');
-    const balanceAliceAfter = await getTokenBalance(api, collectionId, {Ethereum: aliceProxy}, tokenId);
-    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
+    // transfer-from self to self again
+    await collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 5n);
+    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(100n);
   });
 
-  itWeb3('Transfers to self. In case of substrate-evm boundary', async ({api, privateKeyWrapper}) => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const aliceProxy = subToEth(alice.address);
-    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
-    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
-    await transferExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy} , 10, 'Fungible');
-    await transferFromExpectSuccess(collectionId, tokenId, alice, {Ethereum: aliceProxy}, alice, 10, 'Fungible');
-    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
-    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
-  });
+  itEth('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({helper}) => {
+    const [owner] = await helper.arrange.createAccounts([10n], donor);
+    const collection = await helper.ft.mintCollection(owner, {});
+    await collection.mint(owner, 10n);
 
-  itWeb3('Transfers to self. In case of inside substrate-evm', async ({api, privateKeyWrapper}) => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
-    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
-    await transferExpectSuccess(collectionId, tokenId, alice, alice , 10, 'Fungible');
-    await transferFromExpectSuccess(collectionId, tokenId, alice, alice, alice, 10, 'Fungible');
-    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
-    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
-  });
+    // transfer to self again
+    await expect(collection.transfer(owner, {Substrate: owner.address}, 11n))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
 
-  itWeb3('Transfers to self. In case of inside substrate-evm when not enought "Fungibles"', async ({api, privateKeyWrapper}) => {
-    const collectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const tokenId = await createItemExpectSuccess(alice, collectionId, 'Fungible', {Substrate: alice.address});
-    const balanceAliceBefore = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
-    await transferExpectFailure(collectionId, tokenId, alice, alice , 11);
-    await transferFromExpectFail(collectionId, tokenId, alice, alice, alice, 11);
-    const balanceAliceAfter = await getTokenBalance(api, collectionId, normalizeAccountId(alice), tokenId);
-    expect(balanceAliceBefore).to.be.eq(balanceAliceAfter);
+    // transfer-from self to self again
+    await expect(collection.transferFrom(owner, {Substrate: owner.address}, {Substrate: owner.address}, 12n))
+      .to.be.rejectedWith(/common\.TokenValueTooLow/);
+    expect(await collection.getBalance({Substrate: owner.address})).to.be.equal(10n);
   });
 });
modifiedtests/src/transferFrom.test.tsdiffbeforeafterboth
--- a/tests/src/transferFrom.test.ts
+++ b/tests/src/transferFrom.test.ts
@@ -14,97 +14,73 @@
 // 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 {ApiPromise} from '@polkadot/api';
 import {IKeyringPair} from '@polkadot/types/types';
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-import {default as usingApi} from './substrate/substrate-api';
-import {
-  approveExpectFail,
-  approveExpectSuccess,
-  createCollectionExpectSuccess,
-  createFungibleItemExpectSuccess,
-  createItemExpectSuccess,
-  getAllowance,
-  transferFromExpectFail,
-  transferFromExpectSuccess,
-  burnItemExpectSuccess,
-  setCollectionLimitsExpectSuccess,
-  getCreatedCollectionCount,
-  requirePallets,
-  Pallets,
-} from './util/helpers';
+import {itSub, Pallets, usingPlaygrounds, expect} from './util/playgrounds';
 
-chai.use(chaiAsPromised);
-const expect = chai.expect;
-
 describe('Integration Test transferFrom(from, recipient, collection_id, item_id, value):', () => {
   let alice: IKeyringPair;
   let bob: IKeyringPair;
   let charlie: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      charlie = privateKeyWrapper('//Charlie');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob, charlie] = await helper.arrange.createAccounts([20n, 10n, 10n], donor);
     });
   });
 
-  it('[nft] Execute the extrinsic and check nftItemList - owner of token', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-    await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
+  itSub('[nft] Execute the extrinsic and check nftItemList - owner of token', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-1', description: '', tokenPrefix: 'TF'});
+    const nft = await collection.mintToken(alice);
+    await nft.approve(alice, {Substrate: bob.address});
+    expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
 
-    await transferFromExpectSuccess(nftCollectionId, newNftTokenId, bob, alice, charlie, 1, 'NFT');
+    await nft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address});
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: charlie.address});
   });
 
-  it('[fungible] Execute the extrinsic and check nftItemList - owner of token', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-    await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
-    await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1, 'Fungible');
+  itSub('[fungible] Execute the extrinsic and check nftItemList - owner of token', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-2', description: '', tokenPrefix: 'TF'});
+    await collection.mint(alice, 10n);
+    await collection.approveTokens(alice, {Substrate: bob.address}, 7n);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(7n);
+    
+    await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 6n);
+    expect(await collection.getBalance({Substrate: charlie.address})).to.be.equal(6n);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.equal(4n);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(1n);
   });
-
-  it('[refungible] Execute the extrinsic and check nftItemList - owner of token', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
 
-    const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-    await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address, 100);
-    await transferFromExpectSuccess(
-      reFungibleCollectionId,
-      newReFungibleTokenId,
-      bob,
-      alice,
-      charlie,
-      100,
-      'ReFungible',
-    );
+  itSub.ifWithPallets('[refungible] Execute the extrinsic and check nftItemList - owner of token', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-3', description: '', tokenPrefix: 'TF'});
+    const rft = await collection.mintToken(alice, 10n);
+    await rft.approve(alice, {Substrate: bob.address}, 7n);
+    expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(7n);
+    
+    await rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 6n);
+    expect(await rft.getBalance({Substrate: charlie.address})).to.be.equal(6n);
+    expect(await rft.getBalance({Substrate: alice.address})).to.be.equal(4n);
+    expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(1n);
   });
 
-  it('Should reduce allowance if value is big', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      const alice = privateKeyWrapper('//Alice');
-      const bob = privateKeyWrapper('//Bob');
-      const charlie = privateKeyWrapper('//Charlie');
-
-      // fungible
-      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      const newFungibleTokenId = await createFungibleItemExpectSuccess(alice, fungibleCollectionId, {Value: 500000n});
+  itSub('Should reduce allowance if value is big', async ({helper}) => {
+    // fungible
+    const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-4', description: '', tokenPrefix: 'TF'});
+    await collection.mint(alice, 500000n);
 
-      await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address, 500000n);
-      await transferFromExpectSuccess(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 500000n, 'Fungible');
-      expect(await getAllowance(api, fungibleCollectionId, alice.address, bob.address, newFungibleTokenId)).to.equal(0n);
-    });
+    await collection.approveTokens(alice, {Substrate: bob.address}, 500000n);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(500000n);
+    await collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 500000n);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.equal(0n);
   });
 
-  it('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: true});
-    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
+  itSub('can be called by collection owner on non-owned item when OwnerCanTransfer == true', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-5', description: '', tokenPrefix: 'TF'});
+    await collection.setLimits(alice, {ownerCanTransfer: true});
 
-    await transferFromExpectSuccess(collectionId, itemId, alice, bob, charlie);
+    const nft = await collection.mintToken(alice, {Substrate: bob.address});
+    await nft.transferFrom(alice, {Substrate: bob.address}, {Substrate: charlie.address});
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: charlie.address});
   });
 });
 
@@ -114,245 +90,263 @@
   let charlie: IKeyringPair;
 
   before(async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      alice = privateKeyWrapper('//Alice');
-      bob = privateKeyWrapper('//Bob');
-      charlie = privateKeyWrapper('//Charlie');
+    await usingPlaygrounds(async (helper, privateKey) => {
+      const donor = privateKey('//Alice');
+      [alice, bob, charlie] = await helper.arrange.createAccounts([50n, 10n, 10n], donor);
     });
   });
 
-  it('[nft] transferFrom for a collection that does not exist', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      const nftCollectionCount = await getCreatedCollectionCount(api);
-      await approveExpectFail(nftCollectionCount + 1, 1, alice, bob);
+  itSub('transferFrom for a collection that does not exist', async ({helper}) => {
+    const collectionId = (1 << 32) - 1;
+    await expect(helper.collection.approveToken(alice, collectionId, 0, {Substrate: bob.address}, 1n))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
+    await expect(helper.collection.transferTokenFrom(bob, collectionId, 0, {Substrate: alice.address}, {Substrate: bob.address}, 1n))
+      .to.be.rejectedWith(/common\.CollectionNotFound/);
+  });
+
+  /* itSub('transferFrom for a collection that was destroyed', async ({helper}) => {
+      this test copies approve negative test
+  }); */
+
+  /* itSub('transferFrom a token that does not exist', async ({helper}) => {
+    this test copies approve negative test
+  }); */
+
+  /* itSub('transferFrom a token that was deleted', async ({helper}) => {
+    this test copies approve negative test
+  }); */
+
+  itSub('[nft] transferFrom for not approved address', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-1', description: '', tokenPrefix: 'TF'});
+    const nft = await collection.mintToken(alice);
+
+    await expect(nft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}))
+      .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
+  });
+
+  itSub('[fungible] transferFrom for not approved address', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-1', description: '', tokenPrefix: 'TF'});
+    await collection.mint(alice, 10n);
 
-      await transferFromExpectFail(nftCollectionCount + 1, 1, bob, alice, charlie, 1);
-    });
+    await expect(collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 5n))
+      .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
+    expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
   });
 
-  it('[fungible] transferFrom for a collection that does not exist', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      const fungibleCollectionCount = await getCreatedCollectionCount(api);
-      await approveExpectFail(fungibleCollectionCount + 1, 0, alice, bob);
+  itSub.ifWithPallets('[refungible] transferFrom for not approved address', [Pallets.ReFungible], async({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-3', description: '', tokenPrefix: 'TF'});
+    const rft = await collection.mintToken(alice, 10n);
 
-      await transferFromExpectFail(fungibleCollectionCount + 1, 0, bob, alice, charlie, 1);
-    });
+    await expect(rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}))
+      .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
+    expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
+    expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
   });
 
-  it('[refungible] transferFrom for a collection that does not exist', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub('[nft] transferFrom incorrect token count', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-4', description: '', tokenPrefix: 'TF'});
+    const nft = await collection.mintToken(alice);
 
-    await usingApi(async (api: ApiPromise) => {
-      const reFungibleCollectionCount = await getCreatedCollectionCount(api);
-      await approveExpectFail(reFungibleCollectionCount + 1, 1, alice, bob);
+    await nft.approve(alice, {Substrate: bob.address});
+    expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
 
-      await transferFromExpectFail(reFungibleCollectionCount + 1, 1, bob, alice, charlie, 1);
-    });
+    await expect(helper.collection.transferTokenFrom(
+      bob, 
+      collection.collectionId, 
+      nft.tokenId, 
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address}, 
+      2n,
+    )).to.be.rejectedWith(/nonfungible\.NonfungibleItemsHaveNoAmount/);
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
   });
 
-  /* it('transferFrom for a collection that was destroyed', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      this test copies approve negative test
-    });
-  }); */
+  itSub('[fungible] transferFrom incorrect token count', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-5', description: '', tokenPrefix: 'TF'});
+    await collection.mint(alice, 10n);
 
-  /* it('transferFrom a token that does not exist', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      this test copies approve negative test
-    });
-  }); */
+    await collection.approveTokens(alice, {Substrate: bob.address}, 2n);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(2n);
 
-  /* it('transferFrom a token that was deleted', async () => {
-    await usingApi(async (api: ApiPromise) => {
-      this test copies approve negative test
-    });
-  }); */
+    await expect(collection.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 5n))
+      .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
+    expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
+  });
+
+  itSub.ifWithPallets('[refungible] transferFrom incorrect token count', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-6', description: '', tokenPrefix: 'TF'});
+    const rft = await collection.mintToken(alice, 10n);
 
-  it('[nft] transferFrom for not approved address', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
+    await rft.approve(alice, {Substrate: bob.address}, 5n);
+    expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(5n);
 
-    await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
+    await expect(rft.transferFrom(bob, {Substrate: alice.address}, {Substrate: charlie.address}, 7n))
+      .to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10n);
+    expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
+    expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
   });
 
-  it('[fungible] transferFrom for not approved address', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-    await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
+  itSub('[nft] execute transferFrom from account that is not owner of collection', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-7', description: '', tokenPrefix: 'TF'});
+    const nft = await collection.mintToken(alice);
+
+    await expect(nft.approve(charlie, {Substrate: bob.address})).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
+    expect(await nft.isApproved({Substrate: bob.address})).to.be.false;
+
+    await expect(nft.transferFrom(
+      charlie,
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await nft.getOwner()).to.be.deep.equal({Substrate: alice.address});
   });
 
-  it('[refungible] transferFrom for not approved address', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub('[fungible] execute transferFrom from account that is not owner of collection', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-8', description: '', tokenPrefix: 'TF'});
+    await collection.mint(alice, 10000n);
+
+    await expect(collection.approveTokens(charlie, {Substrate: bob.address}, 1n)).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(0n);
+    expect(await collection.getApprovedTokens({Substrate: charlie.address}, {Substrate: bob.address})).to.be.eq(0n);
 
-    const reFungibleCollectionId = await
-    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-    await transferFromExpectFail(
-      reFungibleCollectionId,
-      newReFungibleTokenId,
-      bob,
-      alice,
+    await expect(collection.transferFrom(
       charlie,
-      1,
-    );
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await collection.getBalance({Substrate: alice.address})).to.be.deep.equal(10000n);
+    expect(await collection.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
+    expect(await collection.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
   });
 
-  it('[nft] transferFrom incorrect token count', async () => {
-    const nftCollectionId = await createCollectionExpectSuccess();
-    const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-    await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
+  itSub.ifWithPallets('[refungible] execute transferFrom from account that is not owner of collection', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-9', description: '', tokenPrefix: 'TF'});
+    const rft = await collection.mintToken(alice, 10000n);
 
-    await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 2);
-  });
+    await expect(rft.approve(charlie, {Substrate: bob.address}, 1n)).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
+    expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(0n);
+    expect(await rft.getApprovedPieces({Substrate: charlie.address}, {Substrate: bob.address})).to.be.eq(0n);
 
-  it('[fungible] transferFrom incorrect token count', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-    await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
-    await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 2);
+    await expect(rft.transferFrom(
+      charlie,
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+    expect(await rft.getBalance({Substrate: alice.address})).to.be.deep.equal(10000n);
+    expect(await rft.getBalance({Substrate: bob.address})).to.be.deep.equal(0n);
+    expect(await rft.getBalance({Substrate: charlie.address})).to.be.deep.equal(0n);
   });
 
-  it('[refungible] transferFrom incorrect token count', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub('transferFrom burnt token before approve NFT', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-10', description: '', tokenPrefix: 'TF'});
+    await collection.setLimits(alice, {ownerCanTransfer: true});
+    const nft = await collection.mintToken(alice);
 
-    const reFungibleCollectionId = await
-    createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-    const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-    await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
-    await transferFromExpectFail(
-      reFungibleCollectionId,
-      newReFungibleTokenId,
+    await nft.burn(alice);
+    await expect(nft.approve(alice, {Substrate: bob.address})).to.be.rejectedWith(/common\.TokenNotFound/);
+
+    await expect(nft.transferFrom(
       bob,
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
+  });
+
+  itSub('transferFrom burnt token before approve Fungible', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-11', description: '', tokenPrefix: 'TF'});
+    await collection.setLimits(alice, {ownerCanTransfer: true});
+    await collection.mint(alice, 10n);
+
+    await collection.burnTokens(alice, 10n);
+    await expect(collection.approveTokens(alice, {Substrate: bob.address})).to.be.not.rejected;
+
+    await expect(collection.transferFrom(
       alice,
-      charlie,
-      2,
-    );
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
 
-  it('[nft] execute transferFrom from account that is not owner of collection', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      const dave = privateKeyWrapper('//Dave');
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      try {
-        await approveExpectFail(nftCollectionId, newNftTokenId, dave, bob);
-        await transferFromExpectFail(nftCollectionId, newNftTokenId, dave, alice, charlie, 1);
-      } catch (e) {
-        // tslint:disable-next-line:no-unused-expression
-        expect(e).to.be.exist;
-      }
+  itSub.ifWithPallets('transferFrom burnt token before approve ReFungible', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-12', description: '', tokenPrefix: 'TF'});
+    await collection.setLimits(alice, {ownerCanTransfer: true});
+    const rft = await collection.mintToken(alice, 10n);
+
+    await rft.burn(alice, 10n);
+    await expect(rft.approve(alice, {Substrate: bob.address})).to.be.rejectedWith(/common\.CantApproveMoreThanOwned/);
 
-      // await transferFromExpectFail(nftCollectionId, newNftTokenId, Dave, Alice, Charlie, 1);
-    });
+    await expect(rft.transferFrom(
+      alice,
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
 
-  it('[fungible] execute transferFrom from account that is not owner of collection', async () => {
-    await usingApi(async (api, privateKeyWrapper) => {
-      const dave = privateKeyWrapper('//Dave');
+  itSub('transferFrom burnt token after approve NFT', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-13', description: '', tokenPrefix: 'TF'});
+    const nft = await collection.mintToken(alice);
 
-      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-      try {
-        await approveExpectFail(fungibleCollectionId, newFungibleTokenId, dave, bob);
-        await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, dave, alice, charlie, 1);
-      } catch (e) {
-        // tslint:disable-next-line:no-unused-expression
-        expect(e).to.be.exist;
-      }
-    });
-  });
+    await nft.approve(alice, {Substrate: bob.address});
+    expect(await nft.isApproved({Substrate: bob.address})).to.be.true;
 
-  it('[refungible] execute transferFrom from account that is not owner of collection', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+    await nft.burn(alice);
 
-    await usingApi(async (api, privateKeyWrapper) => {
-      const dave = privateKeyWrapper('//Dave');
-      const reFungibleCollectionId = await
-      createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-      try {
-        await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, bob);
-        await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, dave, alice, charlie, 1);
-      } catch (e) {
-        // tslint:disable-next-line:no-unused-expression
-        expect(e).to.be.exist;
-      }
-    });
-  });
-  it('transferFrom burnt token before approve NFT', async () => {
-    await usingApi(async () => {
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      await setCollectionLimitsExpectSuccess(alice, nftCollectionId, {ownerCanTransfer: true});
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
-      await approveExpectFail(nftCollectionId, newNftTokenId, alice, bob);
-      await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
-    });
+    await expect(nft.transferFrom(
+      bob,
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
   });
-  it('transferFrom burnt token before approve Fungible', async () => {
-    await usingApi(async () => {
-      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      await setCollectionLimitsExpectSuccess(alice, fungibleCollectionId, {ownerCanTransfer: true});
-      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-      await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
-      await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
-      await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
 
-    });
-  });
-  it('transferFrom burnt token before approve ReFungible', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub('transferFrom burnt token after approve Fungible', async ({helper}) => {
+    const collection = await helper.ft.mintCollection(alice, {name: 'TransferFrom-Neg-14', description: '', tokenPrefix: 'TF'});
+    await collection.mint(alice, 10n);
 
-    await usingApi(async () => {
-      const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-      await setCollectionLimitsExpectSuccess(alice, reFungibleCollectionId, {ownerCanTransfer: true});
-      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-      await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
-      await approveExpectFail(reFungibleCollectionId, newReFungibleTokenId, alice, bob);
-      await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice, charlie, 1);
+    await collection.approveTokens(alice, {Substrate: bob.address});
+    expect(await collection.getApprovedTokens({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(1n);
 
-    });
-  });
+    await collection.burnTokens(alice, 10n);
 
-  it('transferFrom burnt token after approve NFT', async () => {
-    await usingApi(async () => {
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await approveExpectSuccess(nftCollectionId, newNftTokenId, alice, bob.address);
-      await burnItemExpectSuccess(alice, nftCollectionId, newNftTokenId, 1);
-      await transferFromExpectFail(nftCollectionId, newNftTokenId, bob, alice, charlie, 1);
-    });
+    await expect(collection.transferFrom(
+      bob,
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.TokenValueTooLow/);
   });
-  it('transferFrom burnt token after approve Fungible', async () => {
-    await usingApi(async () => {
-      const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-      const newFungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-      await approveExpectSuccess(fungibleCollectionId, newFungibleTokenId, alice, bob.address);
-      await burnItemExpectSuccess(alice, fungibleCollectionId, newFungibleTokenId, 10);
-      await transferFromExpectFail(fungibleCollectionId, newFungibleTokenId, bob, alice, charlie, 1);
 
-    });
-  });
-  it('transferFrom burnt token after approve ReFungible', async function() {
-    await requirePallets(this, [Pallets.ReFungible]);
+  itSub.ifWithPallets('transferFrom burnt token after approve ReFungible', [Pallets.ReFungible], async ({helper}) => {
+    const collection = await helper.rft.mintCollection(alice, {name: 'TransferFrom-Neg-15', description: '', tokenPrefix: 'TF'});
+    const rft = await collection.mintToken(alice, 10n);
 
-    await usingApi(async () => {
-      const reFungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-      const newReFungibleTokenId = await createItemExpectSuccess(alice, reFungibleCollectionId, 'ReFungible');
-      await approveExpectSuccess(reFungibleCollectionId, newReFungibleTokenId, alice, bob.address);
-      await burnItemExpectSuccess(alice, reFungibleCollectionId, newReFungibleTokenId, 100);
-      await transferFromExpectFail(reFungibleCollectionId, newReFungibleTokenId, bob, alice, charlie, 1);
+    await rft.approve(alice, {Substrate: bob.address}, 10n);
+    expect(await rft.getApprovedPieces({Substrate: alice.address}, {Substrate: bob.address})).to.be.eq(10n);
+
+    await rft.burn(alice, 10n);
 
-    });
+    await expect(rft.transferFrom(
+      bob,
+      {Substrate: alice.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
   });
 
-  it('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', bob.address);
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {ownerCanTransfer: false});
+  itSub('fails when called by collection owner on non-owned item when OwnerCanTransfer == false', async ({helper}) => {
+    const collection = await helper.nft.mintCollection(alice, {name: 'TransferFrom-Neg-16', description: '', tokenPrefix: 'TF'});
+    const nft = await collection.mintToken(alice, {Substrate: bob.address});
 
-    await transferFromExpectFail(collectionId, itemId, alice, bob, charlie);
+    await collection.setLimits(alice, {ownerCanTransfer: false});
+
+    await expect(nft.transferFrom(
+      alice,
+      {Substrate: bob.address}, 
+      {Substrate: charlie.address},
+    )).to.be.rejectedWith(/common\.ApprovedValueTooLow/);
   });
 });
modifiedtests/src/util/playgrounds/index.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/index.ts
+++ b/tests/src/util/playgrounds/index.ts
@@ -2,12 +2,17 @@
 // SPDX-License-Identifier: Apache-2.0
 
 import {IKeyringPair} from '@polkadot/types/types';
+import chai from 'chai';
+import chaiAsPromised from 'chai-as-promised';
 import {Context} from 'mocha';
 import config from '../../config';
 import '../../interfaces/augment-api-events';
 import {DevUniqueHelper, SilentLogger, SilentConsole} from './unique.dev';
 
 
+chai.use(chaiAsPromised);
+export const expect = chai.expect;
+
 export const usingPlaygrounds = async (code: (helper: DevUniqueHelper, privateKey: (seed: string) => IKeyringPair) => Promise<void>) => {
   const silentConsole = new SilentConsole();
   silentConsole.enable();
modifiedtests/src/util/playgrounds/unique.dev.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.dev.ts
+++ b/tests/src/util/playgrounds/unique.dev.ts
@@ -257,6 +257,7 @@
   }
 
   async forParachainBlockNumber(blockNumber: bigint) {
+    // eslint-disable-next-line no-async-promise-executor
     return new Promise<void>(async (resolve) => {
       const unsubscribe = await this.helper.api!.rpc.chain.subscribeNewHeads(async (data: any) => {
         if (data.number.toNumber() >= blockNumber) {
@@ -268,6 +269,7 @@
   }
   
   async forRelayBlockNumber(blockNumber: bigint) {
+    // eslint-disable-next-line no-async-promise-executor
     return new Promise<void>(async (resolve) => {
       const unsubscribe = await this.helper.api!.query.parachainSystem.validationData(async (data: any) => {
         if (data.value.relayParentNumber.toNumber() >= blockNumber) {
modifiedtests/src/util/playgrounds/unique.tsdiffbeforeafterboth
--- a/tests/src/util/playgrounds/unique.ts
+++ b/tests/src/util/playgrounds/unique.ts
@@ -1678,7 +1678,7 @@
    * @example mintTokens(aliceKeyring, 10, {Substrate: "5GHoZe9c73RYbVzq"}, 1000n);
    * @returns ```true``` if extrinsic success, otherwise ```false``` 
    */
-  async mintTokens(signer: TSigner, collectionId: number, owner: ICrossAccountId | string, amount: bigint): Promise<boolean> {
+  async mintTokens(signer: TSigner, collectionId: number, amount: bigint, owner: ICrossAccountId | string): Promise<boolean> {
     const creationResult = await this.helper.executeExtrinsic(
       signer,
       'api.tx.unique.createItem', [collectionId, (typeof owner === 'string') ? {Substrate: owner} : owner, {
@@ -1699,7 +1699,7 @@
    * @param tokens array of tokens with properties and pieces
    * @returns ```true``` if extrinsic success, otherwise ```false``` 
    */
-  async mintMultipleTokensWithOneOwner(signer: TSigner, collectionId: number, owner: ICrossAccountId, tokens: {value: bigint}[]): Promise<boolean> {
+  async mintMultipleTokensWithOneOwner(signer: TSigner, collectionId: number, tokens: {value: bigint}[], owner: ICrossAccountId): Promise<boolean> {
     const rawTokens = [];
     for (const token of tokens) {
       const raw = {Fungible: {Value: token.value}};
@@ -2128,10 +2128,6 @@
     return await this.helper.collection.addAdmin(signer, this.collectionId, adminAddressObj);
   }
 
-  async enableCertainPermissions(signer: TSigner, accessMode: 'AllowList' | 'Normal' | undefined = 'AllowList', mintMode: boolean | undefined = true) {
-    return await this.setPermissions(signer, {access: accessMode, mintMode: mintMode});
-  }
-
   async addToAllowList(signer: TSigner, addressObj: ICrossAccountId) {
     return await this.helper.collection.addToAllowList(signer, this.collectionId, addressObj);
   }
@@ -2215,7 +2211,7 @@
     return await this.helper.nft.isTokenApproved(this.collectionId, tokenId, toAddressObj);
   }
 
-  async mintToken(signer: TSigner, owner: ICrossAccountId, properties?: IProperty[]) {
+  async mintToken(signer: TSigner, owner: ICrossAccountId = {Substrate: signer.address}, properties?: IProperty[]) {
     return await this.helper.nft.mintToken(signer, {collectionId: this.collectionId, owner, properties});
   }
 
@@ -2290,11 +2286,11 @@
     return await this.helper.rft.repartitionToken(signer, this.collectionId, tokenId, amount);
   }
 
-  async mintToken(signer: TSigner, owner: ICrossAccountId, pieces=100n, properties?: IProperty[]) {
+  async mintToken(signer: TSigner, pieces=1n, owner: ICrossAccountId = {Substrate: signer.address}, properties?: IProperty[]) {
     return await this.helper.rft.mintToken(signer, {collectionId: this.collectionId, owner, pieces, properties});
   }
 
-  async mintMultipleTokens(signer: TSigner, tokens: {owner: ICrossAccountId, pieces: bigint, properties?: IProperty[]}[]) {
+  async mintMultipleTokens(signer: TSigner, tokens: {pieces: bigint, owner: ICrossAccountId, properties?: IProperty[]}[]) {
     return await this.helper.rft.mintMultipleTokens(signer, this.collectionId, tokens);
   }
 
@@ -2317,12 +2313,12 @@
 
 
 class UniqueFTCollection extends UniqueCollectionBase {
-  async mint(signer: TSigner, owner: ICrossAccountId, amount: bigint) {
-    return await this.helper.ft.mintTokens(signer, this.collectionId, owner, amount);
+  async mint(signer: TSigner, amount=1n, owner: ICrossAccountId = {Substrate: signer.address}) {
+    return await this.helper.ft.mintTokens(signer, this.collectionId, amount, owner);
   }
 
-  async mintWithOneOwner(signer: TSigner, owner: ICrossAccountId, tokens: {value: bigint}[]) {
-    return await this.helper.ft.mintMultipleTokensWithOneOwner(signer, this.collectionId, owner, tokens);
+  async mintWithOneOwner(signer: TSigner, tokens: {value: bigint}[], owner: ICrossAccountId = {Substrate: signer.address}) {
+    return await this.helper.ft.mintMultipleTokensWithOneOwner(signer, this.collectionId, tokens, owner);
   }
 
   async getBalance(addressObj: ICrossAccountId) {
modifiedtests/src/xcmTransfer.test.tsdiffbeforeafterboth
--- a/tests/src/xcmTransfer.test.ts
+++ b/tests/src/xcmTransfer.test.ts
@@ -33,6 +33,7 @@
 const KARURA_PORT = '9946';
 const TRANSFER_AMOUNT = 2000000000000000000000000n;
 
+// todo:playgrounds refit when XCM drops
 describe.skip('Integration test: Exchanging QTZ with Karura', () => {
   let alice: IKeyringPair;
 
modifiedtests/yarn.lockdiffbeforeafterboth
--- a/tests/yarn.lock
+++ b/tests/yarn.lock
@@ -17,47 +17,47 @@
   dependencies:
     "@babel/highlight" "^7.18.6"
 
-"@babel/compat-data@^7.18.8":
-  version "7.18.8"
-  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d"
-  integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ==
+"@babel/compat-data@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.0.tgz#2a592fd89bacb1fcde68de31bee4f2f2dacb0e86"
+  integrity sha512-y5rqgTTPTmaF5e2nVhOxw+Ur9HDJLsWb6U/KpgUzRZEdPfE6VOubXBKLdbcUTijzRptednSBDQbYZBOSqJxpJw==
 
 "@babel/core@^7.18.10":
-  version "7.18.10"
-  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.10.tgz#39ad504991d77f1f3da91be0b8b949a5bc466fb8"
-  integrity sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.0.tgz#d2f5f4f2033c00de8096be3c9f45772563e150c3"
+  integrity sha512-reM4+U7B9ss148rh2n1Qs9ASS+w94irYXga7c2jaQv9RVzpS7Mv1a9rnYYwuDa45G+DkORt9g6An2k/V4d9LbQ==
   dependencies:
     "@ampproject/remapping" "^2.1.0"
     "@babel/code-frame" "^7.18.6"
-    "@babel/generator" "^7.18.10"
-    "@babel/helper-compilation-targets" "^7.18.9"
-    "@babel/helper-module-transforms" "^7.18.9"
-    "@babel/helpers" "^7.18.9"
-    "@babel/parser" "^7.18.10"
+    "@babel/generator" "^7.19.0"
+    "@babel/helper-compilation-targets" "^7.19.0"
+    "@babel/helper-module-transforms" "^7.19.0"
+    "@babel/helpers" "^7.19.0"
+    "@babel/parser" "^7.19.0"
     "@babel/template" "^7.18.10"
-    "@babel/traverse" "^7.18.10"
-    "@babel/types" "^7.18.10"
+    "@babel/traverse" "^7.19.0"
+    "@babel/types" "^7.19.0"
     convert-source-map "^1.7.0"
     debug "^4.1.0"
     gensync "^1.0.0-beta.2"
     json5 "^2.2.1"
     semver "^6.3.0"
 
-"@babel/generator@^7.18.10":
-  version "7.18.12"
-  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.12.tgz#fa58daa303757bd6f5e4bbca91b342040463d9f4"
-  integrity sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==
+"@babel/generator@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.0.tgz#785596c06425e59334df2ccee63ab166b738419a"
+  integrity sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==
   dependencies:
-    "@babel/types" "^7.18.10"
+    "@babel/types" "^7.19.0"
     "@jridgewell/gen-mapping" "^0.3.2"
     jsesc "^2.5.1"
 
-"@babel/helper-compilation-targets@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf"
-  integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==
+"@babel/helper-compilation-targets@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.0.tgz#537ec8339d53e806ed422f1e06c8f17d55b96bb0"
+  integrity sha512-Ai5bNWXIvwDvWM7njqsG3feMlL9hCVQsPYXodsZyLwshYkZVJt59Gftau4VrE8S9IT9asd2uSP1hG6wCNw+sXA==
   dependencies:
-    "@babel/compat-data" "^7.18.8"
+    "@babel/compat-data" "^7.19.0"
     "@babel/helper-validator-option" "^7.18.6"
     browserslist "^4.20.2"
     semver "^6.3.0"
@@ -67,13 +67,13 @@
   resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be"
   integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==
 
-"@babel/helper-function-name@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0"
-  integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==
+"@babel/helper-function-name@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c"
+  integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==
   dependencies:
-    "@babel/template" "^7.18.6"
-    "@babel/types" "^7.18.9"
+    "@babel/template" "^7.18.10"
+    "@babel/types" "^7.19.0"
 
 "@babel/helper-hoist-variables@^7.18.6":
   version "7.18.6"
@@ -89,19 +89,19 @@
   dependencies:
     "@babel/types" "^7.18.6"
 
-"@babel/helper-module-transforms@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712"
-  integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==
+"@babel/helper-module-transforms@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30"
+  integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==
   dependencies:
     "@babel/helper-environment-visitor" "^7.18.9"
     "@babel/helper-module-imports" "^7.18.6"
     "@babel/helper-simple-access" "^7.18.6"
     "@babel/helper-split-export-declaration" "^7.18.6"
     "@babel/helper-validator-identifier" "^7.18.6"
-    "@babel/template" "^7.18.6"
-    "@babel/traverse" "^7.18.9"
-    "@babel/types" "^7.18.9"
+    "@babel/template" "^7.18.10"
+    "@babel/traverse" "^7.19.0"
+    "@babel/types" "^7.19.0"
 
 "@babel/helper-simple-access@^7.18.6":
   version "7.18.6"
@@ -132,14 +132,14 @@
   resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8"
   integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==
 
-"@babel/helpers@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9"
-  integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==
+"@babel/helpers@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.0.tgz#f30534657faf246ae96551d88dd31e9d1fa1fc18"
+  integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==
   dependencies:
-    "@babel/template" "^7.18.6"
-    "@babel/traverse" "^7.18.9"
-    "@babel/types" "^7.18.9"
+    "@babel/template" "^7.18.10"
+    "@babel/traverse" "^7.19.0"
+    "@babel/types" "^7.19.0"
 
 "@babel/highlight@^7.18.6":
   version "7.18.6"
@@ -150,10 +150,10 @@
     chalk "^2.0.0"
     js-tokens "^4.0.0"
 
-"@babel/parser@^7.18.10", "@babel/parser@^7.18.11":
-  version "7.18.11"
-  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.11.tgz#68bb07ab3d380affa9a3f96728df07969645d2d9"
-  integrity sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==
+"@babel/parser@^7.18.10", "@babel/parser@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.0.tgz#497fcafb1d5b61376959c1c338745ef0577aa02c"
+  integrity sha512-74bEXKX2h+8rrfQUfsBfuZZHzsEs6Eql4pqy/T4Nn6Y9wNPggQOqD6z6pn5Bl8ZfysKouFZT/UXEH94ummEeQw==
 
 "@babel/register@^7.18.9":
   version "7.18.9"
@@ -167,13 +167,13 @@
     source-map-support "^0.5.16"
 
 "@babel/runtime@^7.18.9":
-  version "7.18.9"
-  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a"
-  integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259"
+  integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==
   dependencies:
     regenerator-runtime "^0.13.4"
 
-"@babel/template@^7.18.10", "@babel/template@^7.18.6":
+"@babel/template@^7.18.10":
   version "7.18.10"
   resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71"
   integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==
@@ -182,26 +182,26 @@
     "@babel/parser" "^7.18.10"
     "@babel/types" "^7.18.10"
 
-"@babel/traverse@^7.18.10", "@babel/traverse@^7.18.9":
-  version "7.18.11"
-  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.11.tgz#3d51f2afbd83ecf9912bcbb5c4d94e3d2ddaa16f"
-  integrity sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ==
+"@babel/traverse@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.0.tgz#eb9c561c7360005c592cc645abafe0c3c4548eed"
+  integrity sha512-4pKpFRDh+utd2mbRC8JLnlsMUii3PMHjpL6a0SZ4NMZy7YFP9aXORxEhdMVOc9CpWtDF09IkciQLEhK7Ml7gRA==
   dependencies:
     "@babel/code-frame" "^7.18.6"
-    "@babel/generator" "^7.18.10"
+    "@babel/generator" "^7.19.0"
     "@babel/helper-environment-visitor" "^7.18.9"
-    "@babel/helper-function-name" "^7.18.9"
+    "@babel/helper-function-name" "^7.19.0"
     "@babel/helper-hoist-variables" "^7.18.6"
     "@babel/helper-split-export-declaration" "^7.18.6"
-    "@babel/parser" "^7.18.11"
-    "@babel/types" "^7.18.10"
+    "@babel/parser" "^7.19.0"
+    "@babel/types" "^7.19.0"
     debug "^4.1.0"
     globals "^11.1.0"
 
-"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9":
-  version "7.18.10"
-  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.10.tgz#4908e81b6b339ca7c6b7a555a5fc29446f26dde6"
-  integrity sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==
+"@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.19.0":
+  version "7.19.0"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.0.tgz#75f21d73d73dc0351f3368d28db73465f4814600"
+  integrity sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==
   dependencies:
     "@babel/helper-string-parser" "^7.18.10"
     "@babel/helper-validator-identifier" "^7.18.6"
@@ -214,14 +214,14 @@
   dependencies:
     "@jridgewell/trace-mapping" "0.3.9"
 
-"@eslint/eslintrc@^1.3.0":
-  version "1.3.0"
-  resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f"
-  integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==
+"@eslint/eslintrc@^1.3.1":
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.1.tgz#de0807bfeffc37b964a7d0400e0c348ce5a2543d"
+  integrity sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==
   dependencies:
     ajv "^6.12.4"
     debug "^4.3.2"
-    espree "^9.3.2"
+    espree "^9.4.0"
     globals "^13.15.0"
     ignore "^5.2.0"
     import-fresh "^3.2.1"
@@ -246,180 +246,181 @@
     ethereumjs-util "^7.1.5"
 
 "@ethersproject/abi@^5.6.3":
-  version "5.6.4"
-  resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.4.tgz#f6e01b6ed391a505932698ecc0d9e7a99ee60362"
-  integrity sha512-TTeZUlCeIHG6527/2goZA6gW5F8Emoc7MrZDC7hhP84aRGvW3TEdTnZR08Ls88YXM1m2SuK42Osw/jSi3uO8gg==
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449"
+  integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==
   dependencies:
-    "@ethersproject/address" "^5.6.1"
-    "@ethersproject/bignumber" "^5.6.2"
-    "@ethersproject/bytes" "^5.6.1"
-    "@ethersproject/constants" "^5.6.1"
-    "@ethersproject/hash" "^5.6.1"
-    "@ethersproject/keccak256" "^5.6.1"
-    "@ethersproject/logger" "^5.6.0"
-    "@ethersproject/properties" "^5.6.0"
-    "@ethersproject/strings" "^5.6.1"
+    "@ethersproject/address" "^5.7.0"
+    "@ethersproject/bignumber" "^5.7.0"
+    "@ethersproject/bytes" "^5.7.0"
+    "@ethersproject/constants" "^5.7.0"
+    "@ethersproject/hash" "^5.7.0"
+    "@ethersproject/keccak256" "^5.7.0"
+    "@ethersproject/logger" "^5.7.0"
+    "@ethersproject/properties" "^5.7.0"
+    "@ethersproject/strings" "^5.7.0"
 
-"@ethersproject/abstract-provider@^5.6.1":
-  version "5.6.1"
-  resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.6.1.tgz#02ddce150785caf0c77fe036a0ebfcee61878c59"
-  integrity sha512-BxlIgogYJtp1FS8Muvj8YfdClk3unZH0vRMVX791Z9INBNT/kuACZ9GzaY1Y4yFq+YSy6/w4gzj3HCRKrK9hsQ==
+"@ethersproject/abstract-provider@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef"
+  integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==
   dependencies:
-    "@ethersproject/bignumber" "^5.6.2"
-    "@ethersproject/bytes" "^5.6.1"
-    "@ethersproject/logger" "^5.6.0"
-    "@ethersproject/networks" "^5.6.3"
-    "@ethersproject/properties" "^5.6.0"
-    "@ethersproject/transactions" "^5.6.2"
-    "@ethersproject/web" "^5.6.1"
+    "@ethersproject/bignumber" "^5.7.0"
+    "@ethersproject/bytes" "^5.7.0"
+    "@ethersproject/logger" "^5.7.0"
+    "@ethersproject/networks" "^5.7.0"
+    "@ethersproject/properties" "^5.7.0"
+    "@ethersproject/transactions" "^5.7.0"
+    "@ethersproject/web" "^5.7.0"
 
-"@ethersproject/abstract-signer@^5.6.2":
-  version "5.6.2"
-  resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.6.2.tgz#491f07fc2cbd5da258f46ec539664713950b0b33"
-  integrity sha512-n1r6lttFBG0t2vNiI3HoWaS/KdOt8xyDjzlP2cuevlWLG6EX0OwcKLyG/Kp/cuwNxdy/ous+R/DEMdTUwWQIjQ==
+"@ethersproject/abstract-signer@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2"
+  integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==
   dependencies:
-    "@ethersproject/abstract-provider" "^5.6.1"
-    "@ethersproject/bignumber" "^5.6.2"
-    "@ethersproject/bytes" "^5.6.1"
-    "@ethersproject/logger" "^5.6.0"
-    "@ethersproject/properties" "^5.6.0"
+    "@ethersproject/abstract-provider" "^5.7.0"
+    "@ethersproject/bignumber" "^5.7.0"
+    "@ethersproject/bytes" "^5.7.0"
+    "@ethersproject/logger" "^5.7.0"
+    "@ethersproject/properties" "^5.7.0"
 
-"@ethersproject/address@^5.6.1":
-  version "5.6.1"
-  resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.6.1.tgz#ab57818d9aefee919c5721d28cd31fd95eff413d"
-  integrity sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==
+"@ethersproject/address@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37"
+  integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==
   dependencies:
-    "@ethersproject/bignumber" "^5.6.2"
-    "@ethersproject/bytes" "^5.6.1"
-    "@ethersproject/keccak256" "^5.6.1"
-    "@ethersproject/logger" "^5.6.0"
-    "@ethersproject/rlp" "^5.6.1"
+    "@ethersproject/bignumber" "^5.7.0"
+    "@ethersproject/bytes" "^5.7.0"
+    "@ethersproject/keccak256" "^5.7.0"
+    "@ethersproject/logger" "^5.7.0"
+    "@ethersproject/rlp" "^5.7.0"
 
-"@ethersproject/base64@^5.6.1":
-  version "5.6.1"
-  resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.6.1.tgz#2c40d8a0310c9d1606c2c37ae3092634b41d87cb"
-  integrity sha512-qB76rjop6a0RIYYMiB4Eh/8n+Hxu2NIZm8S/Q7kNo5pmZfXhHGHmS4MinUainiBC54SCyRnwzL+KZjj8zbsSsw==
+"@ethersproject/base64@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c"
+  integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==
   dependencies:
-    "@ethersproject/bytes" "^5.6.1"
+    "@ethersproject/bytes" "^5.7.0"
 
-"@ethersproject/bignumber@^5.6.2":
-  version "5.6.2"
-  resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.6.2.tgz#72a0717d6163fab44c47bcc82e0c550ac0315d66"
-  integrity sha512-v7+EEUbhGqT3XJ9LMPsKvXYHFc8eHxTowFCG/HgJErmq4XHJ2WR7aeyICg3uTOAQ7Icn0GFHAohXEhxQHq4Ubw==
+"@ethersproject/bignumber@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2"
+  integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==
   dependencies:
-    "@ethersproject/bytes" "^5.6.1"
-    "@ethersproject/logger" "^5.6.0"
+    "@ethersproject/bytes" "^5.7.0"
+    "@ethersproject/logger" "^5.7.0"
     bn.js "^5.2.1"
 
-"@ethersproject/bytes@^5.6.1":
-  version "5.6.1"
-  resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.6.1.tgz#24f916e411f82a8a60412344bf4a813b917eefe7"
-  integrity sha512-NwQt7cKn5+ZE4uDn+X5RAXLp46E1chXoaMmrxAyA0rblpxz8t58lVkrHXoRIn0lz1joQElQ8410GqhTqMOwc6g==
+"@ethersproject/bytes@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d"
+  integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==
   dependencies:
-    "@ethersproject/logger" "^5.6.0"
+    "@ethersproject/logger" "^5.7.0"
 
-"@ethersproject/constants@^5.6.1":
-  version "5.6.1"
-  resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.6.1.tgz#e2e974cac160dd101cf79fdf879d7d18e8cb1370"
-  integrity sha512-QSq9WVnZbxXYFftrjSjZDUshp6/eKp6qrtdBtUCm0QxCV5z1fG/w3kdlcsjMCQuQHUnAclKoK7XpXMezhRDOLg==
+"@ethersproject/constants@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e"
+  integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==
   dependencies:
-    "@ethersproject/bignumber" "^5.6.2"
+    "@ethersproject/bignumber" "^5.7.0"
 
-"@ethersproject/hash@^5.6.1":
-  version "5.6.1"
-  resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.6.1.tgz#224572ea4de257f05b4abf8ae58b03a67e99b0f4"
-  integrity sha512-L1xAHurbaxG8VVul4ankNX5HgQ8PNCTrnVXEiFnE9xoRnaUcgfD12tZINtDinSllxPLCtGwguQxJ5E6keE84pA==
+"@ethersproject/hash@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7"
+  integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==
   dependencies:
-    "@ethersproject/abstract-signer" "^5.6.2"
-    "@ethersproject/address" "^5.6.1"
-    "@ethersproject/bignumber" "^5.6.2"
-    "@ethersproject/bytes" "^5.6.1"
-    "@ethersproject/keccak256" "^5.6.1"
-    "@ethersproject/logger" "^5.6.0"
-    "@ethersproject/properties" "^5.6.0"
-    "@ethersproject/strings" "^5.6.1"
+    "@ethersproject/abstract-signer" "^5.7.0"
+    "@ethersproject/address" "^5.7.0"
+    "@ethersproject/base64" "^5.7.0"
+    "@ethersproject/bignumber" "^5.7.0"
+    "@ethersproject/bytes" "^5.7.0"
+    "@ethersproject/keccak256" "^5.7.0"
+    "@ethersproject/logger" "^5.7.0"
+    "@ethersproject/properties" "^5.7.0"
+    "@ethersproject/strings" "^5.7.0"
 
-"@ethersproject/keccak256@^5.6.1":
-  version "5.6.1"
-  resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.6.1.tgz#b867167c9b50ba1b1a92bccdd4f2d6bd168a91cc"
-  integrity sha512-bB7DQHCTRDooZZdL3lk9wpL0+XuG3XLGHLh3cePnybsO3V0rdCAOQGpn/0R3aODmnTOOkCATJiD2hnL+5bwthA==
+"@ethersproject/keccak256@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a"
+  integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==
   dependencies:
-    "@ethersproject/bytes" "^5.6.1"
+    "@ethersproject/bytes" "^5.7.0"
     js-sha3 "0.8.0"
 
-"@ethersproject/logger@^5.6.0":
-  version "5.6.0"
-  resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.6.0.tgz#d7db1bfcc22fd2e4ab574cba0bb6ad779a9a3e7a"
-  integrity sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==
+"@ethersproject/logger@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892"
+  integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==
 
-"@ethersproject/networks@^5.6.3":
-  version "5.6.4"
-  resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.4.tgz#51296d8fec59e9627554f5a8a9c7791248c8dc07"
-  integrity sha512-KShHeHPahHI2UlWdtDMn2lJETcbtaJge4k7XSjDR9h79QTd6yQJmv6Cp2ZA4JdqWnhszAOLSuJEd9C0PRw7hSQ==
+"@ethersproject/networks@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.0.tgz#df72a392f1a63a57f87210515695a31a245845ad"
+  integrity sha512-MG6oHSQHd4ebvJrleEQQ4HhVu8Ichr0RDYEfHzsVAVjHNM+w36x9wp9r+hf1JstMXtseXDtkiVoARAG6M959AA==
   dependencies:
-    "@ethersproject/logger" "^5.6.0"
+    "@ethersproject/logger" "^5.7.0"
 
-"@ethersproject/properties@^5.6.0":
-  version "5.6.0"
-  resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.6.0.tgz#38904651713bc6bdd5bdd1b0a4287ecda920fa04"
-  integrity sha512-szoOkHskajKePTJSZ46uHUWWkbv7TzP2ypdEK6jGMqJaEt2sb0jCgfBo0gH0m2HBpRixMuJ6TBRaQCF7a9DoCg==
+"@ethersproject/properties@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30"
+  integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==
   dependencies:
-    "@ethersproject/logger" "^5.6.0"
+    "@ethersproject/logger" "^5.7.0"
 
-"@ethersproject/rlp@^5.6.1":
-  version "5.6.1"
-  resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.6.1.tgz#df8311e6f9f24dcb03d59a2bac457a28a4fe2bd8"
-  integrity sha512-uYjmcZx+DKlFUk7a5/W9aQVaoEC7+1MOBgNtvNg13+RnuUwT4F0zTovC0tmay5SmRslb29V1B7Y5KCri46WhuQ==
+"@ethersproject/rlp@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304"
+  integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==
   dependencies:
-    "@ethersproject/bytes" "^5.6.1"
-    "@ethersproject/logger" "^5.6.0"
+    "@ethersproject/bytes" "^5.7.0"
+    "@ethersproject/logger" "^5.7.0"
 
-"@ethersproject/signing-key@^5.6.2":
-  version "5.6.2"
-  resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.6.2.tgz#8a51b111e4d62e5a62aee1da1e088d12de0614a3"
-  integrity sha512-jVbu0RuP7EFpw82vHcL+GP35+KaNruVAZM90GxgQnGqB6crhBqW/ozBfFvdeImtmb4qPko0uxXjn8l9jpn0cwQ==
+"@ethersproject/signing-key@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3"
+  integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==
   dependencies:
-    "@ethersproject/bytes" "^5.6.1"
-    "@ethersproject/logger" "^5.6.0"
-    "@ethersproject/properties" "^5.6.0"
+    "@ethersproject/bytes" "^5.7.0"
+    "@ethersproject/logger" "^5.7.0"
+    "@ethersproject/properties" "^5.7.0"
     bn.js "^5.2.1"
     elliptic "6.5.4"
     hash.js "1.1.7"
 
-"@ethersproject/strings@^5.6.1":
-  version "5.6.1"
-  resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.6.1.tgz#dbc1b7f901db822b5cafd4ebf01ca93c373f8952"
-  integrity sha512-2X1Lgk6Jyfg26MUnsHiT456U9ijxKUybz8IM1Vih+NJxYtXhmvKBcHOmvGqpFSVJ0nQ4ZCoIViR8XlRw1v/+Cw==
+"@ethersproject/strings@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2"
+  integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==
   dependencies:
-    "@ethersproject/bytes" "^5.6.1"
-    "@ethersproject/constants" "^5.6.1"
-    "@ethersproject/logger" "^5.6.0"
+    "@ethersproject/bytes" "^5.7.0"
+    "@ethersproject/constants" "^5.7.0"
+    "@ethersproject/logger" "^5.7.0"
 
-"@ethersproject/transactions@^5.6.2":
-  version "5.6.2"
-  resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.6.2.tgz#793a774c01ced9fe7073985bb95a4b4e57a6370b"
-  integrity sha512-BuV63IRPHmJvthNkkt9G70Ullx6AcM+SDc+a8Aw/8Yew6YwT51TcBKEp1P4oOQ/bP25I18JJr7rcFRgFtU9B2Q==
+"@ethersproject/transactions@^5.6.2", "@ethersproject/transactions@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b"
+  integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==
   dependencies:
-    "@ethersproject/address" "^5.6.1"
-    "@ethersproject/bignumber" "^5.6.2"
-    "@ethersproject/bytes" "^5.6.1"
-    "@ethersproject/constants" "^5.6.1"
-    "@ethersproject/keccak256" "^5.6.1"
-    "@ethersproject/logger" "^5.6.0"
-    "@ethersproject/properties" "^5.6.0"
-    "@ethersproject/rlp" "^5.6.1"
-    "@ethersproject/signing-key" "^5.6.2"
+    "@ethersproject/address" "^5.7.0"
+    "@ethersproject/bignumber" "^5.7.0"
+    "@ethersproject/bytes" "^5.7.0"
+    "@ethersproject/constants" "^5.7.0"
+    "@ethersproject/keccak256" "^5.7.0"
+    "@ethersproject/logger" "^5.7.0"
+    "@ethersproject/properties" "^5.7.0"
+    "@ethersproject/rlp" "^5.7.0"
+    "@ethersproject/signing-key" "^5.7.0"
 
-"@ethersproject/web@^5.6.1":
-  version "5.6.1"
-  resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.6.1.tgz#6e2bd3ebadd033e6fe57d072db2b69ad2c9bdf5d"
-  integrity sha512-/vSyzaQlNXkO1WV+RneYKqCJwualcUdx/Z3gseVovZP0wIlOFcCE1hkRhKBH8ImKbGQbMl9EAAyJFrJu7V0aqA==
+"@ethersproject/web@^5.7.0":
+  version "5.7.0"
+  resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.0.tgz#40850c05260edad8b54827923bbad23d96aac0bc"
+  integrity sha512-ApHcbbj+muRASVDSCl/tgxaH2LBkRMEYfLOLVa0COipx0+nlu0QKet7U2lEg0vdkh8XRSLf2nd1f1Uk9SrVSGA==
   dependencies:
-    "@ethersproject/base64" "^5.6.1"
-    "@ethersproject/bytes" "^5.6.1"
-    "@ethersproject/logger" "^5.6.0"
-    "@ethersproject/properties" "^5.6.0"
-    "@ethersproject/strings" "^5.6.1"
+    "@ethersproject/base64" "^5.7.0"
+    "@ethersproject/bytes" "^5.7.0"
+    "@ethersproject/logger" "^5.7.0"
+    "@ethersproject/properties" "^5.7.0"
+    "@ethersproject/strings" "^5.7.0"
 
 "@humanwhocodes/config-array@^0.10.4":
   version "0.10.4"
@@ -435,6 +436,11 @@
   resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d"
   integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==
 
+"@humanwhocodes/module-importer@^1.0.1":
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
+  integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
+
 "@humanwhocodes/object-schema@^1.2.1":
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
@@ -597,31 +603,22 @@
     rxjs "^7.5.6"
 
 "@polkadot/keyring@^10.1.4":
-  version "10.1.4"
-  resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-10.1.4.tgz#7c60002cb442d2a160ee215b21c1319e85d97eaf"
-  integrity sha512-dCMejp5heZwKSFeO+1vCHFoo1h1KgNvu4AaKQdNxpyr/3eCINrCFI74/qT9XGypblxd61caOpJcMl8B1R/UWFA==
+  version "10.1.7"
+  resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-10.1.7.tgz#d51be1dc5807c961889847d8f0e10e4bbdd19d3f"
+  integrity sha512-lArwaAS3hDs+HHupDIC4r2mFaAfmNQV2YzwL2wM5zhOqB2RugN03BFrgwNll0y9/Bg8rYDqM3Y5BvVMzgMZ6XA==
   dependencies:
     "@babel/runtime" "^7.18.9"
-    "@polkadot/util" "10.1.4"
-    "@polkadot/util-crypto" "10.1.4"
+    "@polkadot/util" "10.1.7"
+    "@polkadot/util-crypto" "10.1.7"
 
-"@polkadot/networks@10.1.1":
-  version "10.1.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-10.1.1.tgz#d3deeff5c4cfad8c1eec85732351d80d1b2d0934"
-  integrity sha512-upM8r0mrsCVA+vPVbJUjtnkAfdleBMHB+Fbxvy3xtbK1IFpzQTUhSOQb6lBnBAPBFGyxMtQ3TytnInckAdYZeg==
+"@polkadot/networks@10.1.7", "@polkadot/networks@^10.1.4":
+  version "10.1.7"
+  resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-10.1.7.tgz#33b38d70409e2daf0990ef18ff150c6718ffb700"
+  integrity sha512-ol864SZ/GwAF72GQOPRy+Y9r6NtgJJjMBlDLESvV5VK64eEB0MRSSyiOdd7y/4SumR9crrrNimx3ynACFgxZ8A==
   dependencies:
     "@babel/runtime" "^7.18.9"
-    "@polkadot/util" "10.1.1"
-    "@substrate/ss58-registry" "^1.24.0"
-
-"@polkadot/networks@10.1.4", "@polkadot/networks@^10.1.4":
-  version "10.1.4"
-  resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-10.1.4.tgz#d8b375aad8f858f611165d8288eb5eab7275ca24"
-  integrity sha512-5wMwqD+DeVMh29OZZBVkA4DQE9EBsUj5FjmUS2CloA8RzE6SV0qL34zhTwOdq95KJV1OoDbp9aGjCBqhEuozKw==
-  dependencies:
-    "@babel/runtime" "^7.18.9"
-    "@polkadot/util" "10.1.4"
-    "@substrate/ss58-registry" "^1.25.0"
+    "@polkadot/util" "10.1.7"
+    "@substrate/ss58-registry" "^1.28.0"
 
 "@polkadot/rpc-augment@9.2.2":
   version "9.2.2"
@@ -758,64 +755,34 @@
     "@polkadot/util-crypto" "^10.1.4"
     rxjs "^7.5.6"
 
-"@polkadot/util-crypto@10.1.1":
-  version "10.1.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-10.1.1.tgz#c6e16e626e55402fdb44c8bb20ce4a9d7c50b9db"
-  integrity sha512-R0V++xXbL2pvnCFIuXnKc/TlNhBkyxcno1u8rmjYNuH9S5GOmi2jY/8cNhbrwk6wafBsi+xMPHrEbUnduk82Ag==
+"@polkadot/util-crypto@10.1.7", "@polkadot/util-crypto@^10.1.4":
+  version "10.1.7"
+  resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-10.1.7.tgz#fe5ea006bf23ae19319f3ac9236905a984a65e2f"
+  integrity sha512-zGmSU7a0wdWfpDtfc+Q7fUuW+extu9o1Uh4JpkuwwZ/dxmyW5xlfqVsIScM1pdPyjJsyamX8KwsKiVsW4slasg==
   dependencies:
     "@babel/runtime" "^7.18.9"
     "@noble/hashes" "1.1.2"
     "@noble/secp256k1" "1.6.3"
-    "@polkadot/networks" "10.1.1"
-    "@polkadot/util" "10.1.1"
+    "@polkadot/networks" "10.1.7"
+    "@polkadot/util" "10.1.7"
     "@polkadot/wasm-crypto" "^6.3.1"
-    "@polkadot/x-bigint" "10.1.1"
-    "@polkadot/x-randomvalues" "10.1.1"
-    "@scure/base" "1.1.1"
-    ed2curve "^0.3.0"
-    tweetnacl "^1.0.3"
-
-"@polkadot/util-crypto@10.1.4", "@polkadot/util-crypto@^10.1.4":
-  version "10.1.4"
-  resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-10.1.4.tgz#1d65a9b3d979f1cb078636a413cdf664db760a8b"
-  integrity sha512-6rdUwCdbwmQ0PBWBNYh55RsXAcFjhco/TGLuM7GJ7YufrN9qqv1sr40HlneLbtpiZnfukZ3q/qOpj0h7Hrw2JQ==
-  dependencies:
-    "@babel/runtime" "^7.18.9"
-    "@noble/hashes" "1.1.2"
-    "@noble/secp256k1" "1.6.3"
-    "@polkadot/networks" "10.1.4"
-    "@polkadot/util" "10.1.4"
-    "@polkadot/wasm-crypto" "^6.3.1"
-    "@polkadot/x-bigint" "10.1.4"
-    "@polkadot/x-randomvalues" "10.1.4"
+    "@polkadot/x-bigint" "10.1.7"
+    "@polkadot/x-randomvalues" "10.1.7"
     "@scure/base" "1.1.1"
     ed2curve "^0.3.0"
     tweetnacl "^1.0.3"
 
-"@polkadot/util@10.1.1":
-  version "10.1.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-10.1.1.tgz#5aa20eac03806e70dc21e618a7f8cd767dac0fd0"
-  integrity sha512-/g0sEqOOXfiNmQnWcFK3H1+wKBjbJEfGj6lTmbQ0xnL4TS5mFFQ7ZZEvxD60EkoXVMuCmSSh9E54goNLzh+Zyg==
-  dependencies:
-    "@babel/runtime" "^7.18.9"
-    "@polkadot/x-bigint" "10.1.1"
-    "@polkadot/x-global" "10.1.1"
-    "@polkadot/x-textdecoder" "10.1.1"
-    "@polkadot/x-textencoder" "10.1.1"
-    "@types/bn.js" "^5.1.0"
-    bn.js "^5.2.1"
-
-"@polkadot/util@10.1.4", "@polkadot/util@^10.1.4":
-  version "10.1.4"
-  resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-10.1.4.tgz#29654dd52d5028fd9ca175e9cebad605fa79396c"
-  integrity sha512-MHz1UxYXuV+XxPl+GR++yOUE0OCiVd+eJBqLgpjpVJNRkudbAmfGAbB2TNR0+76M0fevIeHj4DGEd0gY6vqKLw==
+"@polkadot/util@10.1.7", "@polkadot/util@^10.1.4":
+  version "10.1.7"
+  resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-10.1.7.tgz#c54ca2a5b29cb834b40d8a876baefa3a0efb93af"
+  integrity sha512-s7gDLdNb4HUpoe3faXwoO6HwiUp8pi66voYKiUYRh1kEtW1o9vGBgyZPHPGC/FBgILzTJKii/9XxnSex60zBTA==
   dependencies:
     "@babel/runtime" "^7.18.9"
-    "@polkadot/x-bigint" "10.1.4"
-    "@polkadot/x-global" "10.1.4"
-    "@polkadot/x-textdecoder" "10.1.4"
-    "@polkadot/x-textencoder" "10.1.4"
-    "@types/bn.js" "^5.1.0"
+    "@polkadot/x-bigint" "10.1.7"
+    "@polkadot/x-global" "10.1.7"
+    "@polkadot/x-textdecoder" "10.1.7"
+    "@polkadot/x-textencoder" "10.1.7"
+    "@types/bn.js" "^5.1.1"
     bn.js "^5.2.1"
 
 "@polkadot/wasm-bridge@6.3.1":
@@ -869,101 +836,62 @@
   dependencies:
     "@babel/runtime" "^7.18.9"
 
-"@polkadot/x-bigint@10.1.1":
-  version "10.1.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-10.1.1.tgz#c084cfdfe48633da07423f4d9916563882947563"
-  integrity sha512-YNYN64N4icKyqiDIw0tcGyWwz3g/282Kk0ozfcA5TM0wGRe2BwmoB4gYrZ7pJDxvsHnRPR6Dw0r9Xxh8DNIzHQ==
+"@polkadot/x-bigint@10.1.7", "@polkadot/x-bigint@^10.1.4":
+  version "10.1.7"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-10.1.7.tgz#1338689476ffdbb9f9cb243df1954ae8186134b9"
+  integrity sha512-uaClHpI6cnDumIfejUKvNTkB43JleEb0V6OIufDKJ/e1aCLE3f/Ws9ggwL8ea05lQP5k5xqOzbPdizi/UvrgKQ==
   dependencies:
     "@babel/runtime" "^7.18.9"
-    "@polkadot/x-global" "10.1.1"
-
-"@polkadot/x-bigint@10.1.4", "@polkadot/x-bigint@^10.1.4":
-  version "10.1.4"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-10.1.4.tgz#a084a9d2f80f25ffd529faafdf95cd6c3044ef74"
-  integrity sha512-qgLetTukFhkxNxNcUWMmnrfE9bp4TNbrqNoVBVH7wqSuEVpDPITBXsQ/78LbaaZGWD80Ew0wGxcZ/rqX+dLVUA==
-  dependencies:
-    "@babel/runtime" "^7.18.9"
-    "@polkadot/x-global" "10.1.4"
+    "@polkadot/x-global" "10.1.7"
 
 "@polkadot/x-fetch@^10.1.4":
-  version "10.1.4"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-10.1.4.tgz#72db88007c74f3aee47f72091a33d553f7ca241a"
-  integrity sha512-hVhLpOvx+ys6klkqWJnINi9FU/JcDnc+6cyU9fa+Dum3mqO1XnngOYDO9mpf5HODIwrFNFmohll9diRP+TW0yQ==
+  version "10.1.7"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-10.1.7.tgz#1b76051a495563403a20ef235a8558c6d91b11a6"
+  integrity sha512-NL+xrlqUoCLwCIAvQLwOA189gSUgeSGOFjCmZ9uMkBqf35KXeZoHWse6YaoseTSlnAal3dQOGbXnYWZ4Ck2OSA==
   dependencies:
     "@babel/runtime" "^7.18.9"
-    "@polkadot/x-global" "10.1.4"
+    "@polkadot/x-global" "10.1.7"
     "@types/node-fetch" "^2.6.2"
     node-fetch "^3.2.10"
 
-"@polkadot/x-global@10.1.1":
-  version "10.1.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-10.1.1.tgz#d0d90ef71fd94f59605e8c73dcd1aa3e3dd4fc37"
-  integrity sha512-wB3rZTTNN14umLSfR2GLL0dJrlGM1YRUNw7XvbA+3B8jxGCIOmjSyAkdZBeiCxg2XIbJD3EkB0hBhga2mNuS6g==
+"@polkadot/x-global@10.1.7", "@polkadot/x-global@^10.1.4":
+  version "10.1.7"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-10.1.7.tgz#91a472ac2f83fd0858dcd0df528844a5b650790e"
+  integrity sha512-k2ZUZyBVgDnP/Ysxapa0mthn63j6gsN2V0kZejEQPyOfCHtQQkse3jFvAWdslpWoR8j2k8SN5O6reHc0F4f7mA==
   dependencies:
     "@babel/runtime" "^7.18.9"
 
-"@polkadot/x-global@10.1.4", "@polkadot/x-global@^10.1.4":
-  version "10.1.4"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-10.1.4.tgz#657f7054fe07a7c027b4d18fcfa3438d2ffaef07"
-  integrity sha512-67f53H872wHvmjmL96DvhC3dG7gKRG1ghEbHXeFIGwkix+9zGEMV9krYW1+OAvGAuCQZqUIUGiJ7lad4Zjb7wQ==
+"@polkadot/x-randomvalues@10.1.7":
+  version "10.1.7"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-10.1.7.tgz#d537f1f7bf3fb03e6c08ae6e6ac36e069c1f9844"
+  integrity sha512-3er4UYOlozLGgFYWwcbmcFslmO8m82u4cAGR4AaEag0VdV7jLO/M5lTmivT/3rtLSww6sjkEfr522GM2Q5lmFg==
   dependencies:
     "@babel/runtime" "^7.18.9"
+    "@polkadot/x-global" "10.1.7"
 
-"@polkadot/x-randomvalues@10.1.1":
-  version "10.1.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-10.1.1.tgz#3b1f590e6641e322e3a28bb4f17f0a53005d9ada"
-  integrity sha512-opVFNEnzCir7cWsFfyDqNlrGazkpjnL+JpkxE/b9WmSco6y0IUzn/Q7rL3EaBzBEvxY0/J8KeSGGs3W+mf6tBQ==
+"@polkadot/x-textdecoder@10.1.7":
+  version "10.1.7"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-10.1.7.tgz#1dd4e6141b1669acdd321a4da1fc6fdc271b7908"
+  integrity sha512-iAFOHludmZFOyVL8sQFv4TDqbcqQU5gwwYv74duTA+WQBgbSITJrBahSCV/rXOjUqds9pzQO3qBFzziznNnkiQ==
   dependencies:
     "@babel/runtime" "^7.18.9"
-    "@polkadot/x-global" "10.1.1"
+    "@polkadot/x-global" "10.1.7"
 
-"@polkadot/x-randomvalues@10.1.4":
-  version "10.1.4"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-10.1.4.tgz#de337a046826223081697e6fc1991c547f685787"
-  integrity sha512-sfYz3GmyG739anj07Y+8PUX+95upO1zlsADAEfK1w1mMpTw97xEoMZf66CduAQOe43gEwQXc/JuKq794C/Hr7Q==
+"@polkadot/x-textencoder@10.1.7":
+  version "10.1.7"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-10.1.7.tgz#b208601f33b936c7a059f126dbb6b26a87f45864"
+  integrity sha512-GzjaWZDbgzZ0IQT60xuZ7cZ0wnlNVYMqpfI9KvBc58X9dPI3TIMwzbXDVzZzpjY1SAqJGs4hJse9HMWZazfhew==
   dependencies:
     "@babel/runtime" "^7.18.9"
-    "@polkadot/x-global" "10.1.4"
-
-"@polkadot/x-textdecoder@10.1.1":
-  version "10.1.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-10.1.1.tgz#536d0093749fcc14a60d4ae29c35f699dea7e651"
-  integrity sha512-a52ah/sUS+aGZcCCL7BhrytAeV/7kiqu1zbuCoZtIzxP6x34a2vcic3bLPoyynLcX2ruzvLKFhJDGOJ4Bq5lcA==
-  dependencies:
-    "@babel/runtime" "^7.18.9"
-    "@polkadot/x-global" "10.1.1"
-
-"@polkadot/x-textdecoder@10.1.4":
-  version "10.1.4"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-10.1.4.tgz#d85028f6fcd00adc1e3581ab97668a61299270f9"
-  integrity sha512-B8XcAmJLnuppSr4RUNPevh5MH3tWZBwBR0wUsSdIyiGXuncgnkj9jmpbGLgV1tSn+BGxX3SNsRho3/4CNmndWQ==
-  dependencies:
-    "@babel/runtime" "^7.18.9"
-    "@polkadot/x-global" "10.1.4"
-
-"@polkadot/x-textencoder@10.1.1":
-  version "10.1.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-10.1.1.tgz#c1a86b3d0fe0ca65d30c8ce5c6f75c4035e95847"
-  integrity sha512-prTzUXXW9OxFyf17EwGSBxe2GvVFG60cmKV8goC50nghhNMl1y0GdGpvKNQTFG6hIk5fIon9/pBpWsas4iAf+Q==
-  dependencies:
-    "@babel/runtime" "^7.18.9"
-    "@polkadot/x-global" "10.1.1"
-
-"@polkadot/x-textencoder@10.1.4":
-  version "10.1.4"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-10.1.4.tgz#253e828bb571eb2a92a8377acd57d9bfcbe52fe8"
-  integrity sha512-vDpo0rVV4jBmr0L2tCZPZzxmzV2vZhpH1Dw9H7MpmZSPePz4ZF+o4RBJz/ocwQh3+1qV1SKQm7+fj4lPwUZdEw==
-  dependencies:
-    "@babel/runtime" "^7.18.9"
-    "@polkadot/x-global" "10.1.4"
+    "@polkadot/x-global" "10.1.7"
 
 "@polkadot/x-ws@^10.1.4":
-  version "10.1.4"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-10.1.4.tgz#b3fa515598bc6f8e85d92754d5f1c4be19ca44a1"
-  integrity sha512-hi7hBRRCLlHgqVW2p5TkoJuTxV7sVprl+aAnmcIpPU4J8Ai6PKQvXR+fLK01T8moBYmH5ztHrBWvY/XRzmQ8Vg==
+  version "10.1.7"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-10.1.7.tgz#b1fbfe3e16fa809f35f24ef47fde145b018d8cdc"
+  integrity sha512-aNkotxHx3qPVjiItD9lbNONs4GNzqeeZ98wHtCjd9JWl/g+xNkOVF3xQ8++1qSHPBEYSwKh9URjQH2+CD2XlvQ==
   dependencies:
     "@babel/runtime" "^7.18.9"
-    "@polkadot/x-global" "10.1.4"
+    "@polkadot/x-global" "10.1.7"
     "@types/websocket" "^1.0.5"
     websocket "^1.0.34"
 
@@ -972,7 +900,7 @@
   resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
   integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==
 
-"@sindresorhus/is@^4.6.0":
+"@sindresorhus/is@^4.0.0", "@sindresorhus/is@^4.6.0":
   version "4.6.0"
   resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f"
   integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==
@@ -999,10 +927,17 @@
     pako "^2.0.4"
     websocket "^1.0.32"
 
-"@substrate/ss58-registry@^1.24.0", "@substrate/ss58-registry@^1.25.0":
-  version "1.25.0"
-  resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.25.0.tgz#0fcd8c9c0e53963a88fbed41f2cbd8a1a5c74cde"
-  integrity sha512-LmCH4QJRdHaeLsLTPSgJaXguMoIW+Ig9fA9LRPpeya9HefVAJ7gZuUYinldv+QmX7evNm5CL0rspNUS8l1DvXg==
+"@substrate/ss58-registry@^1.28.0":
+  version "1.29.0"
+  resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.29.0.tgz#0dea078271b5318c5eff7176e1df1f9b2c27e43f"
+  integrity sha512-KTqwZgTjtWPhCAUJJx9qswP/p9cRKUU9GOHYUDKNdISFDiFafWmpI54JHfYLkgjvkSKEUgRZnvLpe0LMF1fXvw==
+
+"@szmarczak/http-timer@^4.0.5":
+  version "4.0.6"
+  resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807"
+  integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==
+  dependencies:
+    defer-to-connect "^2.0.0"
 
 "@szmarczak/http-timer@^5.0.1":
   version "5.0.1"
@@ -1031,14 +966,14 @@
   resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e"
   integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==
 
-"@types/bn.js@^5.1.0":
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68"
-  integrity sha512-QSSVYj7pYFN49kW77o2s9xTCwZ8F2xLbjLLSEVh8D2F4JUhZtPAGOFLTD+ffqksBx/u4cE/KImFjyhqCjn/LIA==
+"@types/bn.js@^5.1.0", "@types/bn.js@^5.1.1":
+  version "5.1.1"
+  resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682"
+  integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g==
   dependencies:
     "@types/node" "*"
 
-"@types/cacheable-request@^6.0.2":
+"@types/cacheable-request@^6.0.1", "@types/cacheable-request@^6.0.2":
   version "6.0.2"
   resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.2.tgz#c324da0197de0a98a2312156536ae262429ff6b9"
   integrity sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==
@@ -1096,11 +1031,6 @@
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812"
   integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==
-
-"@types/json-buffer@~3.0.0":
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/@types/json-buffer/-/json-buffer-3.0.0.tgz#85c1ff0f0948fc159810d4b5be35bf8c20875f64"
-  integrity sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==
 
 "@types/json-schema@^7.0.9":
   version "7.0.11"
@@ -1128,9 +1058,9 @@
     form-data "^3.0.0"
 
 "@types/node@*":
-  version "18.7.5"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.5.tgz#f1c1d4b7d8231c0278962347163656f9c36f3e83"
-  integrity sha512-NcKK6Ts+9LqdHJaW6HQmgr7dT/i3GOHG+pt6BiWv++5SnjtRd4NXeiuN2kA153SjhXPR/AhHIPHPbrsbpUVOww==
+  version "18.7.16"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.16.tgz#0eb3cce1e37c79619943d2fd903919fc30850601"
+  integrity sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg==
 
 "@types/node@^12.12.6":
   version "12.20.55"
@@ -1171,13 +1101,13 @@
     "@types/node" "*"
 
 "@typescript-eslint/eslint-plugin@^5.26.0":
-  version "5.33.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.1.tgz#c0a480d05211660221eda963cc844732fe9b1714"
-  integrity sha512-S1iZIxrTvKkU3+m63YUOxYPKaP+yWDQrdhxTglVDVEVBf+aCSw85+BmJnyUaQQsk5TXFG/LpBu9fa+LrAQ91fQ==
+  version "5.36.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.2.tgz#6df092a20e0f9ec748b27f293a12cb39d0c1fe4d"
+  integrity sha512-OwwR8LRwSnI98tdc2z7mJYgY60gf7I9ZfGjN5EjCwwns9bdTuQfAXcsjSB2wSQ/TVNYSGKf4kzVXbNGaZvwiXw==
   dependencies:
-    "@typescript-eslint/scope-manager" "5.33.1"
-    "@typescript-eslint/type-utils" "5.33.1"
-    "@typescript-eslint/utils" "5.33.1"
+    "@typescript-eslint/scope-manager" "5.36.2"
+    "@typescript-eslint/type-utils" "5.36.2"
+    "@typescript-eslint/utils" "5.36.2"
     debug "^4.3.4"
     functional-red-black-tree "^1.0.1"
     ignore "^5.2.0"
@@ -1186,68 +1116,69 @@
     tsutils "^3.21.0"
 
 "@typescript-eslint/parser@^5.26.0":
-  version "5.33.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.33.1.tgz#e4b253105b4d2a4362cfaa4e184e2d226c440ff3"
-  integrity sha512-IgLLtW7FOzoDlmaMoXdxG8HOCByTBXrB1V2ZQYSEV1ggMmJfAkMWTwUjjzagS6OkfpySyhKFkBw7A9jYmcHpZA==
+  version "5.36.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.36.2.tgz#3ddf323d3ac85a25295a55fcb9c7a49ab4680ddd"
+  integrity sha512-qS/Kb0yzy8sR0idFspI9Z6+t7mqk/oRjnAYfewG+VN73opAUvmYL3oPIMmgOX6CnQS6gmVIXGshlb5RY/R22pA==
   dependencies:
-    "@typescript-eslint/scope-manager" "5.33.1"
-    "@typescript-eslint/types" "5.33.1"
-    "@typescript-eslint/typescript-estree" "5.33.1"
+    "@typescript-eslint/scope-manager" "5.36.2"
+    "@typescript-eslint/types" "5.36.2"
+    "@typescript-eslint/typescript-estree" "5.36.2"
     debug "^4.3.4"
 
-"@typescript-eslint/scope-manager@5.33.1":
-  version "5.33.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.33.1.tgz#8d31553e1b874210018ca069b3d192c6d23bc493"
-  integrity sha512-8ibcZSqy4c5m69QpzJn8XQq9NnqAToC8OdH/W6IXPXv83vRyEDPYLdjAlUx8h/rbusq6MkW4YdQzURGOqsn3CA==
+"@typescript-eslint/scope-manager@5.36.2":
+  version "5.36.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.36.2.tgz#a75eb588a3879ae659514780831370642505d1cd"
+  integrity sha512-cNNP51L8SkIFSfce8B1NSUBTJTu2Ts4nWeWbFrdaqjmn9yKrAaJUBHkyTZc0cL06OFHpb+JZq5AUHROS398Orw==
   dependencies:
-    "@typescript-eslint/types" "5.33.1"
-    "@typescript-eslint/visitor-keys" "5.33.1"
+    "@typescript-eslint/types" "5.36.2"
+    "@typescript-eslint/visitor-keys" "5.36.2"
 
-"@typescript-eslint/type-utils@5.33.1":
-  version "5.33.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.33.1.tgz#1a14e94650a0ae39f6e3b77478baff002cec4367"
-  integrity sha512-X3pGsJsD8OiqhNa5fim41YtlnyiWMF/eKsEZGsHID2HcDqeSC5yr/uLOeph8rNF2/utwuI0IQoAK3fpoxcLl2g==
+"@typescript-eslint/type-utils@5.36.2":
+  version "5.36.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.36.2.tgz#752373f4babf05e993adf2cd543a763632826391"
+  integrity sha512-rPQtS5rfijUWLouhy6UmyNquKDPhQjKsaKH0WnY6hl/07lasj8gPaH2UD8xWkePn6SC+jW2i9c2DZVDnL+Dokw==
   dependencies:
-    "@typescript-eslint/utils" "5.33.1"
+    "@typescript-eslint/typescript-estree" "5.36.2"
+    "@typescript-eslint/utils" "5.36.2"
     debug "^4.3.4"
     tsutils "^3.21.0"
 
-"@typescript-eslint/types@5.33.1":
-  version "5.33.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.33.1.tgz#3faef41793d527a519e19ab2747c12d6f3741ff7"
-  integrity sha512-7K6MoQPQh6WVEkMrMW5QOA5FO+BOwzHSNd0j3+BlBwd6vtzfZceJ8xJ7Um2XDi/O3umS8/qDX6jdy2i7CijkwQ==
+"@typescript-eslint/types@5.36.2":
+  version "5.36.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.36.2.tgz#a5066e500ebcfcee36694186ccc57b955c05faf9"
+  integrity sha512-9OJSvvwuF1L5eS2EQgFUbECb99F0mwq501w0H0EkYULkhFa19Qq7WFbycdw1PexAc929asupbZcgjVIe6OK/XQ==
 
-"@typescript-eslint/typescript-estree@5.33.1":
-  version "5.33.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.33.1.tgz#a573bd360790afdcba80844e962d8b2031984f34"
-  integrity sha512-JOAzJ4pJ+tHzA2pgsWQi4804XisPHOtbvwUyqsuuq8+y5B5GMZs7lI1xDWs6V2d7gE/Ez5bTGojSK12+IIPtXA==
+"@typescript-eslint/typescript-estree@5.36.2":
+  version "5.36.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.2.tgz#0c93418b36c53ba0bc34c61fe9405c4d1d8fe560"
+  integrity sha512-8fyH+RfbKc0mTspfuEjlfqA4YywcwQK2Amcf6TDOwaRLg7Vwdu4bZzyvBZp4bjt1RRjQ5MDnOZahxMrt2l5v9w==
   dependencies:
-    "@typescript-eslint/types" "5.33.1"
-    "@typescript-eslint/visitor-keys" "5.33.1"
+    "@typescript-eslint/types" "5.36.2"
+    "@typescript-eslint/visitor-keys" "5.36.2"
     debug "^4.3.4"
     globby "^11.1.0"
     is-glob "^4.0.3"
     semver "^7.3.7"
     tsutils "^3.21.0"
 
-"@typescript-eslint/utils@5.33.1":
-  version "5.33.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.33.1.tgz#171725f924fe1fe82bb776522bb85bc034e88575"
-  integrity sha512-uphZjkMaZ4fE8CR4dU7BquOV6u0doeQAr8n6cQenl/poMaIyJtBu8eys5uk6u5HiDH01Mj5lzbJ5SfeDz7oqMQ==
+"@typescript-eslint/utils@5.36.2":
+  version "5.36.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.36.2.tgz#b01a76f0ab244404c7aefc340c5015d5ce6da74c"
+  integrity sha512-uNcopWonEITX96v9pefk9DC1bWMdkweeSsewJ6GeC7L6j2t0SJywisgkr9wUTtXk90fi2Eljj90HSHm3OGdGRg==
   dependencies:
     "@types/json-schema" "^7.0.9"
-    "@typescript-eslint/scope-manager" "5.33.1"
-    "@typescript-eslint/types" "5.33.1"
-    "@typescript-eslint/typescript-estree" "5.33.1"
+    "@typescript-eslint/scope-manager" "5.36.2"
+    "@typescript-eslint/types" "5.36.2"
+    "@typescript-eslint/typescript-estree" "5.36.2"
     eslint-scope "^5.1.1"
     eslint-utils "^3.0.0"
 
-"@typescript-eslint/visitor-keys@5.33.1":
-  version "5.33.1"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.33.1.tgz#0155c7571c8cd08956580b880aea327d5c34a18b"
-  integrity sha512-nwIxOK8Z2MPWltLKMLOEZwmfBZReqUdbEoHQXeCpa+sRVARe5twpJGHCB4dk9903Yaf0nMAlGbQfaAH92F60eg==
+"@typescript-eslint/visitor-keys@5.36.2":
+  version "5.36.2"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.2.tgz#2f8f78da0a3bad3320d2ac24965791ac39dace5a"
+  integrity sha512-BtRvSR6dEdrNt7Net2/XDjbYKU5Ml6GqJgVfXT0CxTCJlnIqK7rAGreuWKMT2t8cFUT2Msv5oxw0GMRD7T5J7A==
   dependencies:
-    "@typescript-eslint/types" "5.33.1"
+    "@typescript-eslint/types" "5.36.2"
     eslint-visitor-keys "^3.3.0"
 
 "@ungap/promise-all-settled@1.1.2":
@@ -1621,6 +1552,11 @@
   resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
   integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
 
+cacheable-lookup@^5.0.3:
+  version "5.0.4"
+  resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005"
+  integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==
+
 cacheable-lookup@^6.0.4:
   version "6.1.0"
   resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz#0330a543471c61faa4e9035db583aad753b36385"
@@ -1658,9 +1594,9 @@
   integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
 
 caniuse-lite@^1.0.30001370:
-  version "1.0.30001377"
-  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001377.tgz#fa446cef27f25decb0c7420759c9ea17a2221a70"
-  integrity sha512-I5XeHI1x/mRSGl96LFOaSk528LA/yZG3m3iQgImGujjO8gotd/DL8QaI1R1h1dg5ATeI2jqPblMpKq4Tr5iKfQ==
+  version "1.0.30001393"
+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001393.tgz#1aa161e24fe6af2e2ccda000fc2b94be0b0db356"
+  integrity sha512-N/od11RX+Gsk+1qY/jbPa0R6zJupEa0lxeBG598EbrtblxVCTJsQwbRBm6+V+rxpc5lHKdsXb9RY83cZIPLseA==
 
 caseless@~0.12.0:
   version "0.12.0"
@@ -1834,14 +1770,6 @@
   resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
   integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
 
-compress-brotli@^1.3.8:
-  version "1.3.8"
-  resolved "https://registry.yarnpkg.com/compress-brotli/-/compress-brotli-1.3.8.tgz#0c0a60c97a989145314ec381e84e26682e7b38db"
-  integrity sha512-lVcQsjhxhIXsuupfy9fmZUFtAIdBmXA7EGY6GBdgZ++qkM9zG4YFT8iU7FoBxzryNDMOpD1HIFHUSX4D87oqhQ==
-  dependencies:
-    "@types/json-buffer" "~3.0.0"
-    json-buffer "~3.0.1"
-
 concat-map@0.0.1:
   version "0.0.1"
   resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@@ -2016,13 +1944,6 @@
   resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
   integrity sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==
 
-decompress-response@^3.2.0:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3"
-  integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==
-  dependencies:
-    mimic-response "^1.0.0"
-
 decompress-response@^6.0.0:
   version "6.0.0"
   resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc"
@@ -2042,7 +1963,7 @@
   resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
   integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
 
-defer-to-connect@^2.0.1:
+defer-to-connect@^2.0.0, defer-to-connect@^2.0.1:
   version "2.0.1"
   resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587"
   integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==
@@ -2115,11 +2036,6 @@
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
   integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==
-
-duplexer3@^0.1.4:
-  version "0.1.5"
-  resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e"
-  integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==
 
 ecc-jsbn@~0.1.1:
   version "0.1.2"
@@ -2142,9 +2058,9 @@
   integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
 
 electron-to-chromium@^1.4.202:
-  version "1.4.221"
-  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.221.tgz#1ff8425d257a8bfc8269d552a426993c5b525471"
-  integrity sha512-aWg2mYhpxZ6Q6Xvyk7B2ziBca4YqrCDlXzmcD7wuRs65pVEVkMT1u2ifdjpAQais2O2o0rW964ZWWWYRlAL/kw==
+  version "1.4.246"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.246.tgz#802132d1bbd3ff32ce82fcd6a6ed6ab59b4366dc"
+  integrity sha512-/wFCHUE+Hocqr/LlVGsuKLIw4P2lBWwFIDcNMDpJGzyIysQV4aycpoOitAs32FT94EHKnNqDR/CVZJFbXEufJA==
 
 elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4:
   version "6.5.4"
@@ -2177,15 +2093,15 @@
     once "^1.4.0"
 
 es-abstract@^1.19.0, es-abstract@^1.19.5, es-abstract@^1.20.0:
-  version "1.20.1"
-  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814"
-  integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==
+  version "1.20.2"
+  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.2.tgz#8495a07bc56d342a3b8ea3ab01bd986700c2ccb3"
+  integrity sha512-XxXQuVNrySBNlEkTYJoDNFe5+s2yIOpzq80sUHEdPdQr0S5nTLz4ZPPPswNIpKseDDUS5yghX1gfLIHQZ1iNuQ==
   dependencies:
     call-bind "^1.0.2"
     es-to-primitive "^1.2.1"
     function-bind "^1.1.1"
     function.prototype.name "^1.1.5"
-    get-intrinsic "^1.1.1"
+    get-intrinsic "^1.1.2"
     get-symbol-description "^1.0.0"
     has "^1.0.3"
     has-property-descriptors "^1.0.0"
@@ -2197,9 +2113,9 @@
     is-shared-array-buffer "^1.0.2"
     is-string "^1.0.7"
     is-weakref "^1.0.2"
-    object-inspect "^1.12.0"
+    object-inspect "^1.12.2"
     object-keys "^1.1.1"
-    object.assign "^4.1.2"
+    object.assign "^4.1.4"
     regexp.prototype.flags "^1.4.3"
     string.prototype.trimend "^1.0.5"
     string.prototype.trimstart "^1.0.5"
@@ -2299,13 +2215,14 @@
   integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
 
 eslint@^8.16.0:
-  version "8.22.0"
-  resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.22.0.tgz#78fcb044196dfa7eef30a9d65944f6f980402c48"
-  integrity sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA==
+  version "8.23.0"
+  resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.23.0.tgz#a184918d288820179c6041bb3ddcc99ce6eea040"
+  integrity sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==
   dependencies:
-    "@eslint/eslintrc" "^1.3.0"
+    "@eslint/eslintrc" "^1.3.1"
     "@humanwhocodes/config-array" "^0.10.4"
     "@humanwhocodes/gitignore-to-minimatch" "^1.0.2"
+    "@humanwhocodes/module-importer" "^1.0.1"
     ajv "^6.10.0"
     chalk "^4.0.0"
     cross-spawn "^7.0.2"
@@ -2315,7 +2232,7 @@
     eslint-scope "^7.1.1"
     eslint-utils "^3.0.0"
     eslint-visitor-keys "^3.3.0"
-    espree "^9.3.3"
+    espree "^9.4.0"
     esquery "^1.4.0"
     esutils "^2.0.2"
     fast-deep-equal "^3.1.3"
@@ -2341,12 +2258,11 @@
     strip-ansi "^6.0.1"
     strip-json-comments "^3.1.0"
     text-table "^0.2.0"
-    v8-compile-cache "^2.0.3"
 
-espree@^9.3.2, espree@^9.3.3:
-  version "9.3.3"
-  resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.3.tgz#2dd37c4162bb05f433ad3c1a52ddf8a49dc08e9d"
-  integrity sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==
+espree@^9.4.0:
+  version "9.4.0"
+  resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a"
+  integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==
   dependencies:
     acorn "^8.8.0"
     acorn-jsx "^5.3.2"
@@ -2518,11 +2434,11 @@
     vary "~1.1.2"
 
 ext@^1.1.2:
-  version "1.6.0"
-  resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52"
-  integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==
+  version "1.7.0"
+  resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f"
+  integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==
   dependencies:
-    type "^2.5.0"
+    type "^2.7.2"
 
 extend@~3.0.2:
   version "3.0.2"
@@ -2545,9 +2461,9 @@
   integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
 
 fast-glob@^3.2.9:
-  version "3.2.11"
-  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9"
-  integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==
+  version "3.2.12"
+  resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80"
+  integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==
   dependencies:
     "@nodelib/fs.stat" "^2.0.2"
     "@nodelib/fs.walk" "^1.2.3"
@@ -2654,9 +2570,9 @@
   integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
 
 flatted@^3.1.0:
-  version "3.2.6"
-  resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2"
-  integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==
+  version "3.2.7"
+  resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
+  integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
 
 follow-redirects@^1.12.1:
   version "1.15.1"
@@ -2781,7 +2697,7 @@
   resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
   integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==
 
-get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
+get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.2:
   version "1.1.2"
   resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598"
   integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==
@@ -2789,11 +2705,6 @@
     function-bind "^1.1.1"
     has "^1.0.3"
     has-symbols "^1.0.3"
-
-get-stream@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14"
-  integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==
 
 get-stream@^5.1.0:
   version "5.2.0"
@@ -2911,25 +2822,22 @@
     p-cancelable "^3.0.0"
     responselike "^2.0.0"
 
-got@^7.1.0:
-  version "7.1.0"
-  resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a"
-  integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==
+got@^11.8.5:
+  version "11.8.5"
+  resolved "https://registry.yarnpkg.com/got/-/got-11.8.5.tgz#ce77d045136de56e8f024bebb82ea349bc730046"
+  integrity sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==
   dependencies:
-    decompress-response "^3.2.0"
-    duplexer3 "^0.1.4"
-    get-stream "^3.0.0"
-    is-plain-obj "^1.1.0"
-    is-retry-allowed "^1.0.0"
-    is-stream "^1.0.0"
-    isurl "^1.0.0-alpha5"
-    lowercase-keys "^1.0.0"
-    p-cancelable "^0.3.0"
-    p-timeout "^1.1.1"
-    safe-buffer "^5.0.1"
-    timed-out "^4.0.0"
-    url-parse-lax "^1.0.0"
-    url-to-options "^1.0.1"
+    "@sindresorhus/is" "^4.0.0"
+    "@szmarczak/http-timer" "^4.0.5"
+    "@types/cacheable-request" "^6.0.1"
+    "@types/responselike" "^1.0.0"
+    cacheable-lookup "^5.0.3"
+    cacheable-request "^7.0.2"
+    decompress-response "^6.0.0"
+    http2-wrapper "^1.0.0-beta.5.2"
+    lowercase-keys "^2.0.0"
+    p-cancelable "^2.0.0"
+    responselike "^2.0.0"
 
 graceful-fs@^4.1.2, graceful-fs@^4.1.6:
   version "4.2.10"
@@ -2988,22 +2896,10 @@
   dependencies:
     get-intrinsic "^1.1.1"
 
-has-symbol-support-x@^1.4.1:
-  version "1.4.2"
-  resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455"
-  integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==
-
 has-symbols@^1.0.2, has-symbols@^1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8"
   integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==
-
-has-to-string-tag-x@^1.2.0:
-  version "1.4.1"
-  resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d"
-  integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==
-  dependencies:
-    has-symbol-support-x "^1.4.1"
 
 has-tostringtag@^1.0.0:
   version "1.0.0"
@@ -3080,6 +2976,14 @@
     jsprim "^1.2.2"
     sshpk "^1.7.0"
 
+http2-wrapper@^1.0.0-beta.5.2:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d"
+  integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==
+  dependencies:
+    quick-lru "^5.1.1"
+    resolve-alpn "^1.0.0"
+
 http2-wrapper@^2.1.10:
   version "2.1.11"
   resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.1.11.tgz#d7c980c7ffb85be3859b6a96c800b2951ae257ef"
@@ -3244,16 +3148,6 @@
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
   integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
-
-is-object@^1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf"
-  integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==
-
-is-plain-obj@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e"
-  integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==
 
 is-plain-obj@^2.1.0:
   version "2.1.0"
@@ -3274,11 +3168,6 @@
   dependencies:
     call-bind "^1.0.2"
     has-tostringtag "^1.0.0"
-
-is-retry-allowed@^1.0.0:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
-  integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
 
 is-shared-array-buffer@^1.0.2:
   version "1.0.2"
@@ -3287,11 +3176,6 @@
   dependencies:
     call-bind "^1.0.2"
 
-is-stream@^1.0.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
-  integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==
-
 is-string@^1.0.5, is-string@^1.0.7:
   version "1.0.7"
   resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd"
@@ -3348,14 +3232,6 @@
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
   integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==
-
-isurl@^1.0.0-alpha5:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67"
-  integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==
-  dependencies:
-    has-to-string-tag-x "^1.2.0"
-    is-object "^1.0.1"
 
 js-sha3@0.8.0, js-sha3@^0.8.0:
   version "0.8.0"
@@ -3389,7 +3265,7 @@
   resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
   integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
 
-json-buffer@3.0.1, json-buffer@~3.0.1:
+json-buffer@3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
   integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
@@ -3446,11 +3322,10 @@
     readable-stream "^3.6.0"
 
 keyv@^4.0.0:
-  version "4.3.3"
-  resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.3.3.tgz#6c1bcda6353a9e96fc1b4e1aeb803a6e35090ba9"
-  integrity sha512-AcysI17RvakTh8ir03+a3zJr5r0ovnAH/XTXei/4HIv3bL2K/jzvgivLK9UuI/JbU1aJjM3NSAnVvVVd3n+4DQ==
+  version "4.5.0"
+  resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.0.tgz#dbce9ade79610b6e641a9a65f2f6499ba06b9bc6"
+  integrity sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==
   dependencies:
-    compress-brotli "^1.3.8"
     json-buffer "3.0.1"
 
 kind-of@^6.0.2:
@@ -3505,11 +3380,6 @@
   integrity sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==
   dependencies:
     get-func-name "^2.0.0"
-
-lowercase-keys@^1.0.0:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f"
-  integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==
 
 lowercase-keys@^2.0.0:
   version "2.0.0"
@@ -3885,7 +3755,7 @@
   resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
   integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
 
-object-inspect@^1.12.0, object-inspect@^1.9.0:
+object-inspect@^1.12.2, object-inspect@^1.9.0:
   version "1.12.2"
   resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
   integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
@@ -3895,10 +3765,10 @@
   resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
   integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
 
-object.assign@^4.1.2:
-  version "4.1.3"
-  resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.3.tgz#d36b7700ddf0019abb6b1df1bb13f6445f79051f"
-  integrity sha512-ZFJnX3zltyjcYJL0RoCJuzb+11zWGyaDbjgxZbdV7rFEcHQuYxrZqhow67aA7xpes6LhojyFDaBKAFfogQrikA==
+object.assign@^4.1.4:
+  version "4.1.4"
+  resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f"
+  integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==
   dependencies:
     call-bind "^1.0.2"
     define-properties "^1.1.4"
@@ -3943,21 +3813,16 @@
   resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
   integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==
 
-p-cancelable@^0.3.0:
-  version "0.3.0"
-  resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa"
-  integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==
+p-cancelable@^2.0.0:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
+  integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==
 
 p-cancelable@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050"
   integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==
 
-p-finally@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
-  integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==
-
 p-limit@^2.0.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
@@ -3985,13 +3850,6 @@
   integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
   dependencies:
     p-limit "^3.0.2"
-
-p-timeout@^1.1.1:
-  version "1.2.1"
-  resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386"
-  integrity sha512-gb0ryzr+K2qFqFv6qi3khoeqMZF/+ajxQipEF6NteZVnvz9tzdsfAVj3lYtn1gAXvH5lfLwfxEII799gt/mRIA==
-  dependencies:
-    p-finally "^1.0.0"
 
 p-try@^2.0.0:
   version "2.2.0"
@@ -4113,11 +3971,6 @@
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
   integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
-
-prepend-http@^1.0.1:
-  version "1.0.4"
-  resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc"
-  integrity sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==
 
 process@^0.11.10:
   version "0.11.10"
@@ -4299,7 +4152,7 @@
   resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
   integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
 
-resolve-alpn@^1.2.0:
+resolve-alpn@^1.0.0, resolve-alpn@^1.2.0:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9"
   integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==
@@ -4641,15 +4494,15 @@
     has-flag "^4.0.0"
 
 swarm-js@^0.1.40:
-  version "0.1.40"
-  resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.40.tgz#b1bc7b6dcc76061f6c772203e004c11997e06b99"
-  integrity sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==
+  version "0.1.42"
+  resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.42.tgz#497995c62df6696f6e22372f457120e43e727979"
+  integrity sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==
   dependencies:
     bluebird "^3.5.0"
     buffer "^5.0.5"
     eth-lib "^0.1.26"
     fs-extra "^4.0.2"
-    got "^7.1.0"
+    got "^11.8.5"
     mime-types "^2.1.16"
     mkdirp-promise "^5.0.1"
     mock-fs "^4.1.0"
@@ -4675,7 +4528,7 @@
   resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
   integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
 
-timed-out@^4.0.0, timed-out@^4.0.1:
+timed-out@^4.0.1:
   version "4.0.1"
   resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f"
   integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==
@@ -4800,7 +4653,7 @@
   resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0"
   integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==
 
-type@^2.5.0:
+type@^2.7.2:
   version "2.7.2"
   resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0"
   integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==
@@ -4813,14 +4666,14 @@
     is-typedarray "^1.0.0"
 
 typescript@^4.7.2:
-  version "4.7.4"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
-  integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==
+  version "4.8.3"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.3.tgz#d59344522c4bc464a65a730ac695007fdb66dd88"
+  integrity sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==
 
 uglify-js@^3.1.4:
-  version "3.16.3"
-  resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.16.3.tgz#94c7a63337ee31227a18d03b8a3041c210fd1f1d"
-  integrity sha512-uVbFqx9vvLhQg0iBaau9Z75AxWJ8tqM9AV890dIZCLApF4rTcyHwmAvLeEdYRs+BzYWu8Iw81F79ah0EfTXbaw==
+  version "3.17.0"
+  resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.0.tgz#55bd6e9d19ce5eef0d5ad17cd1f587d85b180a85"
+  integrity sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg==
 
 ultron@~1.1.0:
   version "1.1.1"
@@ -4848,9 +4701,9 @@
   integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
 
 update-browserslist-db@^1.0.5:
-  version "1.0.5"
-  resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38"
-  integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==
+  version "1.0.7"
+  resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.7.tgz#16279639cff1d0f800b14792de43d97df2d11b7d"
+  integrity sha512-iN/XYesmZ2RmmWAiI4Z5rq0YqSiv0brj9Ce9CfhNE4xIW2h+MFxcgkxIzZ+ShkFPUkjU3gQ+3oypadD3RAMtrg==
   dependencies:
     escalade "^3.1.1"
     picocolors "^1.0.0"
@@ -4862,23 +4715,11 @@
   dependencies:
     punycode "^2.1.0"
 
-url-parse-lax@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73"
-  integrity sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==
-  dependencies:
-    prepend-http "^1.0.1"
-
 url-set-query@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339"
   integrity sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==
 
-url-to-options@^1.0.1:
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
-  integrity sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==
-
 utf-8-validate@^5.0.2:
   version "5.0.9"
   resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.9.tgz#ba16a822fbeedff1a58918f2a6a6b36387493ea3"
@@ -4927,11 +4768,6 @@
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
   integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
-
-v8-compile-cache@^2.0.3:
-  version "2.3.0"
-  resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
-  integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
 
 varint@^5.0.0:
   version "5.0.2"