瀏覽代碼

review comments applied

Gleb Urvanov 4 年之前
父節點
當前提交
01d6112d8b

+ 1 - 1
tests/network-tests/package.json

@@ -13,7 +13,7 @@
   },
   "dependencies": {
     "@constantinople/types@npm:@joystream/types": "^0.10.0",
-    "@nicaea/types": "./types",
+    "@nicaea/types": "link:../../types",
     "@polkadot/api": "^0.96.1",
     "@polkadot/keyring": "^1.7.0-beta.5",
     "@rome/types@npm:@joystream/types": "^0.7.0",

+ 1 - 1
tests/network-tests/src/constantinople/tests/proposals/impl/storageRoleParametersProposal.ts

@@ -4,7 +4,7 @@ import { ApiWrapper } from '../../../utils/apiWrapper';
 import { v4 as uuid } from 'uuid';
 import BN from 'bn.js';
 import { assert } from 'chai';
-import { RoleParameters } from '@constantinople/types/roles';
+import { RoleParameters } from '@constantinople/types/lib/roles';
 import tap from 'tap';
 
 export function storageRoleParametersProposalTest(

+ 225 - 0
tests/network-tests/src/nicaea/dto/workingGroupOpening.ts

@@ -0,0 +1,225 @@
+import BN from 'bn.js';
+import { KeyringPair } from '@polkadot/keyring/types';
+
+export class WorkingGroupOpening {
+  private activateAtBlock: BN | undefined;
+  private maxActiveApplicants!: BN;
+  private maxReviewPeriodLength!: BN;
+  private applicationStakingPolicyAmount!: BN;
+  private applicationCrowdedOutUnstakingPeriodLength!: BN;
+  private applicationExpiredUnstakingPeriodLength!: BN;
+  private roleStakingPolicyAmount!: BN;
+  private roleCrowdedOutUnstakingPeriodLength!: BN;
+  private roleExpiredUnstakingPeriodLength!: BN;
+  private slashableMaxCount!: BN;
+  private slashableMaxPercentPtsPerTime!: BN;
+  private successfulApplicantApplicationStakeUnstakingPeriod!: BN;
+  private failedApplicantApplicationStakeUnstakingPeriod!: BN;
+  private failedApplicantRoleStakeUnstakingPeriod!: BN;
+  private terminateCuratorApplicationStakeUnstakingPeriod!: BN;
+  private terminateCuratorRoleStakeUnstakingPeriod!: BN;
+  private exitCuratorRoleApplicationStakeUnstakingPeriod!: BN;
+  private exitCuratorRoleStakeUnstakingPeriod!: BN;
+  private text!: string;
+  private openingType!: string;
+
+  public getActivateAtBlock(): BN | undefined {
+    return this.activateAtBlock;
+  }
+
+  public getMaxActiveApplicants(): BN {
+    return this.maxActiveApplicants;
+  }
+
+  public getMaxReviewPeriodLength(): BN {
+    return this.maxReviewPeriodLength;
+  }
+
+  public getApplicationStakingPolicyAmount(): BN {
+    return this.applicationStakingPolicyAmount;
+  }
+
+  public getApplicationCrowdedOutUnstakingPeriodLength(): BN {
+    return this.applicationCrowdedOutUnstakingPeriodLength;
+  }
+
+  public getApplicationExpiredUnstakingPeriodLength(): BN {
+    return this.applicationExpiredUnstakingPeriodLength;
+  }
+
+  public getRoleStakingPolicyAmount(): BN {
+    return this.roleStakingPolicyAmount;
+  }
+
+  public getRoleCrowdedOutUnstakingPeriodLength(): BN {
+    return this.roleCrowdedOutUnstakingPeriodLength;
+  }
+
+  public getRoleExpiredUnstakingPeriodLength(): BN {
+    return this.roleExpiredUnstakingPeriodLength;
+  }
+
+  public getSlashableMaxCount(): BN {
+    return this.slashableMaxCount;
+  }
+
+  public getSlashableMaxPercentPtsPerTime(): BN {
+    return this.slashableMaxPercentPtsPerTime;
+  }
+
+  public getSuccessfulApplicantApplicationStakeUnstakingPeriod(): BN {
+    return this.successfulApplicantApplicationStakeUnstakingPeriod;
+  }
+
+  public getFailedApplicantApplicationStakeUnstakingPeriod(): BN {
+    return this.failedApplicantApplicationStakeUnstakingPeriod;
+  }
+
+  public getFailedApplicantRoleStakeUnstakingPeriod(): BN {
+    return this.failedApplicantRoleStakeUnstakingPeriod;
+  }
+
+  public getTerminateCuratorApplicationStakeUnstakingPeriod(): BN {
+    return this.terminateCuratorApplicationStakeUnstakingPeriod;
+  }
+
+  public getTerminateCuratorRoleStakeUnstakingPeriod(): BN {
+    return this.terminateCuratorRoleStakeUnstakingPeriod;
+  }
+
+  public getExitCuratorRoleApplicationStakeUnstakingPeriod(): BN {
+    return this.exitCuratorRoleApplicationStakeUnstakingPeriod;
+  }
+
+  public getExitCuratorRoleStakeUnstakingPeriod(): BN {
+    return this.exitCuratorRoleStakeUnstakingPeriod;
+  }
+
+  public getText(): string {
+    return this.text;
+  }
+
+  public getOpeningType(): string {
+    return this.openingType;
+  }
+
+  public setActivateAtBlock(value: BN | undefined) {
+    this.activateAtBlock = value;
+  }
+
+  public setMaxActiveApplicants(value: BN) {
+    this.maxActiveApplicants = value;
+  }
+
+  public setMaxReviewPeriodLength(value: BN) {
+    this.maxReviewPeriodLength = value;
+  }
+
+  public setApplicationStakingPolicyAmount(value: BN) {
+    this.applicationStakingPolicyAmount = value;
+  }
+
+  public setApplicationCrowdedOutUnstakingPeriodLength(value: BN) {
+    this.applicationCrowdedOutUnstakingPeriodLength = value;
+  }
+
+  public setApplicationExpiredUnstakingPeriodLength(value: BN) {
+    this.applicationExpiredUnstakingPeriodLength = value;
+  }
+
+  public setRoleStakingPolicyAmount(value: BN) {
+    this.roleStakingPolicyAmount = value;
+  }
+
+  public setRoleCrowdedOutUnstakingPeriodLength(value: BN) {
+    this.roleCrowdedOutUnstakingPeriodLength = value;
+  }
+
+  public setRoleExpiredUnstakingPeriodLength(value: BN) {
+    this.roleExpiredUnstakingPeriodLength = value;
+  }
+
+  public setSlashableMaxCount(value: BN) {
+    this.slashableMaxCount = value;
+  }
+
+  public setSlashableMaxPercentPtsPerTime(value: BN) {
+    this.slashableMaxPercentPtsPerTime = value;
+  }
+
+  public setSuccessfulApplicantApplicationStakeUnstakingPeriod(value: BN) {
+    this.successfulApplicantApplicationStakeUnstakingPeriod = value;
+  }
+
+  public setFailedApplicantApplicationStakeUnstakingPeriod(value: BN) {
+    this.failedApplicantApplicationStakeUnstakingPeriod = value;
+  }
+
+  public setFailedApplicantRoleStakeUnstakingPeriod(value: BN) {
+    this.failedApplicantRoleStakeUnstakingPeriod = value;
+  }
+
+  public setTerminateCuratorApplicationStakeUnstakingPeriod(value: BN) {
+    this.terminateCuratorApplicationStakeUnstakingPeriod = value;
+  }
+
+  public setTerminateCuratorRoleStakeUnstakingPeriod(value: BN) {
+    this.terminateCuratorRoleStakeUnstakingPeriod = value;
+  }
+
+  public setExitCuratorRoleApplicationStakeUnstakingPeriod(value: BN) {
+    this.exitCuratorRoleApplicationStakeUnstakingPeriod = value;
+  }
+
+  public setExitCuratorRoleStakeUnstakingPeriod(value: BN) {
+    this.exitCuratorRoleStakeUnstakingPeriod = value;
+  }
+
+  public setText(value: string) {
+    this.text = value;
+  }
+
+  public setOpeningType(value: string) {
+    this.openingType = value;
+  }
+
+  constructor() {}
+
+  public getActivateAt() {
+    return this.activateAtBlock == undefined ? 'CurrentBlock' : { ExactBlock: this.activateAtBlock };
+  }
+
+  public getCommitment() {
+    return {
+      application_rationing_policy: { max_active_applicants: this.maxActiveApplicants },
+      max_review_period_length: this.maxReviewPeriodLength,
+      application_staking_policy: {
+        amount: this.applicationStakingPolicyAmount,
+        amount_mode: 'AtLeast',
+        crowded_out_unstaking_period_length: this.applicationCrowdedOutUnstakingPeriodLength,
+        review_period_expired_unstaking_period_length: this.applicationExpiredUnstakingPeriodLength,
+      },
+      role_staking_policy: {
+        amount: this.roleStakingPolicyAmount,
+        amount_mode: 'AtLeast',
+        crowded_out_unstaking_period_length: this.roleCrowdedOutUnstakingPeriodLength,
+        review_period_expired_unstaking_period_length: this.roleExpiredUnstakingPeriodLength,
+      },
+      role_slashing_terms: {
+        Slashable: {
+          max_count: this.slashableMaxCount,
+          max_percent_pts_per_time: this.slashableMaxPercentPtsPerTime,
+        },
+      },
+      fill_opening_successful_applicant_application_stake_unstaking_period: this
+        .successfulApplicantApplicationStakeUnstakingPeriod,
+      fill_opening_failed_applicant_application_stake_unstaking_period: this
+        .failedApplicantApplicationStakeUnstakingPeriod,
+      fill_opening_failed_applicant_role_stake_unstaking_period: this.failedApplicantRoleStakeUnstakingPeriod,
+      terminate_curator_application_stake_unstaking_period: this.terminateCuratorApplicationStakeUnstakingPeriod,
+      terminate_curator_role_stake_unstaking_period: this.terminateCuratorRoleStakeUnstakingPeriod,
+      exit_curator_role_application_stake_unstaking_period: this.exitCuratorRoleApplicationStakeUnstakingPeriod,
+      exit_curator_role_stake_unstaking_period: this.exitCuratorRoleStakeUnstakingPeriod,
+    };
+  }
+}

+ 167 - 162
tests/network-tests/src/nicaea/tests/workingGroup/impl/workingGroupModule.ts

@@ -1,6 +1,6 @@
 import BN from 'bn.js';
 import { assert } from 'chai';
-import { ApiWrapper } from '../../../utils/apiWrapper';
+import { ApiWrapper, WorkingGroups } from '../../../utils/apiWrapper';
 import { KeyringPair } from '@polkadot/keyring/types';
 import { Keyring } from '@polkadot/api';
 import { v4 as uuid } from 'uuid';
@@ -8,6 +8,7 @@ import { RewardRelationship } from '@nicaea/types/recurring-rewards';
 import { Worker, ApplicationIdToWorkerIdMap, Application } from '@nicaea/types/working-group';
 import { Utils } from '../../../utils/utils';
 import { Opening as HiringOpening } from '@nicaea/types/hiring';
+import { WorkingGroupOpening } from '../../../dto/workingGroupOpening';
 
 export async function addWorkerOpening(
   apiWrapper: ApiWrapper,
@@ -16,59 +17,42 @@ export async function addWorkerOpening(
   sudo: KeyringPair,
   applicationStake: BN,
   roleStake: BN,
-  activationDelay: BN
+  activationDelay: BN,
+  module: WorkingGroups
 ): Promise<BN> {
+  // Worker opening construction
+  let opening = new WorkingGroupOpening();
+  const activateAtBlock: BN | undefined = activationDelay.eqn(0)
+    ? undefined
+    : (await apiWrapper.getBestBlock()).add(activationDelay);
+  opening.setActivateAtBlock(activateAtBlock);
+  opening.setMaxActiveApplicants(new BN(membersKeyPairs.length));
+  opening.setMaxReviewPeriodLength(new BN(32));
+  opening.setApplicationStakingPolicyAmount(new BN(applicationStake));
+  opening.setApplicationCrowdedOutUnstakingPeriodLength(new BN(0));
+  opening.setApplicationExpiredUnstakingPeriodLength(new BN(0));
+  opening.setRoleStakingPolicyAmount(new BN(roleStake));
+  opening.setRoleCrowdedOutUnstakingPeriodLength(new BN(0));
+  opening.setRoleExpiredUnstakingPeriodLength(new BN(0));
+  opening.setSlashableMaxCount(new BN(1));
+  opening.setSlashableMaxPercentPtsPerTime(new BN(100));
+  opening.setSuccessfulApplicantApplicationStakeUnstakingPeriod(new BN(1));
+  opening.setFailedApplicantApplicationStakeUnstakingPeriod(new BN(1));
+  opening.setFailedApplicantRoleStakeUnstakingPeriod(new BN(1));
+  opening.setTerminateCuratorApplicationStakeUnstakingPeriod(new BN(1));
+  opening.setTerminateCuratorRoleStakeUnstakingPeriod(new BN(1));
+  opening.setExitCuratorRoleApplicationStakeUnstakingPeriod(new BN(1));
+  opening.setExitCuratorRoleStakeUnstakingPeriod(new BN(1));
+  opening.setText(uuid().substring(0, 8));
+  opening.setOpeningType('Worker');
+
   // Fee estimation and transfer
-  const addOpeningFee: BN = apiWrapper.estimateAddOpeningFee();
+  const addOpeningFee: BN = apiWrapper.estimateAddOpeningFee(opening, module);
   await apiWrapper.transferBalance(sudo, lead.address, addOpeningFee);
 
   // Worker opening creation
-  const maxActiveApplicants: BN = new BN(membersKeyPairs.length);
-  const maxReviewPeriodLength: BN = new BN(32);
-  const applicationStakingPolicyAmount: BN = new BN(applicationStake);
-  const applicationCrowdedOutUnstakingPeriodLength: BN = new BN(0);
-  const applicationExpiredUnstakingPeriodLength: BN = new BN(0);
-  const roleStakingPolicyAmount: BN = new BN(roleStake);
-  const roleCrowdedOutUnstakingPeriodLength: BN = new BN(0);
-  const roleExpiredUnstakingPeriodLength: BN = new BN(0);
-  const slashableMaxCount: BN = new BN(1);
-  const slashableMaxPercentPtsPerTime: BN = new BN(100);
-  const successfulApplicantApplicationStakeUnstakingPeriod: BN = new BN(1);
-  const failedApplicantApplicationStakeUnstakingPeriod: BN = new BN(1);
-  const failedApplicantRoleStakeUnstakingPeriod: BN = new BN(1);
-  const terminateCuratorApplicationStakeUnstakingPeriod: BN = new BN(1);
-  const terminateCuratorRoleStakeUnstakingPeriod: BN = new BN(1);
-  const exitCuratorRoleApplicationStakeUnstakingPeriod: BN = new BN(1);
-  const exitCuratorRoleStakeUnstakingPeriod: BN = new BN(1);
-  const text: string = uuid().substring(0, 8);
-  const openingType: string = 'Worker';
-  const activateAtBlock: BN | undefined = activationDelay.eqn(0)
-    ? undefined
-    : (await apiWrapper.getBestBlock()).add(activationDelay);
   const addOpeningPromise: Promise<BN> = apiWrapper.expectOpeningAdded();
-  await apiWrapper.addOpening(
-    activateAtBlock,
-    lead,
-    maxActiveApplicants,
-    maxReviewPeriodLength,
-    applicationStakingPolicyAmount,
-    applicationCrowdedOutUnstakingPeriodLength,
-    applicationExpiredUnstakingPeriodLength,
-    roleStakingPolicyAmount,
-    roleCrowdedOutUnstakingPeriodLength,
-    roleExpiredUnstakingPeriodLength,
-    slashableMaxCount,
-    slashableMaxPercentPtsPerTime,
-    successfulApplicantApplicationStakeUnstakingPeriod,
-    failedApplicantApplicationStakeUnstakingPeriod,
-    failedApplicantRoleStakeUnstakingPeriod,
-    terminateCuratorApplicationStakeUnstakingPeriod,
-    terminateCuratorRoleStakeUnstakingPeriod,
-    exitCuratorRoleApplicationStakeUnstakingPeriod,
-    exitCuratorRoleStakeUnstakingPeriod,
-    text,
-    openingType
-  );
+  await apiWrapper.addOpening(lead, opening, module);
   const openingId: BN = await addOpeningPromise;
 
   return openingId;
@@ -80,67 +64,55 @@ export async function addLeaderOpening(
   sudo: KeyringPair,
   applicationStake: BN,
   roleStake: BN,
-  activationDelay: BN
+  activationDelay: BN,
+  module: WorkingGroups
 ): Promise<BN> {
   // Leader opening creation
-  const maxActiveApplicants: BN = new BN(membersKeyPairs.length);
-  const maxReviewPeriodLength: BN = new BN(32);
-  const applicationStakingPolicyAmount: BN = new BN(applicationStake);
-  const applicationCrowdedOutUnstakingPeriodLength: BN = new BN(0);
-  const applicationExpiredUnstakingPeriodLength: BN = new BN(0);
-  const roleStakingPolicyAmount: BN = new BN(roleStake);
-  const roleCrowdedOutUnstakingPeriodLength: BN = new BN(0);
-  const roleExpiredUnstakingPeriodLength: BN = new BN(0);
-  const slashableMaxCount: BN = new BN(1);
-  const slashableMaxPercentPtsPerTime: BN = new BN(100);
-  const successfulApplicantApplicationStakeUnstakingPeriod: BN = new BN(1);
-  const failedApplicantApplicationStakeUnstakingPeriod: BN = new BN(1);
-  const failedApplicantRoleStakeUnstakingPeriod: BN = new BN(1);
-  const terminateCuratorApplicationStakeUnstakingPeriod: BN = new BN(1);
-  const terminateCuratorRoleStakeUnstakingPeriod: BN = new BN(1);
-  const exitCuratorRoleApplicationStakeUnstakingPeriod: BN = new BN(1);
-  const exitCuratorRoleStakeUnstakingPeriod: BN = new BN(1);
-  const text: string = uuid().substring(0, 8);
-  const openingType: string = 'leader';
   const activateAtBlock: BN | undefined = activationDelay.eqn(0)
     ? undefined
     : (await apiWrapper.getBestBlock()).add(activationDelay);
+  let opening = new WorkingGroupOpening();
+  opening.setActivateAtBlock(activateAtBlock);
+  opening.setMaxActiveApplicants(new BN(membersKeyPairs.length));
+  opening.setMaxReviewPeriodLength(new BN(32));
+  opening.setApplicationStakingPolicyAmount(new BN(applicationStake));
+  opening.setApplicationCrowdedOutUnstakingPeriodLength(new BN(0));
+  opening.setApplicationExpiredUnstakingPeriodLength(new BN(0));
+  opening.setRoleStakingPolicyAmount(new BN(roleStake));
+  opening.setRoleCrowdedOutUnstakingPeriodLength(new BN(0));
+  opening.setRoleExpiredUnstakingPeriodLength(new BN(0));
+  opening.setSlashableMaxCount(new BN(1));
+  opening.setSlashableMaxPercentPtsPerTime(new BN(100));
+  opening.setSuccessfulApplicantApplicationStakeUnstakingPeriod(new BN(1));
+  opening.setFailedApplicantApplicationStakeUnstakingPeriod(new BN(1));
+  opening.setFailedApplicantRoleStakeUnstakingPeriod(new BN(1));
+  opening.setTerminateCuratorApplicationStakeUnstakingPeriod(new BN(1));
+  opening.setTerminateCuratorRoleStakeUnstakingPeriod(new BN(1));
+  opening.setExitCuratorRoleApplicationStakeUnstakingPeriod(new BN(1));
+  opening.setExitCuratorRoleStakeUnstakingPeriod(new BN(1));
+  opening.setText(uuid().substring(0, 8));
+  opening.setOpeningType('leader');
+
   const addOpeningPromise: Promise<BN> = apiWrapper.expectOpeningAdded();
-  await apiWrapper.sudoAddOpening(
-    activateAtBlock,
-    sudo,
-    maxActiveApplicants,
-    maxReviewPeriodLength,
-    applicationStakingPolicyAmount,
-    applicationCrowdedOutUnstakingPeriodLength,
-    applicationExpiredUnstakingPeriodLength,
-    roleStakingPolicyAmount,
-    roleCrowdedOutUnstakingPeriodLength,
-    roleExpiredUnstakingPeriodLength,
-    slashableMaxCount,
-    slashableMaxPercentPtsPerTime,
-    successfulApplicantApplicationStakeUnstakingPeriod,
-    failedApplicantApplicationStakeUnstakingPeriod,
-    failedApplicantRoleStakeUnstakingPeriod,
-    terminateCuratorApplicationStakeUnstakingPeriod,
-    terminateCuratorRoleStakeUnstakingPeriod,
-    exitCuratorRoleApplicationStakeUnstakingPeriod,
-    exitCuratorRoleStakeUnstakingPeriod,
-    text,
-    openingType
-  );
+  await apiWrapper.sudoAddOpening(sudo, opening, module);
   const openingId: BN = await addOpeningPromise;
 
   return openingId;
 }
 
-export async function acceptApplications(apiWrapper: ApiWrapper, lead: KeyringPair, sudo: KeyringPair, openingId: BN) {
+export async function acceptApplications(
+  apiWrapper: ApiWrapper,
+  lead: KeyringPair,
+  sudo: KeyringPair,
+  openingId: BN,
+  module: WorkingGroups
+) {
   // Fee estimation and transfer
-  const acceptApplicationsFee = apiWrapper.estimateAcceptApplicationsFee();
+  const acceptApplicationsFee = apiWrapper.estimateAcceptApplicationsFee(module);
   await apiWrapper.transferBalance(sudo, lead.address, acceptApplicationsFee);
 
   // Begin accepting applications
-  await apiWrapper.acceptApplications(lead, openingId);
+  await apiWrapper.acceptApplications(lead, openingId, module);
 
   const opening: HiringOpening = await apiWrapper.getHiringOpening(openingId);
   assert(opening.is_active, `Opening ${openingId} is not active`);
@@ -153,10 +125,11 @@ export async function applyForOpening(
   applicationStake: BN,
   roleStake: BN,
   openingId: BN,
+  module: WorkingGroups,
   expectFailure: boolean
 ): Promise<void> {
   // Fee estimation and transfer
-  const applyOnOpeningFee: BN = apiWrapper.estimateApplyOnOpeningFee(sudo).add(applicationStake).add(roleStake);
+  const applyOnOpeningFee: BN = apiWrapper.estimateApplyOnOpeningFee(sudo, module).add(applicationStake).add(roleStake);
   await apiWrapper.transferBalanceToAccounts(sudo, membersKeyPairs, applyOnOpeningFee);
 
   // Applying for created worker opening
@@ -166,21 +139,27 @@ export async function applyForOpening(
     roleStake,
     applicationStake,
     uuid().substring(0, 8),
+    module,
     expectFailure
   );
 }
 
-export async function withdrawApplicaiton(apiWrapper: ApiWrapper, membersKeyPairs: KeyringPair[], sudo: KeyringPair) {
+export async function withdrawApplicaiton(
+  apiWrapper: ApiWrapper,
+  membersKeyPairs: KeyringPair[],
+  sudo: KeyringPair,
+  module: WorkingGroups
+) {
   // Fee estimation and transfer
-  const withdrawApplicaitonFee: BN = apiWrapper.estimateWithdrawApplicationFee();
+  const withdrawApplicaitonFee: BN = apiWrapper.estimateWithdrawApplicationFee(module);
   await apiWrapper.transferBalanceToAccounts(sudo, membersKeyPairs, withdrawApplicaitonFee);
 
   // Application withdrawal
-  await apiWrapper.batchWithdrawApplication(membersKeyPairs);
+  await apiWrapper.batchWithdrawApplication(membersKeyPairs, module);
 
   // Assertions
   membersKeyPairs.forEach(async keyPair => {
-    const activeApplications: BN[] = await apiWrapper.getActiveApplicationsIdsByRoleAccount(keyPair.address);
+    const activeApplications: BN[] = await apiWrapper.getActiveApplicationsIdsByRoleAccount(keyPair.address, module);
     assert(activeApplications.length === 0, `Unexpected active application found for ${keyPair.address}`);
   });
 }
@@ -189,21 +168,27 @@ export async function beginApplicationReview(
   apiWrapper: ApiWrapper,
   lead: KeyringPair,
   sudo: KeyringPair,
-  openingId: BN
+  openingId: BN,
+  module: WorkingGroups
 ) {
   // Fee estimation and transfer
-  const beginReviewFee: BN = apiWrapper.estimateBeginApplicantReviewFee();
+  const beginReviewFee: BN = apiWrapper.estimateBeginApplicantReviewFee(module);
   await apiWrapper.transferBalance(sudo, lead.address, beginReviewFee);
 
   // Begin application review
   const beginApplicantReviewPromise: Promise<void> = apiWrapper.expectApplicationReviewBegan();
-  await apiWrapper.beginApplicantReview(lead, openingId);
+  await apiWrapper.beginApplicantReview(lead, openingId, module);
   await beginApplicantReviewPromise;
 }
 
-export async function beginLeaderApplicationReview(apiWrapper: ApiWrapper, sudo: KeyringPair, openingId: BN) {
+export async function beginLeaderApplicationReview(
+  apiWrapper: ApiWrapper,
+  sudo: KeyringPair,
+  openingId: BN,
+  module: WorkingGroups
+) {
   // Begin application review
-  await apiWrapper.sudoBeginApplicantReview(sudo, openingId);
+  await apiWrapper.sudoBeginApplicantReview(sudo, openingId, module);
 }
 
 export async function fillOpening(
@@ -214,14 +199,15 @@ export async function fillOpening(
   openingId: BN,
   firstPayoutInterval: BN,
   payoutInterval: BN,
-  amountPerPayout: BN
+  amountPerPayout: BN,
+  module: WorkingGroups
 ) {
   // Fee estimation and transfer
-  const beginReviewFee: BN = apiWrapper.estimateBeginApplicantReviewFee();
+  const beginReviewFee: BN = apiWrapper.estimateBeginApplicantReviewFee(module);
   await apiWrapper.transferBalance(sudo, lead.address, beginReviewFee);
   const applicationIds: BN[] = (
     await Promise.all(
-      membersKeyPairs.map(async keypair => apiWrapper.getActiveApplicationsIdsByRoleAccount(keypair.address))
+      membersKeyPairs.map(async keypair => apiWrapper.getActiveApplicationsIdsByRoleAccount(keypair.address, module))
     )
   ).flat();
 
@@ -234,12 +220,13 @@ export async function fillOpening(
     applicationIds,
     amountPerPayout,
     now.add(firstPayoutInterval),
-    payoutInterval
+    payoutInterval,
+    module
   );
   const applicationIdToWorkerIdMap: ApplicationIdToWorkerIdMap = await fillOpeningPromise;
   applicationIdToWorkerIdMap.forEach(async (workerId, applicationId) => {
-    const worker: Worker = await apiWrapper.getWorkerById(workerId);
-    const application: Application = await apiWrapper.getApplicationById(applicationId);
+    const worker: Worker = await apiWrapper.getWorkerById(workerId, module);
+    const application: Application = await apiWrapper.getApplicationById(applicationId, module);
     assert(
       worker.role_account_id.toString() === application.role_account_id.toString(),
       `Role account ids does not match, worker account: ${worker.role_account_id}, application account ${application.role_account_id}`
@@ -247,7 +234,7 @@ export async function fillOpening(
   });
 
   // Assertions
-  const openingWorkersAccounts: string[] = (await apiWrapper.getWorkers()).map(worker =>
+  const openingWorkersAccounts: string[] = (await apiWrapper.getWorkers(module)).map(worker =>
     worker.role_account_id.toString()
   );
   membersKeyPairs.forEach(keyPair =>
@@ -262,11 +249,12 @@ export async function fillLeaderOpening(
   openingId: BN,
   firstPayoutInterval: BN,
   payoutInterval: BN,
-  amountPerPayout: BN
+  amountPerPayout: BN,
+  module: WorkingGroups
 ) {
   const applicationIds: BN[] = (
     await Promise.all(
-      membersKeyPairs.map(async keypair => apiWrapper.getActiveApplicationsIdsByRoleAccount(keypair.address))
+      membersKeyPairs.map(async keypair => apiWrapper.getActiveApplicationsIdsByRoleAccount(keypair.address, module))
     )
   ).flat();
 
@@ -279,12 +267,13 @@ export async function fillLeaderOpening(
     applicationIds,
     amountPerPayout,
     now.add(firstPayoutInterval),
-    payoutInterval
+    payoutInterval,
+    module
   );
   const applicationIdToWorkerIdMap: ApplicationIdToWorkerIdMap = await fillOpeningPromise;
   applicationIdToWorkerIdMap.forEach(async (workerId, applicationId) => {
-    const worker: Worker = await apiWrapper.getWorkerById(workerId);
-    const application: Application = await apiWrapper.getApplicationById(applicationId);
+    const worker: Worker = await apiWrapper.getWorkerById(workerId, module);
+    const application: Application = await apiWrapper.getApplicationById(applicationId, module);
     assert(
       worker.role_account_id.toString() === application.role_account_id.toString(),
       `Role account ids does not match, worker account: ${worker.role_account_id}, application account ${application.role_account_id}`
@@ -292,7 +281,7 @@ export async function fillLeaderOpening(
   });
 
   // Assertions
-  const openingWorkersAccounts: string[] = (await apiWrapper.getWorkers()).map(worker =>
+  const openingWorkersAccounts: string[] = (await apiWrapper.getWorkers(module)).map(worker =>
     worker.role_account_id.toString()
   );
   membersKeyPairs.forEach(keyPair =>
@@ -300,17 +289,22 @@ export async function fillLeaderOpening(
   );
 }
 
-export async function increaseStake(apiWrapper: ApiWrapper, membersKeyPairs: KeyringPair[], sudo: KeyringPair) {
+export async function increaseStake(
+  apiWrapper: ApiWrapper,
+  membersKeyPairs: KeyringPair[],
+  sudo: KeyringPair,
+  module: WorkingGroups
+) {
   // Fee estimation and transfer
-  const increaseStakeFee: BN = apiWrapper.estimateIncreaseStakeFee();
+  const increaseStakeFee: BN = apiWrapper.estimateIncreaseStakeFee(module);
   const stakeIncrement: BN = new BN(1);
   await apiWrapper.transferBalance(sudo, membersKeyPairs[0].address, increaseStakeFee.add(stakeIncrement));
-  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address);
+  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address, module);
 
   // Increase worker stake
-  const increasedWorkerStake: BN = (await apiWrapper.getWorkerStakeAmount(workerId)).add(stakeIncrement);
-  await apiWrapper.increaseStake(membersKeyPairs[0], workerId, stakeIncrement);
-  const newWorkerStake: BN = await apiWrapper.getWorkerStakeAmount(workerId);
+  const increasedWorkerStake: BN = (await apiWrapper.getWorkerStakeAmount(workerId, module)).add(stakeIncrement);
+  await apiWrapper.increaseStake(membersKeyPairs[0], workerId, stakeIncrement, module);
+  const newWorkerStake: BN = await apiWrapper.getWorkerStakeAmount(workerId, module);
   assert(
     increasedWorkerStake.eq(newWorkerStake),
     `Unexpected worker stake ${newWorkerStake}, expected ${increasedWorkerStake}`
@@ -321,17 +315,18 @@ export async function updateRewardAccount(
   apiWrapper: ApiWrapper,
   membersKeyPairs: KeyringPair[],
   keyring: Keyring,
-  sudo: KeyringPair
+  sudo: KeyringPair,
+  module: WorkingGroups
 ) {
   // Fee estimation and transfer
-  const updateRewardAccountFee: BN = apiWrapper.estimateUpdateRewardAccountFee(sudo.address);
+  const updateRewardAccountFee: BN = apiWrapper.estimateUpdateRewardAccountFee(sudo.address, module);
   await apiWrapper.transferBalance(sudo, membersKeyPairs[0].address, updateRewardAccountFee);
-  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address);
+  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address, module);
 
   // Update reward account
   const createdAccount: KeyringPair = keyring.addFromUri(uuid().substring(0, 8));
-  await apiWrapper.updateRewardAccount(membersKeyPairs[0], workerId, createdAccount.address);
-  const newRewardAccount: string = await apiWrapper.getWorkerRewardAccount(workerId);
+  await apiWrapper.updateRewardAccount(membersKeyPairs[0], workerId, createdAccount.address, module);
+  const newRewardAccount: string = await apiWrapper.getWorkerRewardAccount(workerId, module);
   assert(
     newRewardAccount === createdAccount.address,
     `Unexpected role account ${newRewardAccount}, expected ${createdAccount.address}`
@@ -342,17 +337,18 @@ export async function updateRoleAccount(
   apiWrapper: ApiWrapper,
   membersKeyPairs: KeyringPair[],
   keyring: Keyring,
-  sudo: KeyringPair
+  sudo: KeyringPair,
+  module: WorkingGroups
 ) {
   // Fee estimation and transfer
-  const updateRoleAccountFee: BN = apiWrapper.estimateUpdateRoleAccountFee(sudo.address);
+  const updateRoleAccountFee: BN = apiWrapper.estimateUpdateRoleAccountFee(sudo.address, module);
   await apiWrapper.transferBalance(sudo, membersKeyPairs[0].address, updateRoleAccountFee);
-  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address);
+  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address, module);
 
   // Update role account
   const createdAccount: KeyringPair = keyring.addFromUri(uuid().substring(0, 8));
-  await apiWrapper.updateRoleAccount(membersKeyPairs[0], workerId, createdAccount.address);
-  const newRoleAccount: string = (await apiWrapper.getWorkerById(workerId)).role_account_id.toString();
+  await apiWrapper.updateRoleAccount(membersKeyPairs[0], workerId, createdAccount.address, module);
+  const newRoleAccount: string = (await apiWrapper.getWorkerById(workerId, module)).role_account_id.toString();
   assert(
     newRoleAccount === createdAccount.address,
     `Unexpected role account ${newRoleAccount}, expected ${createdAccount.address}`
@@ -365,16 +361,17 @@ export async function terminateApplications(
   apiWrapper: ApiWrapper,
   membersKeyPairs: KeyringPair[],
   lead: KeyringPair,
-  sudo: KeyringPair
+  sudo: KeyringPair,
+  module: WorkingGroups
 ) {
   // Fee estimation and transfer
-  const terminateApplicationFee = apiWrapper.estimateTerminateApplicationFee();
+  const terminateApplicationFee = apiWrapper.estimateTerminateApplicationFee(module);
   await apiWrapper.transferBalance(sudo, lead.address, terminateApplicationFee.muln(membersKeyPairs.length));
 
   // Terminate worker applications
-  await apiWrapper.batchTerminateApplication(lead, membersKeyPairs);
+  await apiWrapper.batchTerminateApplication(lead, membersKeyPairs, module);
   membersKeyPairs.forEach(async keyPair => {
-    const activeApplications = await apiWrapper.getActiveApplicationsIdsByRoleAccount(keyPair.address);
+    const activeApplications = await apiWrapper.getActiveApplicationsIdsByRoleAccount(keyPair.address, module);
     assert(activeApplications.length === 0, `Account ${keyPair.address} has unexpected active applications`);
   });
 }
@@ -384,18 +381,19 @@ export async function decreaseStake(
   membersKeyPairs: KeyringPair[],
   lead: KeyringPair,
   sudo: KeyringPair,
+  module: WorkingGroups,
   expectFailure: boolean
 ) {
   // Fee estimation and transfer
-  const decreaseStakeFee = apiWrapper.estimateDecreaseStakeFee();
+  const decreaseStakeFee = apiWrapper.estimateDecreaseStakeFee(module);
   await apiWrapper.transferBalance(sudo, lead.address, decreaseStakeFee);
   const workerStakeDecrement = new BN(1);
-  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address);
+  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address, module);
 
   // Worker stake decrement
-  const decreasedWorkerStake: BN = (await apiWrapper.getWorkerStakeAmount(workerId)).sub(workerStakeDecrement);
-  await apiWrapper.decreaseStake(lead, workerId, workerStakeDecrement, expectFailure);
-  const newWorkerStake: BN = await apiWrapper.getWorkerStakeAmount(workerId);
+  const decreasedWorkerStake: BN = (await apiWrapper.getWorkerStakeAmount(workerId, module)).sub(workerStakeDecrement);
+  await apiWrapper.decreaseStake(lead, workerId, workerStakeDecrement, module, expectFailure);
+  const newWorkerStake: BN = await apiWrapper.getWorkerStakeAmount(workerId, module);
 
   // Assertions
   if (!expectFailure) {
@@ -411,18 +409,19 @@ export async function slash(
   membersKeyPairs: KeyringPair[],
   lead: KeyringPair,
   sudo: KeyringPair,
+  module: WorkingGroups,
   expectFailure: boolean
 ) {
   // Fee estimation and transfer
-  const slashStakeFee = apiWrapper.estimateSlashStakeFee();
+  const slashStakeFee = apiWrapper.estimateSlashStakeFee(module);
   await apiWrapper.transferBalance(sudo, lead.address, slashStakeFee);
   const slashAmount = new BN(1);
-  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address);
+  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address, module);
 
   // Slash worker
-  const slashedStake: BN = (await apiWrapper.getWorkerStakeAmount(workerId)).sub(slashAmount);
-  await apiWrapper.slashStake(lead, workerId, slashAmount, expectFailure);
-  const newStake: BN = await apiWrapper.getWorkerStakeAmount(workerId);
+  const slashedStake: BN = (await apiWrapper.getWorkerStakeAmount(workerId, module)).sub(slashAmount);
+  await apiWrapper.slashStake(lead, workerId, slashAmount, module, expectFailure);
+  const newStake: BN = await apiWrapper.getWorkerStakeAmount(workerId, module);
 
   // Assertions
   assert(slashedStake.eq(newStake), `Unexpected worker stake ${newStake}, expected ${slashedStake}`);
@@ -433,40 +432,46 @@ export async function terminateRole(
   membersKeyPairs: KeyringPair[],
   lead: KeyringPair,
   sudo: KeyringPair,
+  module: WorkingGroups,
   expectFailure: boolean
 ) {
   // Fee estimation and transfer
-  const terminateRoleFee = apiWrapper.estimateTerminateRoleFee();
+  const terminateRoleFee = apiWrapper.estimateTerminateRoleFee(module);
   await apiWrapper.transferBalance(sudo, lead.address, terminateRoleFee);
-  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address);
+  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address, module);
 
   // Slash worker
-  await apiWrapper.terminateRole(lead, workerId, uuid().substring(0, 8), expectFailure);
+  await apiWrapper.terminateRole(lead, workerId, uuid().substring(0, 8), module, expectFailure);
 
   // Assertions
-  apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address);
-  const newWorkerId = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address);
+  apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address, module);
+  const newWorkerId = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address, module);
   assert(newWorkerId === undefined, `Worker with account ${membersKeyPairs[0].address} is not terminated`);
 }
 
-export async function leaveRole(apiWrapper: ApiWrapper, membersKeyPairs: KeyringPair[], sudo: KeyringPair) {
+export async function leaveRole(
+  apiWrapper: ApiWrapper,
+  membersKeyPairs: KeyringPair[],
+  sudo: KeyringPair,
+  module: WorkingGroups
+) {
   // Fee estimation and transfer
-  const leaveRoleFee = apiWrapper.estimateLeaveRoleFee();
+  const leaveRoleFee = apiWrapper.estimateLeaveRoleFee(module);
   await apiWrapper.transferBalanceToAccounts(sudo, membersKeyPairs, leaveRoleFee);
 
-  await apiWrapper.batchLeaveRole(membersKeyPairs, uuid().substring(0, 8), false);
+  await apiWrapper.batchLeaveRole(membersKeyPairs, uuid().substring(0, 8), false, module);
 
   // Assertions
   membersKeyPairs.forEach(async keyPair => {
-    apiWrapper.getWorkerIdByRoleAccount(keyPair.address);
-    const newWorkerId = await apiWrapper.getWorkerIdByRoleAccount(keyPair.address);
+    apiWrapper.getWorkerIdByRoleAccount(keyPair.address, module);
+    const newWorkerId = await apiWrapper.getWorkerIdByRoleAccount(keyPair.address, module);
     assert(newWorkerId === undefined, `Worker with account ${keyPair.address} is not terminated`);
   });
 }
 
-export async function awaitPayout(apiWrapper: ApiWrapper, membersKeyPairs: KeyringPair[]) {
-  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address);
-  const worker: Worker = await apiWrapper.getWorkerById(workerId);
+export async function awaitPayout(apiWrapper: ApiWrapper, membersKeyPairs: KeyringPair[], module: WorkingGroups) {
+  const workerId: BN = await apiWrapper.getWorkerIdByRoleAccount(membersKeyPairs[0].address, module);
+  const worker: Worker = await apiWrapper.getWorkerById(workerId, module);
   const reward: RewardRelationship = await apiWrapper.getRewardRelationship(worker.reward_relationship.unwrap());
   const now: BN = await apiWrapper.getBestBlock();
   const nextPaymentBlock: BN = new BN(reward.getField('next_payment_at_block').toString());
@@ -497,6 +502,6 @@ export async function awaitPayout(apiWrapper: ApiWrapper, membersKeyPairs: Keyri
   );
 }
 
-export async function setMintCapacity(apiWrapper: ApiWrapper, sudo: KeyringPair, capacity: BN) {
-  await apiWrapper.sudoSetWorkingGroupMintCapacity(sudo, capacity);
+export async function setMintCapacity(apiWrapper: ApiWrapper, sudo: KeyringPair, capacity: BN, module: WorkingGroups) {
+  await apiWrapper.sudoSetWorkingGroupMintCapacity(sudo, capacity, module);
 }

+ 87 - 19
tests/network-tests/src/nicaea/tests/workingGroup/manageWorkerAsLeadTest.ts

@@ -2,7 +2,7 @@ import tap = require('tap');
 import { initConfig } from '../../utils/config';
 import { registerJoystreamTypes } from '@nicaea/types';
 import { closeApi } from '../impl/closeApi';
-import { ApiWrapper } from '../../utils/apiWrapper';
+import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper';
 import { WsProvider, Keyring } from '@polkadot/api';
 import { KeyringPair } from '@polkadot/keyring/types';
 import { setTestTimeout } from '../../utils/setTestTimeout';
@@ -60,16 +60,38 @@ tap.mocha.describe('Manage worker as worker scenario', async () => {
         sudo,
         applicationStake,
         roleStake,
-        openingActivationDelay
+        openingActivationDelay,
+        WorkingGroups.storageWorkingGroup
       ))
   );
   tap.test(
     'Apply for lead opening',
-    async () => await applyForOpening(apiWrapper, leadKeyPair, sudo, applicationStake, roleStake, leadOpenignId, false)
+    async () =>
+      await applyForOpening(
+        apiWrapper,
+        leadKeyPair,
+        sudo,
+        applicationStake,
+        roleStake,
+        leadOpenignId,
+        WorkingGroups.storageWorkingGroup,
+        false
+      )
+  );
+  tap.test('Begin lead application review', async () =>
+    beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId, WorkingGroups.storageWorkingGroup)
   );
-  tap.test('Begin lead application review', async () => beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId));
   tap.test('Fill lead opening', async () =>
-    fillLeaderOpening(apiWrapper, leadKeyPair, sudo, leadOpenignId, firstRewardInterval, rewardInterval, payoutAmount)
+    fillLeaderOpening(
+      apiWrapper,
+      leadKeyPair,
+      sudo,
+      leadOpenignId,
+      firstRewardInterval,
+      rewardInterval,
+      payoutAmount,
+      WorkingGroups.storageWorkingGroup
+    )
   );
 
   let openignId: BN;
@@ -83,14 +105,27 @@ tap.mocha.describe('Manage worker as worker scenario', async () => {
         sudo,
         applicationStake,
         roleStake,
-        openingActivationDelay
+        openingActivationDelay,
+        WorkingGroups.storageWorkingGroup
       ))
   );
   tap.test(
     'Apply for worker opening',
-    async () => await applyForOpening(apiWrapper, nKeyPairs, sudo, applicationStake, roleStake, openignId, false)
+    async () =>
+      await applyForOpening(
+        apiWrapper,
+        nKeyPairs,
+        sudo,
+        applicationStake,
+        roleStake,
+        openignId,
+        WorkingGroups.storageWorkingGroup,
+        false
+      )
+  );
+  tap.test('Begin application review', async () =>
+    beginApplicationReview(apiWrapper, leadKeyPair[0], sudo, openignId, WorkingGroups.storageWorkingGroup)
   );
-  tap.test('Begin application review', async () => beginApplicationReview(apiWrapper, leadKeyPair[0], sudo, openignId));
   tap.test('Fill worker opening', async () =>
     fillOpening(
       apiWrapper,
@@ -100,13 +135,16 @@ tap.mocha.describe('Manage worker as worker scenario', async () => {
       openignId,
       firstRewardInterval,
       rewardInterval,
-      payoutAmount
+      payoutAmount,
+      WorkingGroups.storageWorkingGroup
     )
   );
 
-  tap.test('Leaving lead role', async () => leaveRole(apiWrapper, leadKeyPair, sudo));
+  tap.test('Leaving lead role', async () =>
+    leaveRole(apiWrapper, leadKeyPair, sudo, WorkingGroups.storageWorkingGroup)
+  );
   tap.test('Decrease worker stake, expect failure', async () =>
-    decreaseStake(apiWrapper, nKeyPairs, leadKeyPair[0], sudo, true)
+    decreaseStake(apiWrapper, nKeyPairs, leadKeyPair[0], sudo, WorkingGroups.storageWorkingGroup, true)
   );
 
   tap.test(
@@ -118,23 +156,53 @@ tap.mocha.describe('Manage worker as worker scenario', async () => {
         sudo,
         applicationStake,
         roleStake,
-        openingActivationDelay
+        openingActivationDelay,
+        WorkingGroups.storageWorkingGroup
       ))
   );
   tap.test(
     'Apply for lead opening',
-    async () => await applyForOpening(apiWrapper, leadKeyPair, sudo, applicationStake, roleStake, leadOpenignId, false)
+    async () =>
+      await applyForOpening(
+        apiWrapper,
+        leadKeyPair,
+        sudo,
+        applicationStake,
+        roleStake,
+        leadOpenignId,
+        WorkingGroups.storageWorkingGroup,
+        false
+      )
+  );
+  tap.test('Begin lead application review', async () =>
+    beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId, WorkingGroups.storageWorkingGroup)
   );
-  tap.test('Begin lead application review', async () => beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId));
   tap.test('Fill lead opening', async () =>
-    fillLeaderOpening(apiWrapper, leadKeyPair, sudo, leadOpenignId, firstRewardInterval, rewardInterval, payoutAmount)
+    fillLeaderOpening(
+      apiWrapper,
+      leadKeyPair,
+      sudo,
+      leadOpenignId,
+      firstRewardInterval,
+      rewardInterval,
+      payoutAmount,
+      WorkingGroups.storageWorkingGroup
+    )
   );
 
-  tap.test('Decrease worker stake', async () => decreaseStake(apiWrapper, nKeyPairs, leadKeyPair[0], sudo, false));
-  tap.test('Slash worker', async () => slash(apiWrapper, nKeyPairs, leadKeyPair[0], sudo, false));
-  tap.test('Terminate worker role', async () => terminateRole(apiWrapper, nKeyPairs, leadKeyPair[0], sudo, false));
+  tap.test('Decrease worker stake', async () =>
+    decreaseStake(apiWrapper, nKeyPairs, leadKeyPair[0], sudo, WorkingGroups.storageWorkingGroup, false)
+  );
+  tap.test('Slash worker', async () =>
+    slash(apiWrapper, nKeyPairs, leadKeyPair[0], sudo, WorkingGroups.storageWorkingGroup, false)
+  );
+  tap.test('Terminate worker role', async () =>
+    terminateRole(apiWrapper, nKeyPairs, leadKeyPair[0], sudo, WorkingGroups.storageWorkingGroup, false)
+  );
 
-  tap.test('Leaving lead role', async () => leaveRole(apiWrapper, leadKeyPair, sudo));
+  tap.test('Leaving lead role', async () =>
+    leaveRole(apiWrapper, leadKeyPair, sudo, WorkingGroups.storageWorkingGroup)
+  );
 
   closeApi(apiWrapper);
 });

+ 57 - 13
tests/network-tests/src/nicaea/tests/workingGroup/manageWorkerAsWorkerTest.ts

@@ -2,7 +2,7 @@ import tap = require('tap');
 import { initConfig } from '../../utils/config';
 import { registerJoystreamTypes } from '@nicaea/types';
 import { closeApi } from '../impl/closeApi';
-import { ApiWrapper } from '../../utils/apiWrapper';
+import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper';
 import { WsProvider, Keyring } from '@polkadot/api';
 import { KeyringPair } from '@polkadot/keyring/types';
 import { setTestTimeout } from '../../utils/setTestTimeout';
@@ -60,16 +60,38 @@ tap.mocha.describe('Manage worker as worker scenario', async () => {
         sudo,
         applicationStake,
         roleStake,
-        openingActivationDelay
+        openingActivationDelay,
+        WorkingGroups.storageWorkingGroup
       ))
   );
   tap.test(
     'Apply for lead opening',
-    async () => await applyForOpening(apiWrapper, leadKeyPair, sudo, applicationStake, roleStake, leadOpenignId, false)
+    async () =>
+      await applyForOpening(
+        apiWrapper,
+        leadKeyPair,
+        sudo,
+        applicationStake,
+        roleStake,
+        leadOpenignId,
+        WorkingGroups.storageWorkingGroup,
+        false
+      )
+  );
+  tap.test('Begin lead application review', async () =>
+    beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId, WorkingGroups.storageWorkingGroup)
   );
-  tap.test('Begin lead application review', async () => beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId));
   tap.test('Fill lead opening', async () =>
-    fillLeaderOpening(apiWrapper, leadKeyPair, sudo, leadOpenignId, firstRewardInterval, rewardInterval, payoutAmount)
+    fillLeaderOpening(
+      apiWrapper,
+      leadKeyPair,
+      sudo,
+      leadOpenignId,
+      firstRewardInterval,
+      rewardInterval,
+      payoutAmount,
+      WorkingGroups.storageWorkingGroup
+    )
   );
 
   let openignId: BN;
@@ -83,14 +105,27 @@ tap.mocha.describe('Manage worker as worker scenario', async () => {
         sudo,
         applicationStake,
         roleStake,
-        openingActivationDelay
+        openingActivationDelay,
+        WorkingGroups.storageWorkingGroup
       ))
   );
   tap.test(
     'Apply for worker opening',
-    async () => await applyForOpening(apiWrapper, nKeyPairs, sudo, applicationStake, roleStake, openignId, false)
+    async () =>
+      await applyForOpening(
+        apiWrapper,
+        nKeyPairs,
+        sudo,
+        applicationStake,
+        roleStake,
+        openignId,
+        WorkingGroups.storageWorkingGroup,
+        false
+      )
+  );
+  tap.test('Begin application review', async () =>
+    beginApplicationReview(apiWrapper, leadKeyPair[0], sudo, openignId, WorkingGroups.storageWorkingGroup)
   );
-  tap.test('Begin application review', async () => beginApplicationReview(apiWrapper, leadKeyPair[0], sudo, openignId));
   tap.test('Fill worker opening', async () =>
     fillOpening(
       apiWrapper,
@@ -100,15 +135,24 @@ tap.mocha.describe('Manage worker as worker scenario', async () => {
       openignId,
       firstRewardInterval,
       rewardInterval,
-      payoutAmount
+      payoutAmount,
+      WorkingGroups.storageWorkingGroup
     )
   );
 
-  tap.test('Increase worker stake', async () => increaseStake(apiWrapper, nKeyPairs, sudo));
-  tap.test('Update reward account', async () => updateRewardAccount(apiWrapper, nKeyPairs, keyring, sudo));
-  tap.test('Update role account', async () => updateRoleAccount(apiWrapper, nKeyPairs, keyring, sudo));
+  tap.test('Increase worker stake', async () =>
+    increaseStake(apiWrapper, nKeyPairs, sudo, WorkingGroups.storageWorkingGroup)
+  );
+  tap.test('Update reward account', async () =>
+    updateRewardAccount(apiWrapper, nKeyPairs, keyring, sudo, WorkingGroups.storageWorkingGroup)
+  );
+  tap.test('Update role account', async () =>
+    updateRoleAccount(apiWrapper, nKeyPairs, keyring, sudo, WorkingGroups.storageWorkingGroup)
+  );
 
-  tap.test('Leaving lead role', async () => leaveRole(apiWrapper, leadKeyPair, sudo));
+  tap.test('Leaving lead role', async () =>
+    leaveRole(apiWrapper, leadKeyPair, sudo, WorkingGroups.storageWorkingGroup)
+  );
 
   closeApi(apiWrapper);
 });

+ 58 - 12
tests/network-tests/src/nicaea/tests/workingGroup/workerApplicationHappyCaseTest.ts

@@ -2,7 +2,7 @@ import tap from 'tap';
 import { initConfig } from '../../utils/config';
 import { registerJoystreamTypes } from '@nicaea/types';
 import { closeApi } from '../impl/closeApi';
-import { ApiWrapper } from '../../utils/apiWrapper';
+import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper';
 import { WsProvider, Keyring } from '@polkadot/api';
 import { KeyringPair } from '@polkadot/keyring/types';
 import { setTestTimeout } from '../../utils/setTestTimeout';
@@ -58,16 +58,38 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
         sudo,
         applicationStake,
         roleStake,
-        openingActivationDelay
+        openingActivationDelay,
+        WorkingGroups.storageWorkingGroup
       ))
   );
   tap.test(
     'Apply for lead opening',
-    async () => await applyForOpening(apiWrapper, leadKeyPair, sudo, applicationStake, roleStake, leadOpenignId, false)
+    async () =>
+      await applyForOpening(
+        apiWrapper,
+        leadKeyPair,
+        sudo,
+        applicationStake,
+        roleStake,
+        leadOpenignId,
+        WorkingGroups.storageWorkingGroup,
+        false
+      )
+  );
+  tap.test('Begin lead application review', async () =>
+    beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId, WorkingGroups.storageWorkingGroup)
   );
-  tap.test('Begin lead application review', async () => beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId));
   tap.test('Fill lead opening', async () =>
-    fillLeaderOpening(apiWrapper, leadKeyPair, sudo, leadOpenignId, firstRewardInterval, rewardInterval, payoutAmount)
+    fillLeaderOpening(
+      apiWrapper,
+      leadKeyPair,
+      sudo,
+      leadOpenignId,
+      firstRewardInterval,
+      rewardInterval,
+      payoutAmount,
+      WorkingGroups.storageWorkingGroup
+    )
   );
 
   let workerOpenignId: BN;
@@ -81,18 +103,39 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
         sudo,
         applicationStake,
         roleStake,
-        openingActivationDelay
+        openingActivationDelay,
+        WorkingGroups.storageWorkingGroup
       ))
   );
   tap.test('Apply for worker opening', async () =>
-    applyForOpening(apiWrapper, nKeyPairs, sudo, applicationStake, roleStake, workerOpenignId, false)
+    applyForOpening(
+      apiWrapper,
+      nKeyPairs,
+      sudo,
+      applicationStake,
+      roleStake,
+      workerOpenignId,
+      WorkingGroups.storageWorkingGroup,
+      false
+    )
+  );
+  tap.test('Withdraw worker application', async () =>
+    withdrawApplicaiton(apiWrapper, nKeyPairs, sudo, WorkingGroups.storageWorkingGroup)
   );
-  tap.test('Withdraw worker application', async () => withdrawApplicaiton(apiWrapper, nKeyPairs, sudo));
   tap.test('Apply for worker opening', async () =>
-    applyForOpening(apiWrapper, nKeyPairs, sudo, applicationStake, roleStake, workerOpenignId, false)
+    applyForOpening(
+      apiWrapper,
+      nKeyPairs,
+      sudo,
+      applicationStake,
+      roleStake,
+      workerOpenignId,
+      WorkingGroups.storageWorkingGroup,
+      false
+    )
   );
   tap.test('Begin application review', async () =>
-    beginApplicationReview(apiWrapper, leadKeyPair[0], sudo, workerOpenignId)
+    beginApplicationReview(apiWrapper, leadKeyPair[0], sudo, workerOpenignId, WorkingGroups.storageWorkingGroup)
   );
   tap.test('Fill worker opening', async () =>
     fillOpening(
@@ -103,11 +146,14 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
       workerOpenignId,
       firstRewardInterval,
       rewardInterval,
-      payoutAmount
+      payoutAmount,
+      WorkingGroups.storageWorkingGroup
     )
   );
 
-  tap.test('Leaving lead role', async () => leaveRole(apiWrapper, leadKeyPair, sudo));
+  tap.test('Leaving lead role', async () =>
+    leaveRole(apiWrapper, leadKeyPair, sudo, WorkingGroups.storageWorkingGroup)
+  );
 
   closeApi(apiWrapper);
 });

+ 64 - 12
tests/network-tests/src/nicaea/tests/workingGroup/workerApplicationRejectionCaseTest.ts

@@ -2,7 +2,7 @@ import tap from 'tap';
 import { initConfig } from '../../utils/config';
 import { registerJoystreamTypes } from '@nicaea/types';
 import { closeApi } from '../impl/closeApi';
-import { ApiWrapper } from '../../utils/apiWrapper';
+import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper';
 import { WsProvider, Keyring } from '@polkadot/api';
 import { KeyringPair } from '@polkadot/keyring/types';
 import { setTestTimeout } from '../../utils/setTestTimeout';
@@ -59,16 +59,38 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
         sudo,
         applicationStake,
         roleStake,
-        leadOpeningActivationDelay
+        leadOpeningActivationDelay,
+        WorkingGroups.storageWorkingGroup
       ))
   );
   tap.test(
     'Apply for lead opening',
-    async () => await applyForOpening(apiWrapper, leadKeyPair, sudo, applicationStake, roleStake, leadOpenignId, false)
+    async () =>
+      await applyForOpening(
+        apiWrapper,
+        leadKeyPair,
+        sudo,
+        applicationStake,
+        roleStake,
+        leadOpenignId,
+        WorkingGroups.storageWorkingGroup,
+        false
+      )
+  );
+  tap.test('Begin lead application review', async () =>
+    beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId, WorkingGroups.storageWorkingGroup)
   );
-  tap.test('Begin lead application review', async () => beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId));
   tap.test('Fill lead opening', async () =>
-    fillLeaderOpening(apiWrapper, leadKeyPair, sudo, leadOpenignId, firstRewardInterval, rewardInterval, payoutAmount)
+    fillLeaderOpening(
+      apiWrapper,
+      leadKeyPair,
+      sudo,
+      leadOpenignId,
+      firstRewardInterval,
+      rewardInterval,
+      payoutAmount,
+      WorkingGroups.storageWorkingGroup
+    )
   );
 
   let openignId: BN;
@@ -82,26 +104,56 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
         sudo,
         applicationStake,
         roleStake,
-        openingActivationDelay
+        openingActivationDelay,
+        WorkingGroups.storageWorkingGroup
       ))
   );
   tap.test('Apply for worker opening, expect failure', async () =>
-    applyForOpening(apiWrapper, nKeyPairs, sudo, applicationStake, roleStake, openignId, true)
+    applyForOpening(
+      apiWrapper,
+      nKeyPairs,
+      sudo,
+      applicationStake,
+      roleStake,
+      openignId,
+      WorkingGroups.storageWorkingGroup,
+      true
+    )
   );
   tap.test('Begin accepting worker applications', async () =>
-    acceptApplications(apiWrapper, leadKeyPair[0], sudo, openignId)
+    acceptApplications(apiWrapper, leadKeyPair[0], sudo, openignId, WorkingGroups.storageWorkingGroup)
   );
   tap.test('Apply for worker opening as non-member, expect failure', async () =>
-    applyForOpening(apiWrapper, nonMemberKeyPairs, sudo, applicationStake, roleStake, openignId, true)
+    applyForOpening(
+      apiWrapper,
+      nonMemberKeyPairs,
+      sudo,
+      applicationStake,
+      roleStake,
+      openignId,
+      WorkingGroups.storageWorkingGroup,
+      true
+    )
   );
   tap.test('Apply for worker opening as member', async () =>
-    applyForOpening(apiWrapper, nKeyPairs, sudo, applicationStake, roleStake, openignId, false)
+    applyForOpening(
+      apiWrapper,
+      nKeyPairs,
+      sudo,
+      applicationStake,
+      roleStake,
+      openignId,
+      WorkingGroups.storageWorkingGroup,
+      false
+    )
   );
   tap.test('Terminate worker applicaitons', async () =>
-    terminateApplications(apiWrapper, nKeyPairs, leadKeyPair[0], sudo)
+    terminateApplications(apiWrapper, nKeyPairs, leadKeyPair[0], sudo, WorkingGroups.storageWorkingGroup)
   );
 
-  tap.test('Leaving lead role', async () => leaveRole(apiWrapper, leadKeyPair, sudo));
+  tap.test('Leaving lead role', async () =>
+    leaveRole(apiWrapper, leadKeyPair, sudo, WorkingGroups.storageWorkingGroup)
+  );
 
   closeApi(apiWrapper);
 });

+ 49 - 12
tests/network-tests/src/nicaea/tests/workingGroup/workerPayout.ts

@@ -2,7 +2,7 @@ import tap from 'tap';
 import { initConfig } from '../../utils/config';
 import { registerJoystreamTypes } from '@nicaea/types';
 import { closeApi } from '../impl/closeApi';
-import { ApiWrapper } from '../../utils/apiWrapper';
+import { ApiWrapper, WorkingGroups } from '../../utils/apiWrapper';
 import { WsProvider, Keyring } from '@polkadot/api';
 import { KeyringPair } from '@polkadot/keyring/types';
 import { setTestTimeout } from '../../utils/setTestTimeout';
@@ -60,16 +60,38 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
         sudo,
         applicationStake,
         roleStake,
-        openingActivationDelay
+        openingActivationDelay,
+        WorkingGroups.storageWorkingGroup
       ))
   );
   tap.test(
     'Apply for lead opening',
-    async () => await applyForOpening(apiWrapper, leadKeyPair, sudo, applicationStake, roleStake, leadOpenignId, false)
+    async () =>
+      await applyForOpening(
+        apiWrapper,
+        leadKeyPair,
+        sudo,
+        applicationStake,
+        roleStake,
+        leadOpenignId,
+        WorkingGroups.storageWorkingGroup,
+        false
+      )
+  );
+  tap.test('Begin lead application review', async () =>
+    beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId, WorkingGroups.storageWorkingGroup)
   );
-  tap.test('Begin lead application review', async () => beginLeaderApplicationReview(apiWrapper, sudo, leadOpenignId));
   tap.test('Fill lead opening', async () =>
-    fillLeaderOpening(apiWrapper, leadKeyPair, sudo, leadOpenignId, firstRewardInterval, rewardInterval, payoutAmount)
+    fillLeaderOpening(
+      apiWrapper,
+      leadKeyPair,
+      sudo,
+      leadOpenignId,
+      firstRewardInterval,
+      rewardInterval,
+      payoutAmount,
+      WorkingGroups.storageWorkingGroup
+    )
   );
 
   let workerOpenignId: BN;
@@ -83,16 +105,28 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
         sudo,
         applicationStake,
         roleStake,
-        openingActivationDelay
+        openingActivationDelay,
+        WorkingGroups.storageWorkingGroup
       ))
   );
   tap.test('Apply for worker opening', async () =>
-    applyForOpening(apiWrapper, nKeyPairs, sudo, applicationStake, roleStake, workerOpenignId, false)
+    applyForOpening(
+      apiWrapper,
+      nKeyPairs,
+      sudo,
+      applicationStake,
+      roleStake,
+      workerOpenignId,
+      WorkingGroups.storageWorkingGroup,
+      false
+    )
   );
   tap.test('Begin application review', async () =>
-    beginApplicationReview(apiWrapper, leadKeyPair[0], sudo, workerOpenignId)
+    beginApplicationReview(apiWrapper, leadKeyPair[0], sudo, workerOpenignId, WorkingGroups.storageWorkingGroup)
+  );
+  tap.test('Set mint capacity', async () =>
+    setMintCapacity(apiWrapper, sudo, mintCapacity, WorkingGroups.storageWorkingGroup)
   );
-  tap.test('Set mint capacity', async () => setMintCapacity(apiWrapper, sudo, mintCapacity));
   tap.test('Fill worker opening', async () =>
     fillOpening(
       apiWrapper,
@@ -102,13 +136,16 @@ tap.mocha.describe('Worker application happy case scenario', async () => {
       workerOpenignId,
       firstRewardInterval,
       rewardInterval,
-      payoutAmount
+      payoutAmount,
+      WorkingGroups.storageWorkingGroup
     )
   );
 
-  tap.test('Await worker payout', async () => awaitPayout(apiWrapper, nKeyPairs));
+  tap.test('Await worker payout', async () => awaitPayout(apiWrapper, nKeyPairs, WorkingGroups.storageWorkingGroup));
 
-  tap.test('Leaving lead role', async () => leaveRole(apiWrapper, leadKeyPair, sudo));
+  tap.test('Leaving lead role', async () =>
+    leaveRole(apiWrapper, leadKeyPair, sudo, WorkingGroups.storageWorkingGroup)
+  );
 
   closeApi(apiWrapper);
 });

+ 174 - 280
tests/network-tests/src/nicaea/utils/apiWrapper.ts

@@ -17,6 +17,11 @@ import { Utils } from './utils';
 import { Stake, StakedState } from '@nicaea/types/stake';
 import { RewardRelationship } from '@nicaea/types/recurring-rewards';
 import { Opening as HiringOpening, ApplicationId } from '@nicaea/types/hiring';
+import { WorkingGroupOpening } from '../dto/workingGroupOpening';
+
+export enum WorkingGroups {
+  storageWorkingGroup = 'storageWorkingGroup',
+}
 
 export class ApiWrapper {
   private readonly api: ApiPromise;
@@ -221,52 +226,24 @@ export class ApiWrapper {
     return this.estimateTxFee(this.api.tx.proposalsEngine.vote(0, 0, 'Approve'));
   }
 
-  public estimateAddOpeningFee(): BN {
+  public estimateAddOpeningFee(opening: WorkingGroupOpening, module: WorkingGroups): BN {
     return this.estimateTxFee(
-      this.api.tx.storageWorkingGroup.addOpening(
-        'CurrentBlock',
-        {
-          application_rationing_policy: { max_active_applicants: '32' },
-          max_review_period_length: 32,
-          application_staking_policy: {
-            amount: 0,
-            amount_mode: 'AtLeast',
-            crowded_out_unstaking_period_length: 0,
-            review_period_expired_unstaking_period_length: 0,
-          },
-          role_staking_policy: {
-            amount: 0,
-            amount_mode: 'AtLeast',
-            crowded_out_unstaking_period_length: 0,
-            review_period_expired_unstaking_period_length: 0,
-          },
-          role_slashing_terms: {
-            Slashable: {
-              max_count: 0,
-              max_percent_pts_per_time: 0,
-            },
-          },
-          fill_opening_successful_applicant_application_stake_unstaking_period: 0,
-          fill_opening_failed_applicant_application_stake_unstaking_period: 0,
-          fill_opening_failed_applicant_role_stake_unstaking_period: 0,
-          terminate_curator_application_stake_unstaking_period: 0,
-          terminate_curator_role_stake_unstaking_period: 0,
-          exit_curator_role_application_stake_unstaking_period: 0,
-          exit_curator_role_stake_unstaking_period: 0,
-        },
-        'Opening readable text',
-        'Worker'
+      this.api.tx[module].addOpening(
+        opening.getActivateAt(),
+        opening.getCommitment(),
+        opening.getText(),
+        opening.getOpeningType()
       )
     );
   }
 
-  public estimateAcceptApplicationsFee(): BN {
-    return this.estimateTxFee(this.api.tx.storageWorkingGroup.acceptApplications(0));
+  public estimateAcceptApplicationsFee(module: WorkingGroups): BN {
+    return this.estimateTxFee(this.api.tx[module].acceptApplications(0));
   }
 
-  public estimateApplyOnOpeningFee(account: KeyringPair): BN {
+  public estimateApplyOnOpeningFee(account: KeyringPair, module: WorkingGroups): BN {
     return this.estimateTxFee(
-      this.api.tx.storageWorkingGroup.applyOnOpening(
+      this.api.tx[module].applyOnOpening(
         0,
         0,
         account.address,
@@ -277,13 +254,13 @@ export class ApiWrapper {
     );
   }
 
-  public estimateBeginApplicantReviewFee(): BN {
-    return this.estimateTxFee(this.api.tx.storageWorkingGroup.beginApplicantReview(0));
+  public estimateBeginApplicantReviewFee(module: WorkingGroups): BN {
+    return this.estimateTxFee(this.api.tx[module].beginApplicantReview(0));
   }
 
-  public estimateFillOpeningFee(): BN {
+  public estimateFillOpeningFee(module: WorkingGroups): BN {
     return this.estimateTxFee(
-      this.api.tx.storageWorkingGroup.fillOpening(0, [0], {
+      this.api.tx[module].fillOpening(0, [0], {
         amount_per_payout: 0,
         next_payment_at_block: 0,
         payout_interval: 0,
@@ -291,41 +268,41 @@ export class ApiWrapper {
     );
   }
 
-  public estimateIncreaseStakeFee(): BN {
-    return this.estimateTxFee(this.api.tx.storageWorkingGroup.increaseStake(0, 0));
+  public estimateIncreaseStakeFee(module: WorkingGroups): BN {
+    return this.estimateTxFee(this.api.tx[module].increaseStake(0, 0));
   }
 
-  public estimateDecreaseStakeFee(): BN {
-    return this.estimateTxFee(this.api.tx.storageWorkingGroup.decreaseStake(0, 0));
+  public estimateDecreaseStakeFee(module: WorkingGroups): BN {
+    return this.estimateTxFee(this.api.tx[module].decreaseStake(0, 0));
   }
 
-  public estimateUpdateRoleAccountFee(address: string): BN {
-    return this.estimateTxFee(this.api.tx.storageWorkingGroup.updateRoleAccount(0, address));
+  public estimateUpdateRoleAccountFee(address: string, module: WorkingGroups): BN {
+    return this.estimateTxFee(this.api.tx[module].updateRoleAccount(0, address));
   }
 
-  public estimateUpdateRewardAccountFee(address: string): BN {
-    return this.estimateTxFee(this.api.tx.storageWorkingGroup.updateRewardAccount(0, address));
+  public estimateUpdateRewardAccountFee(address: string, module: WorkingGroups): BN {
+    return this.estimateTxFee(this.api.tx[module].updateRewardAccount(0, address));
   }
 
-  public estimateLeaveRoleFee(): BN {
-    return this.estimateTxFee(this.api.tx.storageWorkingGroup.leaveRole(0, 'Long justification text'));
+  public estimateLeaveRoleFee(module: WorkingGroups): BN {
+    return this.estimateTxFee(this.api.tx[module].leaveRole(0, 'Long justification text'));
   }
 
-  public estimateWithdrawApplicationFee(): BN {
-    return this.estimateTxFee(this.api.tx.storageWorkingGroup.withdrawApplication(0));
+  public estimateWithdrawApplicationFee(module: WorkingGroups): BN {
+    return this.estimateTxFee(this.api.tx[module].withdrawApplication(0));
   }
 
-  public estimateTerminateApplicationFee(): BN {
-    return this.estimateTxFee(this.api.tx.storageWorkingGroup.terminateApplication(0));
+  public estimateTerminateApplicationFee(module: WorkingGroups): BN {
+    return this.estimateTxFee(this.api.tx[module].terminateApplication(0));
   }
 
-  public estimateSlashStakeFee(): BN {
-    return this.estimateTxFee(this.api.tx.storageWorkingGroup.slashStake(0, 0));
+  public estimateSlashStakeFee(module: WorkingGroups): BN {
+    return this.estimateTxFee(this.api.tx[module].slashStake(0, 0));
   }
 
-  public estimateTerminateRoleFee(): BN {
+  public estimateTerminateRoleFee(module: WorkingGroups): BN {
     return this.estimateTxFee(
-      this.api.tx.storageWorkingGroup.terminateRole(
+      this.api.tx[module].terminateRole(
         0,
         'Long justification text explaining why the worker role will be terminated',
         false
@@ -417,12 +394,8 @@ export class ApiWrapper {
     );
   }
 
-  public sudoSetWorkingGroupMintCapacity(sudo: KeyringPair, capacity: BN): Promise<void> {
-    return this.sender.signAndSend(
-      this.api.tx.sudo.sudo(this.api.tx.storageWorkingGroup.setMintCapacity(capacity)),
-      sudo,
-      false
-    );
+  public sudoSetWorkingGroupMintCapacity(sudo: KeyringPair, capacity: BN, module: WorkingGroups): Promise<void> {
+    return this.sender.signAndSend(this.api.tx.sudo.sudo(this.api.tx[module].setMintCapacity(capacity)), sudo, false);
   }
 
   public getBestBlock(): Promise<BN> {
@@ -764,153 +737,45 @@ export class ApiWrapper {
     const storageProviders: Vec<AccountId> = await this.api.query.actors.accountIdsByRole<Vec<AccountId>>(
       'StorageProvider'
     );
-    return storageProviders.map(accountId => accountId.toString()).includes(address);
+    const accountWorkers: BN = await this.getWorkerIdByRoleAccount(address, WorkingGroups.storageWorkingGroup);
+    return accountWorkers !== undefined;
   }
 
-  public async sudoSetLead(sudo: KeyringPair, lead: KeyringPair): Promise<void> {
-    const leadMemberId: BN = (await this.getMemberIds(lead.address))[0].toBn();
-    return this.sender.signAndSend(
-      this.api.tx.sudo.sudo(this.api.tx.storageWorkingGroup.setLead(leadMemberId, lead.address)),
-      sudo,
-      false
-    );
-  }
-
-  public async sudoUnsetLead(sudo: KeyringPair): Promise<void> {
-    return this.sender.signAndSend(this.api.tx.sudo.sudo(this.api.tx.storageWorkingGroup.unsetLead()), sudo, false);
+  public async addOpening(leader: KeyringPair, opening: WorkingGroupOpening, module: WorkingGroups): Promise<void> {
+    await this.sender.signAndSend(this.createAddOpeningTransaction(opening, module), leader, false);
   }
 
-  public async addOpening(
-    activateAtBlock: BN | undefined,
-    account: KeyringPair,
-    maxActiveApplicants: BN,
-    maxReviewPeriodLength: BN,
-    applicationStakingPolicyAmount: BN,
-    applicationCrowdedOutUnstakingPeriodLength: BN,
-    applicationExpiredUnstakingPeriodLength: BN,
-    roleStakingPolicyAmount: BN,
-    roleCrowdedOutUnstakingPeriodLength: BN,
-    roleExpiredUnstakingPeriodLength: BN,
-    slashableMaxCount: BN,
-    slashableMaxPercentPtsPerTime: BN,
-    successfulApplicantApplicationStakeUnstakingPeriod: BN,
-    failedApplicantApplicationStakeUnstakingPeriod: BN,
-    failedApplicantRoleStakeUnstakingPeriod: BN,
-    terminateCuratorApplicationStakeUnstakingPeriod: BN,
-    terminateCuratorRoleStakeUnstakingPeriod: BN,
-    exitCuratorRoleApplicationStakeUnstakingPeriod: BN,
-    exitCuratorRoleStakeUnstakingPeriod: BN,
-    text: string,
-    openingType: string
-  ): Promise<void> {
-    const activateAt = activateAtBlock == undefined ? 'CurrentBlock' : { ExactBlock: activateAtBlock };
-    const commitment = {
-      application_rationing_policy: { max_active_applicants: maxActiveApplicants },
-      max_review_period_length: maxReviewPeriodLength,
-      application_staking_policy: {
-        amount: applicationStakingPolicyAmount,
-        amount_mode: 'AtLeast',
-        crowded_out_unstaking_period_length: applicationCrowdedOutUnstakingPeriodLength,
-        review_period_expired_unstaking_period_length: applicationExpiredUnstakingPeriodLength,
-      },
-      role_staking_policy: {
-        amount: roleStakingPolicyAmount,
-        amount_mode: 'AtLeast',
-        crowded_out_unstaking_period_length: roleCrowdedOutUnstakingPeriodLength,
-        review_period_expired_unstaking_period_length: roleExpiredUnstakingPeriodLength,
-      },
-      role_slashing_terms: {
-        Slashable: {
-          max_count: slashableMaxCount,
-          max_percent_pts_per_time: slashableMaxPercentPtsPerTime,
-        },
-      },
-      fill_opening_successful_applicant_application_stake_unstaking_period: successfulApplicantApplicationStakeUnstakingPeriod,
-      fill_opening_failed_applicant_application_stake_unstaking_period: failedApplicantApplicationStakeUnstakingPeriod,
-      fill_opening_failed_applicant_role_stake_unstaking_period: failedApplicantRoleStakeUnstakingPeriod,
-      terminate_curator_application_stake_unstaking_period: terminateCuratorApplicationStakeUnstakingPeriod,
-      terminate_curator_role_stake_unstaking_period: terminateCuratorRoleStakeUnstakingPeriod,
-      exit_curator_role_application_stake_unstaking_period: exitCuratorRoleApplicationStakeUnstakingPeriod,
-      exit_curator_role_stake_unstaking_period: exitCuratorRoleStakeUnstakingPeriod,
-    };
+  public async sudoAddOpening(sudo: KeyringPair, opening: WorkingGroupOpening, module: WorkingGroups): Promise<void> {
     await this.sender.signAndSend(
-      this.api.tx.storageWorkingGroup.addOpening(activateAt, commitment, text, openingType),
-      account,
+      this.api.tx.sudo.sudo(this.createAddOpeningTransaction(opening, module)),
+      sudo,
       false
     );
   }
 
-  public async sudoAddOpening(
-    activateAtBlock: BN | undefined,
-    sudo: KeyringPair,
-    maxActiveApplicants: BN,
-    maxReviewPeriodLength: BN,
-    applicationStakingPolicyAmount: BN,
-    applicationCrowdedOutUnstakingPeriodLength: BN,
-    applicationExpiredUnstakingPeriodLength: BN,
-    roleStakingPolicyAmount: BN,
-    roleCrowdedOutUnstakingPeriodLength: BN,
-    roleExpiredUnstakingPeriodLength: BN,
-    slashableMaxCount: BN,
-    slashableMaxPercentPtsPerTime: BN,
-    successfulApplicantApplicationStakeUnstakingPeriod: BN,
-    failedApplicantApplicationStakeUnstakingPeriod: BN,
-    failedApplicantRoleStakeUnstakingPeriod: BN,
-    terminateCuratorApplicationStakeUnstakingPeriod: BN,
-    terminateCuratorRoleStakeUnstakingPeriod: BN,
-    exitCuratorRoleApplicationStakeUnstakingPeriod: BN,
-    exitCuratorRoleStakeUnstakingPeriod: BN,
-    text: string,
-    openingType: string
-  ): Promise<void> {
-    const activateAt = activateAtBlock == undefined ? 'CurrentBlock' : { ExactBlock: activateAtBlock };
-    const commitment = {
-      application_rationing_policy: { max_active_applicants: maxActiveApplicants },
-      max_review_period_length: maxReviewPeriodLength,
-      application_staking_policy: {
-        amount: applicationStakingPolicyAmount,
-        amount_mode: 'AtLeast',
-        crowded_out_unstaking_period_length: applicationCrowdedOutUnstakingPeriodLength,
-        review_period_expired_unstaking_period_length: applicationExpiredUnstakingPeriodLength,
-      },
-      role_staking_policy: {
-        amount: roleStakingPolicyAmount,
-        amount_mode: 'AtLeast',
-        crowded_out_unstaking_period_length: roleCrowdedOutUnstakingPeriodLength,
-        review_period_expired_unstaking_period_length: roleExpiredUnstakingPeriodLength,
-      },
-      role_slashing_terms: {
-        Slashable: {
-          max_count: slashableMaxCount,
-          max_percent_pts_per_time: slashableMaxPercentPtsPerTime,
-        },
-      },
-      fill_opening_successful_applicant_application_stake_unstaking_period: successfulApplicantApplicationStakeUnstakingPeriod,
-      fill_opening_failed_applicant_application_stake_unstaking_period: failedApplicantApplicationStakeUnstakingPeriod,
-      fill_opening_failed_applicant_role_stake_unstaking_period: failedApplicantRoleStakeUnstakingPeriod,
-      terminate_curator_application_stake_unstaking_period: terminateCuratorApplicationStakeUnstakingPeriod,
-      terminate_curator_role_stake_unstaking_period: terminateCuratorRoleStakeUnstakingPeriod,
-      exit_curator_role_application_stake_unstaking_period: exitCuratorRoleApplicationStakeUnstakingPeriod,
-      exit_curator_role_stake_unstaking_period: exitCuratorRoleStakeUnstakingPeriod,
-    };
-    await this.sender.signAndSend(
-      this.api.tx.sudo.sudo(this.api.tx.storageWorkingGroup.addOpening(activateAt, commitment, text, openingType)),
-      sudo,
-      false
+  private createAddOpeningTransaction(
+    opening: WorkingGroupOpening,
+    module: WorkingGroups
+  ): SubmittableExtrinsic<'promise'> {
+    return this.api.tx[module].addOpening(
+      opening.getActivateAt(),
+      opening.getCommitment(),
+      opening.getText(),
+      opening.getOpeningType()
     );
   }
 
-  public async acceptApplications(account: KeyringPair, openingId: BN): Promise<void> {
-    return this.sender.signAndSend(this.api.tx.storageWorkingGroup.acceptApplications(openingId), account, false);
+  public async acceptApplications(leader: KeyringPair, openingId: BN, module: WorkingGroups): Promise<void> {
+    return this.sender.signAndSend(this.api.tx[module].acceptApplications(openingId), leader, false);
   }
 
-  public async beginApplicantReview(account: KeyringPair, openingId: BN): Promise<void> {
-    return this.sender.signAndSend(this.api.tx.storageWorkingGroup.beginApplicantReview(openingId), account, false);
+  public async beginApplicantReview(leader: KeyringPair, openingId: BN, module: WorkingGroups): Promise<void> {
+    return this.sender.signAndSend(this.api.tx[module].beginApplicantReview(openingId), leader, false);
   }
 
-  public async sudoBeginApplicantReview(sudo: KeyringPair, openingId: BN): Promise<void> {
+  public async sudoBeginApplicantReview(sudo: KeyringPair, openingId: BN, module: WorkingGroups): Promise<void> {
     return this.sender.signAndSend(
-      this.api.tx.sudo.sudo(this.api.tx.storageWorkingGroup.beginApplicantReview(openingId)),
+      this.api.tx.sudo.sudo(this.api.tx[module].beginApplicantReview(openingId)),
       sudo,
       false
     );
@@ -918,22 +783,17 @@ export class ApiWrapper {
 
   public async applyOnOpening(
     account: KeyringPair,
+    roleAccountAddress: string,
     openingId: BN,
     roleStake: BN,
     applicantStake: BN,
     text: string,
-    expectFailure: boolean
+    expectFailure: boolean,
+    module: WorkingGroups
   ): Promise<void> {
     const memberId: BN = (await this.getMemberIds(account.address))[0];
     return this.sender.signAndSend(
-      this.api.tx.storageWorkingGroup.applyOnOpening(
-        memberId,
-        openingId,
-        account.address,
-        roleStake,
-        applicantStake,
-        text
-      ),
+      this.api.tx[module].applyOnOpening(memberId, openingId, roleAccountAddress, roleStake, applicantStake, text),
       account,
       expectFailure
     );
@@ -945,30 +805,41 @@ export class ApiWrapper {
     roleStake: BN,
     applicantStake: BN,
     text: string,
+    module: WorkingGroups,
     expectFailure: boolean
   ): Promise<void[]> {
     return Promise.all(
       accounts.map(async keyPair => {
-        await this.applyOnOpening(keyPair, openingId, roleStake, applicantStake, text, expectFailure);
+        await this.applyOnOpening(
+          keyPair,
+          keyPair.address,
+          openingId,
+          roleStake,
+          applicantStake,
+          text,
+          expectFailure,
+          module
+        );
       })
     );
   }
 
   public async fillOpening(
-    account: KeyringPair,
+    leader: KeyringPair,
     openingId: BN,
     applicationId: BN[],
     amountPerPayout: BN,
     nextPaymentBlock: BN,
-    payoutInterval: BN
+    payoutInterval: BN,
+    module: WorkingGroups
   ): Promise<void> {
     return this.sender.signAndSend(
-      this.api.tx.storageWorkingGroup.fillOpening(openingId, applicationId, {
+      this.api.tx[module].fillOpening(openingId, applicationId, {
         amount_per_payout: amountPerPayout,
         next_payment_at_block: nextPaymentBlock,
         payout_interval: payoutInterval,
       }),
-      account,
+      leader,
       false
     );
   }
@@ -979,11 +850,12 @@ export class ApiWrapper {
     applicationId: BN[],
     amountPerPayout: BN,
     nextPaymentBlock: BN,
-    payoutInterval: BN
+    payoutInterval: BN,
+    module: WorkingGroups
   ): Promise<void> {
     return this.sender.signAndSend(
       this.api.tx.sudo.sudo(
-        this.api.tx.storageWorkingGroup.fillOpening(openingId, applicationId, {
+        this.api.tx[module].fillOpening(openingId, applicationId, {
           amount_per_payout: amountPerPayout,
           next_payment_at_block: nextPaymentBlock,
           payout_interval: payoutInterval,
@@ -994,86 +866,111 @@ export class ApiWrapper {
     );
   }
 
-  public async increaseStake(account: KeyringPair, workerId: BN, stake: BN): Promise<void> {
-    return this.sender.signAndSend(this.api.tx.storageWorkingGroup.increaseStake(workerId, stake), account, false);
+  public async increaseStake(worker: KeyringPair, workerId: BN, stake: BN, module: WorkingGroups): Promise<void> {
+    return this.sender.signAndSend(this.api.tx[module].increaseStake(workerId, stake), worker, false);
   }
 
-  public async decreaseStake(account: KeyringPair, workerId: BN, stake: BN, expectFailure: boolean): Promise<void> {
-    return this.sender.signAndSend(
-      this.api.tx.storageWorkingGroup.decreaseStake(workerId, stake),
-      account,
-      expectFailure
-    );
+  public async decreaseStake(
+    leader: KeyringPair,
+    workerId: BN,
+    stake: BN,
+    module: WorkingGroups,
+    expectFailure: boolean
+  ): Promise<void> {
+    return this.sender.signAndSend(this.api.tx[module].decreaseStake(workerId, stake), leader, expectFailure);
   }
 
-  public async slashStake(account: KeyringPair, workerId: BN, stake: BN, expectFailure: boolean): Promise<void> {
-    return this.sender.signAndSend(this.api.tx.storageWorkingGroup.slashStake(workerId, stake), account, expectFailure);
+  public async slashStake(
+    leader: KeyringPair,
+    workerId: BN,
+    stake: BN,
+    module: WorkingGroups,
+    expectFailure: boolean
+  ): Promise<void> {
+    return this.sender.signAndSend(this.api.tx[module].slashStake(workerId, stake), leader, expectFailure);
   }
 
-  public async updateRoleAccount(account: KeyringPair, workerId: BN, newRoleAccount: string): Promise<void> {
-    return this.sender.signAndSend(
-      this.api.tx.storageWorkingGroup.updateRoleAccount(workerId, newRoleAccount),
-      account,
-      false
-    );
+  public async updateRoleAccount(
+    worker: KeyringPair,
+    workerId: BN,
+    newRoleAccount: string,
+    module: WorkingGroups
+  ): Promise<void> {
+    return this.sender.signAndSend(this.api.tx[module].updateRoleAccount(workerId, newRoleAccount), worker, false);
   }
 
-  public async updateRewardAccount(account: KeyringPair, workerId: BN, newRewardAccount: string): Promise<void> {
-    return this.sender.signAndSend(
-      this.api.tx.storageWorkingGroup.updateRewardAccount(workerId, newRewardAccount),
-      account,
-      false
-    );
+  public async updateRewardAccount(
+    worker: KeyringPair,
+    workerId: BN,
+    newRewardAccount: string,
+    module: WorkingGroups
+  ): Promise<void> {
+    return this.sender.signAndSend(this.api.tx[module].updateRewardAccount(workerId, newRewardAccount), worker, false);
   }
 
-  public async withdrawApplication(account: KeyringPair, workerId: BN): Promise<void> {
-    return this.sender.signAndSend(this.api.tx.storageWorkingGroup.withdrawApplication(workerId), account, false);
+  public async withdrawApplication(account: KeyringPair, workerId: BN, module: WorkingGroups): Promise<void> {
+    return this.sender.signAndSend(this.api.tx[module].withdrawApplication(workerId), account, false);
   }
 
-  public async batchWithdrawApplication(accounts: KeyringPair[]): Promise<void[]> {
+  public async batchWithdrawApplication(accounts: KeyringPair[], module: WorkingGroups): Promise<void[]> {
     return Promise.all(
       accounts.map(async keyPair => {
-        const applicationIds: BN[] = await this.getApplicationsIdsByRoleAccount(keyPair.address);
-        await this.withdrawApplication(keyPair, applicationIds[0]);
+        const applicationIds: BN[] = await this.getApplicationsIdsByRoleAccount(keyPair.address, module);
+        await this.withdrawApplication(keyPair, applicationIds[0], module);
       })
     );
   }
 
-  public async terminateApplication(account: KeyringPair, applicationId: BN): Promise<void> {
-    return this.sender.signAndSend(this.api.tx.storageWorkingGroup.terminateApplication(applicationId), account, false);
+  public async terminateApplication(leader: KeyringPair, applicationId: BN, module: WorkingGroups): Promise<void> {
+    return this.sender.signAndSend(this.api.tx[module].terminateApplication(applicationId), leader, false);
   }
 
-  public async batchTerminateApplication(account: KeyringPair, roleAccounts: KeyringPair[]): Promise<void[]> {
+  public async batchTerminateApplication(
+    leader: KeyringPair,
+    roleAccounts: KeyringPair[],
+    module: WorkingGroups
+  ): Promise<void[]> {
     return Promise.all(
       roleAccounts.map(async keyPair => {
-        const applicationIds: BN[] = await this.getActiveApplicationsIdsByRoleAccount(keyPair.address);
-        await this.terminateApplication(account, applicationIds[0]);
+        const applicationIds: BN[] = await this.getActiveApplicationsIdsByRoleAccount(keyPair.address, module);
+        await this.terminateApplication(leader, applicationIds[0], module);
       })
     );
   }
 
   public async terminateRole(
-    account: KeyringPair,
+    leader: KeyringPair,
     applicationId: BN,
     text: string,
+    module: WorkingGroups,
     expectFailure: boolean
   ): Promise<void> {
     return this.sender.signAndSend(
-      this.api.tx.storageWorkingGroup.terminateRole(applicationId, text, false),
-      account,
+      this.api.tx[module].terminateRole(applicationId, text, false),
+      leader,
       expectFailure
     );
   }
 
-  public async leaveRole(account: KeyringPair, text: string, expectFailure: boolean): Promise<void> {
-    const workerId: BN = await this.getWorkerIdByRoleAccount(account.address);
-    return this.sender.signAndSend(this.api.tx.storageWorkingGroup.leaveRole(workerId, text), account, expectFailure);
+  public async leaveRole(
+    account: KeyringPair,
+    text: string,
+    expectFailure: boolean,
+    module: WorkingGroups
+  ): Promise<void> {
+    const workerId: BN = await this.getWorkerIdByRoleAccount(account.address, module);
+    return this.sender.signAndSend(this.api.tx[module].leaveRole(workerId, text), account, expectFailure);
   }
 
-  public async batchLeaveRole(roleAccounts: KeyringPair[], text: string, expectFailure: boolean): Promise<void[]> {
+  public async batchLeaveRole(
+    roleAccounts: KeyringPair[],
+    text: string,
+    expectFailure: boolean,
+    module: WorkingGroups
+  ): Promise<void[]> {
     return Promise.all(
       roleAccounts.map(async keyPair => {
-        await this.leaveRole(keyPair, text, expectFailure);
+        await this.leaveRole(keyPair, text, expectFailure, module);
       })
     );
   }
@@ -1114,60 +1011,57 @@ export class ApiWrapper {
     return this.api.query.councilElection.minVotingStake<BalanceOf>();
   }
 
-  public async getNextOpeningId(): Promise<BN> {
-    return this.api.query.storageWorkingGroup.nextOpeningId<u32>();
+  public async getNextOpeningId(module: WorkingGroups): Promise<BN> {
+    return this.api.query[module].nextOpeningId<u32>();
   }
 
-  public async getNextApplicationId(): Promise<BN> {
-    return this.api.query.storageWorkingGroup.nextApplicationId<u32>();
+  public async getNextApplicationId(module: WorkingGroups): Promise<BN> {
+    return this.api.query[module].nextApplicationId<u32>();
   }
 
-  public async getOpening(id: BN): Promise<Opening> {
-    return ((await this.api.query.storageWorkingGroup.openingById<Codec[]>(id))[0] as unknown) as Opening;
+  public async getOpening(id: BN, module: WorkingGroups): Promise<Opening> {
+    return ((await this.api.query[module].openingById<Codec[]>(id))[0] as unknown) as Opening;
   }
 
   public async getHiringOpening(id: BN): Promise<HiringOpening> {
     return ((await this.api.query.hiring.openingById<Codec[]>(id))[0] as unknown) as HiringOpening;
   }
 
-  public async getWorkers(): Promise<Worker[]> {
-    return ((await this.api.query.storageWorkingGroup.workerById<Codec[]>())[1] as unknown) as Worker[];
+  public async getWorkers(module: WorkingGroups): Promise<Worker[]> {
+    return ((await this.api.query[module].workerById<Codec[]>())[1] as unknown) as Worker[];
   }
 
-  public async getWorkerById(id: BN): Promise<Worker> {
-    return ((await this.api.query.storageWorkingGroup.workerById<Codec[]>(id))[0] as unknown) as Worker;
+  public async getWorkerById(id: BN, module: WorkingGroups): Promise<Worker> {
+    return ((await this.api.query[module].workerById<Codec[]>(id))[0] as unknown) as Worker;
   }
 
-  public async getWorkerIdByRoleAccount(address: string): Promise<BN> {
-    const workersAndIds = await this.api.query.storageWorkingGroup.workerById<Codec[]>();
+  public async getWorkerIdByRoleAccount(address: string, module: WorkingGroups): Promise<BN> {
+    const workersAndIds = await this.api.query[module].workerById<Codec[]>();
     const workers: Worker[] = (workersAndIds[1] as unknown) as Worker[];
     const ids: WorkerId[] = (workersAndIds[0] as unknown) as WorkerId[];
-    let index: number;
-    workers.forEach((worker, i) => {
-      if (worker.role_account_id.toString() === address) index = i;
-    });
-    return ids[index!];
+    const index: number = workers.findIndex(worker => worker.role_account_id.toString() === address);
+    return ids[index];
   }
 
-  public async getApplicationsIdsByRoleAccount(address: string): Promise<BN[]> {
-    const applicationsAndIds = await this.api.query.storageWorkingGroup.applicationById<Codec[]>();
+  public async getApplicationsIdsByRoleAccount(address: string, module: WorkingGroups): Promise<BN[]> {
+    const applicationsAndIds = await this.api.query[module].applicationById<Codec[]>();
     const applications: Application[] = (applicationsAndIds[1] as unknown) as Application[];
     const ids: ApplicationId[] = (applicationsAndIds[0] as unknown) as ApplicationId[];
     return applications
       .map((application, index) => (application.role_account_id.toString() === address ? ids[index] : undefined))
-      .filter(index => index !== undefined) as BN[];
+      .filter(id => id !== undefined) as BN[];
   }
 
   public async getHiringApplicationById(id: BN): Promise<HiringApplication> {
     return ((await this.api.query.hiring.applicationById<Codec[]>(id))[0] as unknown) as HiringApplication;
   }
 
-  public async getApplicationById(id: BN): Promise<Application> {
-    return ((await this.api.query.storageWorkingGroup.applicationById<Codec[]>(id))[0] as unknown) as Application;
+  public async getApplicationById(id: BN, module: WorkingGroups): Promise<Application> {
+    return ((await this.api.query[module].applicationById<Codec[]>(id))[0] as unknown) as Application;
   }
 
-  public async getActiveApplicationsIdsByRoleAccount(address: string): Promise<BN[]> {
-    const applicationsAndIds = await this.api.query.storageWorkingGroup.applicationById<Codec[]>();
+  public async getActiveApplicationsIdsByRoleAccount(address: string, module: WorkingGroups): Promise<BN[]> {
+    const applicationsAndIds = await this.api.query[module].applicationById<Codec[]>();
     const applications: Application[] = (applicationsAndIds[1] as unknown) as Application[];
     const ids: ApplicationId[] = (applicationsAndIds[0] as unknown) as ApplicationId[];
     return (
@@ -1190,8 +1084,8 @@ export class ApiWrapper {
     return ((await this.api.query.stake.stakes<Codec[]>(id))[0] as unknown) as Stake;
   }
 
-  public async getWorkerStakeAmount(workerId: BN): Promise<BN> {
-    let stakeId: BN = (await this.getWorkerById(workerId)).role_stake_profile.unwrap().stake_id;
+  public async getWorkerStakeAmount(workerId: BN, module: WorkingGroups): Promise<BN> {
+    let stakeId: BN = (await this.getWorkerById(workerId, module)).role_stake_profile.unwrap().stake_id;
     return (((await this.getStake(stakeId)).staking_status.value as unknown) as StakedState).staked_amount;
   }
 
@@ -1201,8 +1095,8 @@ export class ApiWrapper {
     )[0] as unknown) as RewardRelationship;
   }
 
-  public async getWorkerRewardAccount(workerId: BN): Promise<string> {
-    let rewardRelationshipId: BN = (await this.getWorkerById(workerId)).reward_relationship.unwrap();
+  public async getWorkerRewardAccount(workerId: BN, module: WorkingGroups): Promise<string> {
+    let rewardRelationshipId: BN = (await this.getWorkerById(workerId, module)).reward_relationship.unwrap();
     return (await this.getRewardRelationship(rewardRelationshipId)).getField('account').toString();
   }
 }

+ 14 - 7
yarn.lock

@@ -1737,7 +1737,7 @@
     "@types/istanbul-reports" "^1.1.1"
     "@types/yargs" "^13.0.0"
 
-"@joystream/types@./types", "@nicaea/types@./types":
+"@joystream/types@./types":
   version "0.11.0"
   dependencies:
     "@polkadot/keyring" "^1.7.0-beta.5"
@@ -1746,6 +1746,7 @@
     "@types/vfile" "^4.0.0"
     ajv "^6.11.0"
     lodash "^4.17.15"
+    moment "^2.24.0"
 
 "@ledgerhq/devices@^4.78.0":
   version "4.78.0"
@@ -2492,6 +2493,17 @@
     call-me-maybe "^1.0.1"
     glob-to-regexp "^0.3.0"
 
+"@nicaea/types@link:types":
+  version "0.11.0"
+  dependencies:
+    "@polkadot/keyring" "^1.7.0-beta.5"
+    "@polkadot/types" "^0.96.1"
+    "@types/lodash" "^4.14.157"
+    "@types/vfile" "^4.0.0"
+    ajv "^6.11.0"
+    lodash "^4.17.15"
+    moment "^2.24.0"
+
 "@nodelib/fs.scandir@2.1.3":
   version "2.1.3"
   resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b"
@@ -22388,16 +22400,11 @@ typescript-formatter@^7.2.2:
     commandpost "^1.0.0"
     editorconfig "^0.15.0"
 
-typescript@3.7.2, typescript@3.7.x, typescript@^3.0.3, typescript@^3.6.4, typescript@^3.7.2:
+typescript@3.7.2, typescript@3.7.x, typescript@^3.0.3, typescript@^3.6.4, typescript@^3.7.2, typescript@^3.8.3:
   version "3.7.2"
   resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.2.tgz#27e489b95fa5909445e9fef5ee48d81697ad18fb"
   integrity sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==
 
-typescript@^3.8.3:
-  version "3.9.5"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36"
-  integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==
-
 u2f-api@0.2.7:
   version "0.2.7"
   resolved "https://registry.yarnpkg.com/u2f-api/-/u2f-api-0.2.7.tgz#17bf196b242f6bf72353d9858e6a7566cc192720"