Browse Source

Merge branch 'working-groups-schemas' into cli-query-node

Leszek Wiesner 3 years ago
parent
commit
af4158bd6c
100 changed files with 24828 additions and 919 deletions
  1. 2 2
      docker-compose.yml
  2. 10 9
      metadata-protobuf/compile.sh
  3. 1119 0
      metadata-protobuf/compiled/index.d.ts
  4. 2666 0
      metadata-protobuf/compiled/index.js
  5. 127 42
      metadata-protobuf/doc/index.md
  6. 6 4
      metadata-protobuf/package.json
  7. 4 4
      metadata-protobuf/proto/Council.proto
  8. 3 3
      metadata-protobuf/proto/Membership.proto
  9. 44 15
      metadata-protobuf/proto/WorkingGroups.proto
  10. 1 3
      metadata-protobuf/src/index.ts
  11. 2 1
      package.json
  12. 1 3
      query-node/build.sh
  13. 2 2
      query-node/codegen/package.json
  14. 344 247
      query-node/codegen/yarn.lock
  15. 225 19
      query-node/manifest.yml
  16. 49 11
      query-node/mappings/common.ts
  17. 2 1
      query-node/mappings/index.ts
  18. 8 14
      query-node/mappings/init.ts
  19. 45 0
      query-node/mappings/initializeDb.ts
  20. 0 216
      query-node/mappings/mappings.ts
  21. 419 0
      query-node/mappings/membership.ts
  22. 3 3
      query-node/mappings/package.json
  23. 965 0
      query-node/mappings/workingGroups.ts
  24. 3 3
      query-node/package.json
  25. 6 1
      query-node/run-tests.sh
  26. 24 0
      query-node/schemas/common.graphql
  27. 37 32
      query-node/schemas/membership.graphql
  28. 398 0
      query-node/schemas/membershipEvents.graphql
  29. 91 0
      query-node/schemas/storage.graphql
  30. 316 0
      query-node/schemas/workingGroups.graphql
  31. 695 0
      query-node/schemas/workingGroupsEvents.graphql
  32. 6 0
      query-node/start.sh
  33. 11 0
      tests/integration-tests/.env
  34. 21 1
      tests/integration-tests/codegen.yml
  35. 6 3
      tests/integration-tests/package.json
  36. 1 1
      tests/integration-tests/run-test-scenario.sh
  37. 207 13
      tests/integration-tests/src/Api.ts
  38. 88 2
      tests/integration-tests/src/Fixture.ts
  39. 634 43
      tests/integration-tests/src/QueryNodeApi.ts
  40. 21 0
      tests/integration-tests/src/consts.ts
  41. 103 0
      tests/integration-tests/src/fixtures/membership/AddStakingAccountsHappyCaseFixture.ts
  42. 106 0
      tests/integration-tests/src/fixtures/membership/BuyMembershipHappyCaseFixture.ts
  43. 51 0
      tests/integration-tests/src/fixtures/membership/BuyMembershipWithInsufficienFundsFixture.ts
  44. 133 0
      tests/integration-tests/src/fixtures/membership/InviteMembersHappyCaseFixture.ts
  45. 70 0
      tests/integration-tests/src/fixtures/membership/RemoveStakingAccountsHappyCaseFixture.ts
  46. 162 0
      tests/integration-tests/src/fixtures/membership/SudoUpdateMembershipSystem.ts
  47. 93 0
      tests/integration-tests/src/fixtures/membership/TransferInvitesHappyCaseFixture.ts
  48. 79 0
      tests/integration-tests/src/fixtures/membership/UpdateAccountsHappyCaseFixture.ts
  49. 87 0
      tests/integration-tests/src/fixtures/membership/UpdateProfileHappyCaseFixture.ts
  50. 9 0
      tests/integration-tests/src/fixtures/membership/index.ts
  51. 19 0
      tests/integration-tests/src/fixtures/membership/utils.ts
  52. 168 0
      tests/integration-tests/src/fixtures/workingGroups/ApplyOnOpeningsHappyCaseFixture.ts
  53. 40 0
      tests/integration-tests/src/fixtures/workingGroups/BaseCreateOpeningFixture.ts
  54. 13 0
      tests/integration-tests/src/fixtures/workingGroups/BaseWorkingGroupFixture.ts
  55. 79 0
      tests/integration-tests/src/fixtures/workingGroups/CancelOpeningsFixture.ts
  56. 154 0
      tests/integration-tests/src/fixtures/workingGroups/CreateOpeningsFixture.ts
  57. 150 0
      tests/integration-tests/src/fixtures/workingGroups/CreateUpcomingOpeningsFixture.ts
  58. 90 0
      tests/integration-tests/src/fixtures/workingGroups/DecreaseWorkerStakesFixture.ts
  59. 241 0
      tests/integration-tests/src/fixtures/workingGroups/FillOpeningsFixture.ts
  60. 96 0
      tests/integration-tests/src/fixtures/workingGroups/HireWorkersFixture.ts
  61. 79 0
      tests/integration-tests/src/fixtures/workingGroups/IncreaseWorkerStakesFixture.ts
  62. 79 0
      tests/integration-tests/src/fixtures/workingGroups/LeaveRoleFixture.ts
  63. 65 0
      tests/integration-tests/src/fixtures/workingGroups/RemoveUpcomingOpeningsFixture.ts
  64. 56 0
      tests/integration-tests/src/fixtures/workingGroups/SetBudgetFixture.ts
  65. 105 0
      tests/integration-tests/src/fixtures/workingGroups/SlashWorkerStakesFixture.ts
  66. 71 0
      tests/integration-tests/src/fixtures/workingGroups/SpendBudgetFixture.ts
  67. 145 0
      tests/integration-tests/src/fixtures/workingGroups/TerminateWorkersFixture.ts
  68. 128 0
      tests/integration-tests/src/fixtures/workingGroups/UpdateGroupStatusFixture.ts
  69. 76 0
      tests/integration-tests/src/fixtures/workingGroups/UpdateWorkerRewardAccountsFixture.ts
  70. 78 0
      tests/integration-tests/src/fixtures/workingGroups/UpdateWorkerRewardAmountsFixture.ts
  71. 78 0
      tests/integration-tests/src/fixtures/workingGroups/UpdateWorkerRoleAccountsFixture.ts
  72. 78 0
      tests/integration-tests/src/fixtures/workingGroups/WithdrawApplicationsFixture.ts
  73. 16 0
      tests/integration-tests/src/fixtures/workingGroups/index.ts
  74. 12 0
      tests/integration-tests/src/fixtures/workingGroups/utils.ts
  75. 5 8
      tests/integration-tests/src/flows/membership/creatingMemberships.ts
  76. 5 5
      tests/integration-tests/src/flows/membership/invitingMembers.ts
  77. 6 6
      tests/integration-tests/src/flows/membership/managingStakingAccounts.ts
  78. 42 0
      tests/integration-tests/src/flows/membership/membershipSystem.ts
  79. 4 4
      tests/integration-tests/src/flows/membership/transferringInvites.ts
  80. 15 8
      tests/integration-tests/src/flows/membership/updatingAccounts.ts
  81. 4 4
      tests/integration-tests/src/flows/membership/updatingProfile.ts
  82. 29 0
      tests/integration-tests/src/flows/working-groups/groupBudget.ts
  83. 64 0
      tests/integration-tests/src/flows/working-groups/groupStatus.ts
  84. 69 0
      tests/integration-tests/src/flows/working-groups/leadOpening.ts
  85. 150 0
      tests/integration-tests/src/flows/working-groups/openingsAndApplications.ts
  86. 94 0
      tests/integration-tests/src/flows/working-groups/upcomingOpenings.ts
  87. 127 0
      tests/integration-tests/src/flows/working-groups/workerActions.ts
  88. 1995 0
      tests/integration-tests/src/graphql/generated/queries.ts
  89. 9255 0
      tests/integration-tests/src/graphql/generated/schema.ts
  90. 69 0
      tests/integration-tests/src/graphql/queries/membership.graphql
  91. 240 0
      tests/integration-tests/src/graphql/queries/membershipEvents.graphql
  92. 248 0
      tests/integration-tests/src/graphql/queries/workingGroups.graphql
  93. 447 0
      tests/integration-tests/src/graphql/queries/workingGroupsEvents.graphql
  94. 2 0
      tests/integration-tests/src/scenarios/full.ts
  95. 19 0
      tests/integration-tests/src/scenarios/memberships.ts
  96. 16 0
      tests/integration-tests/src/scenarios/workingGroups.ts
  97. 90 0
      tests/integration-tests/src/types.ts
  98. 26 0
      tests/integration-tests/src/utils.ts
  99. 29 29
      types/augment-codec/augment-api-query.ts
  100. 157 157
      types/augment-codec/augment-api-tx.ts

+ 2 - 2
docker-compose.yml

@@ -124,7 +124,7 @@ services:
     command: ["yarn", "workspace", "query-node-root", "processor:start"]
 
   indexer:
-    image: joystream/hydra-indexer:latest
+    image: joystream/hydra-indexer:3.0.0-beta.6
     restart: unless-stopped
     env_file:
       # relative to working directory where docker-compose was run from
@@ -146,7 +146,7 @@ services:
       sh -c "yarn db:bootstrap && yarn start:prod"
 
   indexer-api-gateway:
-    image: joystream/hydra-indexer-gateway:latest
+    image: joystream/hydra-indexer-gateway:3.0.0-beta.6
     restart: unless-stopped
     env_file:
       # relative to working directory where docker-compose was run from

+ 10 - 9
metadata-protobuf/compile.sh

@@ -1,15 +1,16 @@
 #!/usr/bin/env bash
 
-# Path to this plugin
-PROTOC_GEN_TS_PATH="./node_modules/.bin/protoc-gen-ts"
-
 # Directory to write generated code to (.js and .d.ts files)
 OUT_DIR="./compiled"
 mkdir -p ${OUT_DIR}
 
-# Compile proto files
-protoc \
-    --plugin="protoc-gen-ts=${PROTOC_GEN_TS_PATH}" \
-    --js_out="import_style=commonjs,binary:${OUT_DIR}" \
-    --ts_out="${OUT_DIR}" \
-    proto/*.proto
+yarn pbjs \
+  -t="static-module" \
+  -w="commonjs" \
+  -o="${OUT_DIR}/index.js" \
+  --force-long \
+  proto/*.proto
+
+yarn pbts \
+  -o="${OUT_DIR}/index.d.ts" \
+  ${OUT_DIR}/*.js

+ 1119 - 0
metadata-protobuf/compiled/index.d.ts

@@ -0,0 +1,1119 @@
+import * as $protobuf from "protobufjs";
+/** Properties of a CouncilCandidacyNoteMetadata. */
+export interface ICouncilCandidacyNoteMetadata {
+
+    /** CouncilCandidacyNoteMetadata header */
+    header?: (string|null);
+
+    /** CouncilCandidacyNoteMetadata bulletPoints */
+    bulletPoints?: (string[]|null);
+
+    /** CouncilCandidacyNoteMetadata bannerImageUri */
+    bannerImageUri?: (string|null);
+
+    /** CouncilCandidacyNoteMetadata description */
+    description?: (string|null);
+}
+
+/** Represents a CouncilCandidacyNoteMetadata. */
+export class CouncilCandidacyNoteMetadata implements ICouncilCandidacyNoteMetadata {
+
+    /**
+     * Constructs a new CouncilCandidacyNoteMetadata.
+     * @param [properties] Properties to set
+     */
+    constructor(properties?: ICouncilCandidacyNoteMetadata);
+
+    /** CouncilCandidacyNoteMetadata header. */
+    public header: string;
+
+    /** CouncilCandidacyNoteMetadata bulletPoints. */
+    public bulletPoints: string[];
+
+    /** CouncilCandidacyNoteMetadata bannerImageUri. */
+    public bannerImageUri: string;
+
+    /** CouncilCandidacyNoteMetadata description. */
+    public description: string;
+
+    /**
+     * Creates a new CouncilCandidacyNoteMetadata instance using the specified properties.
+     * @param [properties] Properties to set
+     * @returns CouncilCandidacyNoteMetadata instance
+     */
+    public static create(properties?: ICouncilCandidacyNoteMetadata): CouncilCandidacyNoteMetadata;
+
+    /**
+     * Encodes the specified CouncilCandidacyNoteMetadata message. Does not implicitly {@link CouncilCandidacyNoteMetadata.verify|verify} messages.
+     * @param message CouncilCandidacyNoteMetadata message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encode(message: ICouncilCandidacyNoteMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Encodes the specified CouncilCandidacyNoteMetadata message, length delimited. Does not implicitly {@link CouncilCandidacyNoteMetadata.verify|verify} messages.
+     * @param message CouncilCandidacyNoteMetadata message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encodeDelimited(message: ICouncilCandidacyNoteMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Decodes a CouncilCandidacyNoteMetadata message from the specified reader or buffer.
+     * @param reader Reader or buffer to decode from
+     * @param [length] Message length if known beforehand
+     * @returns CouncilCandidacyNoteMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): CouncilCandidacyNoteMetadata;
+
+    /**
+     * Decodes a CouncilCandidacyNoteMetadata message from the specified reader or buffer, length delimited.
+     * @param reader Reader or buffer to decode from
+     * @returns CouncilCandidacyNoteMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): CouncilCandidacyNoteMetadata;
+
+    /**
+     * Verifies a CouncilCandidacyNoteMetadata message.
+     * @param message Plain object to verify
+     * @returns `null` if valid, otherwise the reason why it is not
+     */
+    public static verify(message: { [k: string]: any }): (string|null);
+
+    /**
+     * Creates a CouncilCandidacyNoteMetadata message from a plain object. Also converts values to their respective internal types.
+     * @param object Plain object
+     * @returns CouncilCandidacyNoteMetadata
+     */
+    public static fromObject(object: { [k: string]: any }): CouncilCandidacyNoteMetadata;
+
+    /**
+     * Creates a plain object from a CouncilCandidacyNoteMetadata message. Also converts values to other types if specified.
+     * @param message CouncilCandidacyNoteMetadata
+     * @param [options] Conversion options
+     * @returns Plain object
+     */
+    public static toObject(message: CouncilCandidacyNoteMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
+
+    /**
+     * Converts this CouncilCandidacyNoteMetadata to JSON.
+     * @returns JSON object
+     */
+    public toJSON(): { [k: string]: any };
+}
+
+/** Properties of a MembershipMetadata. */
+export interface IMembershipMetadata {
+
+    /** MembershipMetadata name */
+    name?: (string|null);
+
+    /** MembershipMetadata avatar */
+    avatar?: (number|null);
+
+    /** MembershipMetadata about */
+    about?: (string|null);
+}
+
+/** Represents a MembershipMetadata. */
+export class MembershipMetadata implements IMembershipMetadata {
+
+    /**
+     * Constructs a new MembershipMetadata.
+     * @param [properties] Properties to set
+     */
+    constructor(properties?: IMembershipMetadata);
+
+    /** MembershipMetadata name. */
+    public name: string;
+
+    /** MembershipMetadata avatar. */
+    public avatar: number;
+
+    /** MembershipMetadata about. */
+    public about: string;
+
+    /**
+     * Creates a new MembershipMetadata instance using the specified properties.
+     * @param [properties] Properties to set
+     * @returns MembershipMetadata instance
+     */
+    public static create(properties?: IMembershipMetadata): MembershipMetadata;
+
+    /**
+     * Encodes the specified MembershipMetadata message. Does not implicitly {@link MembershipMetadata.verify|verify} messages.
+     * @param message MembershipMetadata message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encode(message: IMembershipMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Encodes the specified MembershipMetadata message, length delimited. Does not implicitly {@link MembershipMetadata.verify|verify} messages.
+     * @param message MembershipMetadata message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encodeDelimited(message: IMembershipMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Decodes a MembershipMetadata message from the specified reader or buffer.
+     * @param reader Reader or buffer to decode from
+     * @param [length] Message length if known beforehand
+     * @returns MembershipMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): MembershipMetadata;
+
+    /**
+     * Decodes a MembershipMetadata message from the specified reader or buffer, length delimited.
+     * @param reader Reader or buffer to decode from
+     * @returns MembershipMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): MembershipMetadata;
+
+    /**
+     * Verifies a MembershipMetadata message.
+     * @param message Plain object to verify
+     * @returns `null` if valid, otherwise the reason why it is not
+     */
+    public static verify(message: { [k: string]: any }): (string|null);
+
+    /**
+     * Creates a MembershipMetadata message from a plain object. Also converts values to their respective internal types.
+     * @param object Plain object
+     * @returns MembershipMetadata
+     */
+    public static fromObject(object: { [k: string]: any }): MembershipMetadata;
+
+    /**
+     * Creates a plain object from a MembershipMetadata message. Also converts values to other types if specified.
+     * @param message MembershipMetadata
+     * @param [options] Conversion options
+     * @returns Plain object
+     */
+    public static toObject(message: MembershipMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
+
+    /**
+     * Converts this MembershipMetadata to JSON.
+     * @returns JSON object
+     */
+    public toJSON(): { [k: string]: any };
+}
+
+/** Properties of an OpeningMetadata. */
+export interface IOpeningMetadata {
+
+    /** OpeningMetadata shortDescription */
+    shortDescription?: (string|null);
+
+    /** OpeningMetadata description */
+    description?: (string|null);
+
+    /** OpeningMetadata hiringLimit */
+    hiringLimit?: (number|null);
+
+    /** OpeningMetadata expectedEndingTimestamp */
+    expectedEndingTimestamp?: (number|null);
+
+    /** OpeningMetadata applicationDetails */
+    applicationDetails?: (string|null);
+
+    /** OpeningMetadata applicationFormQuestions */
+    applicationFormQuestions?: (OpeningMetadata.IApplicationFormQuestion[]|null);
+}
+
+/** Represents an OpeningMetadata. */
+export class OpeningMetadata implements IOpeningMetadata {
+
+    /**
+     * Constructs a new OpeningMetadata.
+     * @param [properties] Properties to set
+     */
+    constructor(properties?: IOpeningMetadata);
+
+    /** OpeningMetadata shortDescription. */
+    public shortDescription: string;
+
+    /** OpeningMetadata description. */
+    public description: string;
+
+    /** OpeningMetadata hiringLimit. */
+    public hiringLimit: number;
+
+    /** OpeningMetadata expectedEndingTimestamp. */
+    public expectedEndingTimestamp: number;
+
+    /** OpeningMetadata applicationDetails. */
+    public applicationDetails: string;
+
+    /** OpeningMetadata applicationFormQuestions. */
+    public applicationFormQuestions: OpeningMetadata.IApplicationFormQuestion[];
+
+    /**
+     * Creates a new OpeningMetadata instance using the specified properties.
+     * @param [properties] Properties to set
+     * @returns OpeningMetadata instance
+     */
+    public static create(properties?: IOpeningMetadata): OpeningMetadata;
+
+    /**
+     * Encodes the specified OpeningMetadata message. Does not implicitly {@link OpeningMetadata.verify|verify} messages.
+     * @param message OpeningMetadata message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encode(message: IOpeningMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Encodes the specified OpeningMetadata message, length delimited. Does not implicitly {@link OpeningMetadata.verify|verify} messages.
+     * @param message OpeningMetadata message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encodeDelimited(message: IOpeningMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Decodes an OpeningMetadata message from the specified reader or buffer.
+     * @param reader Reader or buffer to decode from
+     * @param [length] Message length if known beforehand
+     * @returns OpeningMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): OpeningMetadata;
+
+    /**
+     * Decodes an OpeningMetadata message from the specified reader or buffer, length delimited.
+     * @param reader Reader or buffer to decode from
+     * @returns OpeningMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): OpeningMetadata;
+
+    /**
+     * Verifies an OpeningMetadata message.
+     * @param message Plain object to verify
+     * @returns `null` if valid, otherwise the reason why it is not
+     */
+    public static verify(message: { [k: string]: any }): (string|null);
+
+    /**
+     * Creates an OpeningMetadata message from a plain object. Also converts values to their respective internal types.
+     * @param object Plain object
+     * @returns OpeningMetadata
+     */
+    public static fromObject(object: { [k: string]: any }): OpeningMetadata;
+
+    /**
+     * Creates a plain object from an OpeningMetadata message. Also converts values to other types if specified.
+     * @param message OpeningMetadata
+     * @param [options] Conversion options
+     * @returns Plain object
+     */
+    public static toObject(message: OpeningMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
+
+    /**
+     * Converts this OpeningMetadata to JSON.
+     * @returns JSON object
+     */
+    public toJSON(): { [k: string]: any };
+}
+
+export namespace OpeningMetadata {
+
+    /** Properties of an ApplicationFormQuestion. */
+    interface IApplicationFormQuestion {
+
+        /** ApplicationFormQuestion question */
+        question?: (string|null);
+
+        /** ApplicationFormQuestion type */
+        type?: (OpeningMetadata.ApplicationFormQuestion.InputType|null);
+    }
+
+    /** Represents an ApplicationFormQuestion. */
+    class ApplicationFormQuestion implements IApplicationFormQuestion {
+
+        /**
+         * Constructs a new ApplicationFormQuestion.
+         * @param [properties] Properties to set
+         */
+        constructor(properties?: OpeningMetadata.IApplicationFormQuestion);
+
+        /** ApplicationFormQuestion question. */
+        public question: string;
+
+        /** ApplicationFormQuestion type. */
+        public type: OpeningMetadata.ApplicationFormQuestion.InputType;
+
+        /**
+         * Creates a new ApplicationFormQuestion instance using the specified properties.
+         * @param [properties] Properties to set
+         * @returns ApplicationFormQuestion instance
+         */
+        public static create(properties?: OpeningMetadata.IApplicationFormQuestion): OpeningMetadata.ApplicationFormQuestion;
+
+        /**
+         * Encodes the specified ApplicationFormQuestion message. Does not implicitly {@link OpeningMetadata.ApplicationFormQuestion.verify|verify} messages.
+         * @param message ApplicationFormQuestion message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encode(message: OpeningMetadata.IApplicationFormQuestion, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Encodes the specified ApplicationFormQuestion message, length delimited. Does not implicitly {@link OpeningMetadata.ApplicationFormQuestion.verify|verify} messages.
+         * @param message ApplicationFormQuestion message or plain object to encode
+         * @param [writer] Writer to encode to
+         * @returns Writer
+         */
+        public static encodeDelimited(message: OpeningMetadata.IApplicationFormQuestion, writer?: $protobuf.Writer): $protobuf.Writer;
+
+        /**
+         * Decodes an ApplicationFormQuestion message from the specified reader or buffer.
+         * @param reader Reader or buffer to decode from
+         * @param [length] Message length if known beforehand
+         * @returns ApplicationFormQuestion
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): OpeningMetadata.ApplicationFormQuestion;
+
+        /**
+         * Decodes an ApplicationFormQuestion message from the specified reader or buffer, length delimited.
+         * @param reader Reader or buffer to decode from
+         * @returns ApplicationFormQuestion
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): OpeningMetadata.ApplicationFormQuestion;
+
+        /**
+         * Verifies an ApplicationFormQuestion message.
+         * @param message Plain object to verify
+         * @returns `null` if valid, otherwise the reason why it is not
+         */
+        public static verify(message: { [k: string]: any }): (string|null);
+
+        /**
+         * Creates an ApplicationFormQuestion message from a plain object. Also converts values to their respective internal types.
+         * @param object Plain object
+         * @returns ApplicationFormQuestion
+         */
+        public static fromObject(object: { [k: string]: any }): OpeningMetadata.ApplicationFormQuestion;
+
+        /**
+         * Creates a plain object from an ApplicationFormQuestion message. Also converts values to other types if specified.
+         * @param message ApplicationFormQuestion
+         * @param [options] Conversion options
+         * @returns Plain object
+         */
+        public static toObject(message: OpeningMetadata.ApplicationFormQuestion, options?: $protobuf.IConversionOptions): { [k: string]: any };
+
+        /**
+         * Converts this ApplicationFormQuestion to JSON.
+         * @returns JSON object
+         */
+        public toJSON(): { [k: string]: any };
+    }
+
+    namespace ApplicationFormQuestion {
+
+        /** InputType enum. */
+        enum InputType {
+            TEXTAREA = 0,
+            TEXT = 1
+        }
+    }
+}
+
+/** Properties of an UpcomingOpeningMetadata. */
+export interface IUpcomingOpeningMetadata {
+
+    /** UpcomingOpeningMetadata expectedStart */
+    expectedStart?: (number|null);
+
+    /** UpcomingOpeningMetadata rewardPerBlock */
+    rewardPerBlock?: (Long|null);
+
+    /** UpcomingOpeningMetadata minApplicationStake */
+    minApplicationStake?: (Long|null);
+
+    /** UpcomingOpeningMetadata metadata */
+    metadata?: (IOpeningMetadata|null);
+}
+
+/** Represents an UpcomingOpeningMetadata. */
+export class UpcomingOpeningMetadata implements IUpcomingOpeningMetadata {
+
+    /**
+     * Constructs a new UpcomingOpeningMetadata.
+     * @param [properties] Properties to set
+     */
+    constructor(properties?: IUpcomingOpeningMetadata);
+
+    /** UpcomingOpeningMetadata expectedStart. */
+    public expectedStart: number;
+
+    /** UpcomingOpeningMetadata rewardPerBlock. */
+    public rewardPerBlock: Long;
+
+    /** UpcomingOpeningMetadata minApplicationStake. */
+    public minApplicationStake: Long;
+
+    /** UpcomingOpeningMetadata metadata. */
+    public metadata?: (IOpeningMetadata|null);
+
+    /**
+     * Creates a new UpcomingOpeningMetadata instance using the specified properties.
+     * @param [properties] Properties to set
+     * @returns UpcomingOpeningMetadata instance
+     */
+    public static create(properties?: IUpcomingOpeningMetadata): UpcomingOpeningMetadata;
+
+    /**
+     * Encodes the specified UpcomingOpeningMetadata message. Does not implicitly {@link UpcomingOpeningMetadata.verify|verify} messages.
+     * @param message UpcomingOpeningMetadata message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encode(message: IUpcomingOpeningMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Encodes the specified UpcomingOpeningMetadata message, length delimited. Does not implicitly {@link UpcomingOpeningMetadata.verify|verify} messages.
+     * @param message UpcomingOpeningMetadata message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encodeDelimited(message: IUpcomingOpeningMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Decodes an UpcomingOpeningMetadata message from the specified reader or buffer.
+     * @param reader Reader or buffer to decode from
+     * @param [length] Message length if known beforehand
+     * @returns UpcomingOpeningMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): UpcomingOpeningMetadata;
+
+    /**
+     * Decodes an UpcomingOpeningMetadata message from the specified reader or buffer, length delimited.
+     * @param reader Reader or buffer to decode from
+     * @returns UpcomingOpeningMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): UpcomingOpeningMetadata;
+
+    /**
+     * Verifies an UpcomingOpeningMetadata message.
+     * @param message Plain object to verify
+     * @returns `null` if valid, otherwise the reason why it is not
+     */
+    public static verify(message: { [k: string]: any }): (string|null);
+
+    /**
+     * Creates an UpcomingOpeningMetadata message from a plain object. Also converts values to their respective internal types.
+     * @param object Plain object
+     * @returns UpcomingOpeningMetadata
+     */
+    public static fromObject(object: { [k: string]: any }): UpcomingOpeningMetadata;
+
+    /**
+     * Creates a plain object from an UpcomingOpeningMetadata message. Also converts values to other types if specified.
+     * @param message UpcomingOpeningMetadata
+     * @param [options] Conversion options
+     * @returns Plain object
+     */
+    public static toObject(message: UpcomingOpeningMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
+
+    /**
+     * Converts this UpcomingOpeningMetadata to JSON.
+     * @returns JSON object
+     */
+    public toJSON(): { [k: string]: any };
+}
+
+/** Properties of an ApplicationMetadata. */
+export interface IApplicationMetadata {
+
+    /** ApplicationMetadata answers */
+    answers?: (string[]|null);
+}
+
+/** Represents an ApplicationMetadata. */
+export class ApplicationMetadata implements IApplicationMetadata {
+
+    /**
+     * Constructs a new ApplicationMetadata.
+     * @param [properties] Properties to set
+     */
+    constructor(properties?: IApplicationMetadata);
+
+    /** ApplicationMetadata answers. */
+    public answers: string[];
+
+    /**
+     * Creates a new ApplicationMetadata instance using the specified properties.
+     * @param [properties] Properties to set
+     * @returns ApplicationMetadata instance
+     */
+    public static create(properties?: IApplicationMetadata): ApplicationMetadata;
+
+    /**
+     * Encodes the specified ApplicationMetadata message. Does not implicitly {@link ApplicationMetadata.verify|verify} messages.
+     * @param message ApplicationMetadata message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encode(message: IApplicationMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Encodes the specified ApplicationMetadata message, length delimited. Does not implicitly {@link ApplicationMetadata.verify|verify} messages.
+     * @param message ApplicationMetadata message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encodeDelimited(message: IApplicationMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Decodes an ApplicationMetadata message from the specified reader or buffer.
+     * @param reader Reader or buffer to decode from
+     * @param [length] Message length if known beforehand
+     * @returns ApplicationMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): ApplicationMetadata;
+
+    /**
+     * Decodes an ApplicationMetadata message from the specified reader or buffer, length delimited.
+     * @param reader Reader or buffer to decode from
+     * @returns ApplicationMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): ApplicationMetadata;
+
+    /**
+     * Verifies an ApplicationMetadata message.
+     * @param message Plain object to verify
+     * @returns `null` if valid, otherwise the reason why it is not
+     */
+    public static verify(message: { [k: string]: any }): (string|null);
+
+    /**
+     * Creates an ApplicationMetadata message from a plain object. Also converts values to their respective internal types.
+     * @param object Plain object
+     * @returns ApplicationMetadata
+     */
+    public static fromObject(object: { [k: string]: any }): ApplicationMetadata;
+
+    /**
+     * Creates a plain object from an ApplicationMetadata message. Also converts values to other types if specified.
+     * @param message ApplicationMetadata
+     * @param [options] Conversion options
+     * @returns Plain object
+     */
+    public static toObject(message: ApplicationMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
+
+    /**
+     * Converts this ApplicationMetadata to JSON.
+     * @returns JSON object
+     */
+    public toJSON(): { [k: string]: any };
+}
+
+/** Properties of a WorkingGroupMetadata. */
+export interface IWorkingGroupMetadata {
+
+    /** WorkingGroupMetadata description */
+    description?: (string|null);
+
+    /** WorkingGroupMetadata about */
+    about?: (string|null);
+
+    /** WorkingGroupMetadata status */
+    status?: (string|null);
+
+    /** WorkingGroupMetadata statusMessage */
+    statusMessage?: (string|null);
+}
+
+/** Represents a WorkingGroupMetadata. */
+export class WorkingGroupMetadata implements IWorkingGroupMetadata {
+
+    /**
+     * Constructs a new WorkingGroupMetadata.
+     * @param [properties] Properties to set
+     */
+    constructor(properties?: IWorkingGroupMetadata);
+
+    /** WorkingGroupMetadata description. */
+    public description: string;
+
+    /** WorkingGroupMetadata about. */
+    public about: string;
+
+    /** WorkingGroupMetadata status. */
+    public status: string;
+
+    /** WorkingGroupMetadata statusMessage. */
+    public statusMessage: string;
+
+    /**
+     * Creates a new WorkingGroupMetadata instance using the specified properties.
+     * @param [properties] Properties to set
+     * @returns WorkingGroupMetadata instance
+     */
+    public static create(properties?: IWorkingGroupMetadata): WorkingGroupMetadata;
+
+    /**
+     * Encodes the specified WorkingGroupMetadata message. Does not implicitly {@link WorkingGroupMetadata.verify|verify} messages.
+     * @param message WorkingGroupMetadata message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encode(message: IWorkingGroupMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Encodes the specified WorkingGroupMetadata message, length delimited. Does not implicitly {@link WorkingGroupMetadata.verify|verify} messages.
+     * @param message WorkingGroupMetadata message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encodeDelimited(message: IWorkingGroupMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Decodes a WorkingGroupMetadata message from the specified reader or buffer.
+     * @param reader Reader or buffer to decode from
+     * @param [length] Message length if known beforehand
+     * @returns WorkingGroupMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): WorkingGroupMetadata;
+
+    /**
+     * Decodes a WorkingGroupMetadata message from the specified reader or buffer, length delimited.
+     * @param reader Reader or buffer to decode from
+     * @returns WorkingGroupMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): WorkingGroupMetadata;
+
+    /**
+     * Verifies a WorkingGroupMetadata message.
+     * @param message Plain object to verify
+     * @returns `null` if valid, otherwise the reason why it is not
+     */
+    public static verify(message: { [k: string]: any }): (string|null);
+
+    /**
+     * Creates a WorkingGroupMetadata message from a plain object. Also converts values to their respective internal types.
+     * @param object Plain object
+     * @returns WorkingGroupMetadata
+     */
+    public static fromObject(object: { [k: string]: any }): WorkingGroupMetadata;
+
+    /**
+     * Creates a plain object from a WorkingGroupMetadata message. Also converts values to other types if specified.
+     * @param message WorkingGroupMetadata
+     * @param [options] Conversion options
+     * @returns Plain object
+     */
+    public static toObject(message: WorkingGroupMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
+
+    /**
+     * Converts this WorkingGroupMetadata to JSON.
+     * @returns JSON object
+     */
+    public toJSON(): { [k: string]: any };
+}
+
+/** Properties of a SetGroupMetadata. */
+export interface ISetGroupMetadata {
+
+    /** SetGroupMetadata newMetadata */
+    newMetadata?: (IWorkingGroupMetadata|null);
+}
+
+/** Represents a SetGroupMetadata. */
+export class SetGroupMetadata implements ISetGroupMetadata {
+
+    /**
+     * Constructs a new SetGroupMetadata.
+     * @param [properties] Properties to set
+     */
+    constructor(properties?: ISetGroupMetadata);
+
+    /** SetGroupMetadata newMetadata. */
+    public newMetadata?: (IWorkingGroupMetadata|null);
+
+    /**
+     * Creates a new SetGroupMetadata instance using the specified properties.
+     * @param [properties] Properties to set
+     * @returns SetGroupMetadata instance
+     */
+    public static create(properties?: ISetGroupMetadata): SetGroupMetadata;
+
+    /**
+     * Encodes the specified SetGroupMetadata message. Does not implicitly {@link SetGroupMetadata.verify|verify} messages.
+     * @param message SetGroupMetadata message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encode(message: ISetGroupMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Encodes the specified SetGroupMetadata message, length delimited. Does not implicitly {@link SetGroupMetadata.verify|verify} messages.
+     * @param message SetGroupMetadata message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encodeDelimited(message: ISetGroupMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Decodes a SetGroupMetadata message from the specified reader or buffer.
+     * @param reader Reader or buffer to decode from
+     * @param [length] Message length if known beforehand
+     * @returns SetGroupMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): SetGroupMetadata;
+
+    /**
+     * Decodes a SetGroupMetadata message from the specified reader or buffer, length delimited.
+     * @param reader Reader or buffer to decode from
+     * @returns SetGroupMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): SetGroupMetadata;
+
+    /**
+     * Verifies a SetGroupMetadata message.
+     * @param message Plain object to verify
+     * @returns `null` if valid, otherwise the reason why it is not
+     */
+    public static verify(message: { [k: string]: any }): (string|null);
+
+    /**
+     * Creates a SetGroupMetadata message from a plain object. Also converts values to their respective internal types.
+     * @param object Plain object
+     * @returns SetGroupMetadata
+     */
+    public static fromObject(object: { [k: string]: any }): SetGroupMetadata;
+
+    /**
+     * Creates a plain object from a SetGroupMetadata message. Also converts values to other types if specified.
+     * @param message SetGroupMetadata
+     * @param [options] Conversion options
+     * @returns Plain object
+     */
+    public static toObject(message: SetGroupMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
+
+    /**
+     * Converts this SetGroupMetadata to JSON.
+     * @returns JSON object
+     */
+    public toJSON(): { [k: string]: any };
+}
+
+/** Properties of an AddUpcomingOpening. */
+export interface IAddUpcomingOpening {
+
+    /** AddUpcomingOpening metadata */
+    metadata?: (IUpcomingOpeningMetadata|null);
+}
+
+/** Represents an AddUpcomingOpening. */
+export class AddUpcomingOpening implements IAddUpcomingOpening {
+
+    /**
+     * Constructs a new AddUpcomingOpening.
+     * @param [properties] Properties to set
+     */
+    constructor(properties?: IAddUpcomingOpening);
+
+    /** AddUpcomingOpening metadata. */
+    public metadata?: (IUpcomingOpeningMetadata|null);
+
+    /**
+     * Creates a new AddUpcomingOpening instance using the specified properties.
+     * @param [properties] Properties to set
+     * @returns AddUpcomingOpening instance
+     */
+    public static create(properties?: IAddUpcomingOpening): AddUpcomingOpening;
+
+    /**
+     * Encodes the specified AddUpcomingOpening message. Does not implicitly {@link AddUpcomingOpening.verify|verify} messages.
+     * @param message AddUpcomingOpening message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encode(message: IAddUpcomingOpening, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Encodes the specified AddUpcomingOpening message, length delimited. Does not implicitly {@link AddUpcomingOpening.verify|verify} messages.
+     * @param message AddUpcomingOpening message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encodeDelimited(message: IAddUpcomingOpening, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Decodes an AddUpcomingOpening message from the specified reader or buffer.
+     * @param reader Reader or buffer to decode from
+     * @param [length] Message length if known beforehand
+     * @returns AddUpcomingOpening
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): AddUpcomingOpening;
+
+    /**
+     * Decodes an AddUpcomingOpening message from the specified reader or buffer, length delimited.
+     * @param reader Reader or buffer to decode from
+     * @returns AddUpcomingOpening
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): AddUpcomingOpening;
+
+    /**
+     * Verifies an AddUpcomingOpening message.
+     * @param message Plain object to verify
+     * @returns `null` if valid, otherwise the reason why it is not
+     */
+    public static verify(message: { [k: string]: any }): (string|null);
+
+    /**
+     * Creates an AddUpcomingOpening message from a plain object. Also converts values to their respective internal types.
+     * @param object Plain object
+     * @returns AddUpcomingOpening
+     */
+    public static fromObject(object: { [k: string]: any }): AddUpcomingOpening;
+
+    /**
+     * Creates a plain object from an AddUpcomingOpening message. Also converts values to other types if specified.
+     * @param message AddUpcomingOpening
+     * @param [options] Conversion options
+     * @returns Plain object
+     */
+    public static toObject(message: AddUpcomingOpening, options?: $protobuf.IConversionOptions): { [k: string]: any };
+
+    /**
+     * Converts this AddUpcomingOpening to JSON.
+     * @returns JSON object
+     */
+    public toJSON(): { [k: string]: any };
+}
+
+/** Properties of a RemoveUpcomingOpening. */
+export interface IRemoveUpcomingOpening {
+
+    /** RemoveUpcomingOpening id */
+    id?: (string|null);
+}
+
+/** Represents a RemoveUpcomingOpening. */
+export class RemoveUpcomingOpening implements IRemoveUpcomingOpening {
+
+    /**
+     * Constructs a new RemoveUpcomingOpening.
+     * @param [properties] Properties to set
+     */
+    constructor(properties?: IRemoveUpcomingOpening);
+
+    /** RemoveUpcomingOpening id. */
+    public id: string;
+
+    /**
+     * Creates a new RemoveUpcomingOpening instance using the specified properties.
+     * @param [properties] Properties to set
+     * @returns RemoveUpcomingOpening instance
+     */
+    public static create(properties?: IRemoveUpcomingOpening): RemoveUpcomingOpening;
+
+    /**
+     * Encodes the specified RemoveUpcomingOpening message. Does not implicitly {@link RemoveUpcomingOpening.verify|verify} messages.
+     * @param message RemoveUpcomingOpening message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encode(message: IRemoveUpcomingOpening, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Encodes the specified RemoveUpcomingOpening message, length delimited. Does not implicitly {@link RemoveUpcomingOpening.verify|verify} messages.
+     * @param message RemoveUpcomingOpening message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encodeDelimited(message: IRemoveUpcomingOpening, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Decodes a RemoveUpcomingOpening message from the specified reader or buffer.
+     * @param reader Reader or buffer to decode from
+     * @param [length] Message length if known beforehand
+     * @returns RemoveUpcomingOpening
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): RemoveUpcomingOpening;
+
+    /**
+     * Decodes a RemoveUpcomingOpening message from the specified reader or buffer, length delimited.
+     * @param reader Reader or buffer to decode from
+     * @returns RemoveUpcomingOpening
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): RemoveUpcomingOpening;
+
+    /**
+     * Verifies a RemoveUpcomingOpening message.
+     * @param message Plain object to verify
+     * @returns `null` if valid, otherwise the reason why it is not
+     */
+    public static verify(message: { [k: string]: any }): (string|null);
+
+    /**
+     * Creates a RemoveUpcomingOpening message from a plain object. Also converts values to their respective internal types.
+     * @param object Plain object
+     * @returns RemoveUpcomingOpening
+     */
+    public static fromObject(object: { [k: string]: any }): RemoveUpcomingOpening;
+
+    /**
+     * Creates a plain object from a RemoveUpcomingOpening message. Also converts values to other types if specified.
+     * @param message RemoveUpcomingOpening
+     * @param [options] Conversion options
+     * @returns Plain object
+     */
+    public static toObject(message: RemoveUpcomingOpening, options?: $protobuf.IConversionOptions): { [k: string]: any };
+
+    /**
+     * Converts this RemoveUpcomingOpening to JSON.
+     * @returns JSON object
+     */
+    public toJSON(): { [k: string]: any };
+}
+
+/** Properties of a WorkingGroupMetadataAction. */
+export interface IWorkingGroupMetadataAction {
+
+    /** WorkingGroupMetadataAction setGroupMetadata */
+    setGroupMetadata?: (ISetGroupMetadata|null);
+
+    /** WorkingGroupMetadataAction addUpcomingOpening */
+    addUpcomingOpening?: (IAddUpcomingOpening|null);
+
+    /** WorkingGroupMetadataAction removeUpcomingOpening */
+    removeUpcomingOpening?: (IRemoveUpcomingOpening|null);
+}
+
+/** Represents a WorkingGroupMetadataAction. */
+export class WorkingGroupMetadataAction implements IWorkingGroupMetadataAction {
+
+    /**
+     * Constructs a new WorkingGroupMetadataAction.
+     * @param [properties] Properties to set
+     */
+    constructor(properties?: IWorkingGroupMetadataAction);
+
+    /** WorkingGroupMetadataAction setGroupMetadata. */
+    public setGroupMetadata?: (ISetGroupMetadata|null);
+
+    /** WorkingGroupMetadataAction addUpcomingOpening. */
+    public addUpcomingOpening?: (IAddUpcomingOpening|null);
+
+    /** WorkingGroupMetadataAction removeUpcomingOpening. */
+    public removeUpcomingOpening?: (IRemoveUpcomingOpening|null);
+
+    /** WorkingGroupMetadataAction action. */
+    public action?: ("setGroupMetadata"|"addUpcomingOpening"|"removeUpcomingOpening");
+
+    /**
+     * Creates a new WorkingGroupMetadataAction instance using the specified properties.
+     * @param [properties] Properties to set
+     * @returns WorkingGroupMetadataAction instance
+     */
+    public static create(properties?: IWorkingGroupMetadataAction): WorkingGroupMetadataAction;
+
+    /**
+     * Encodes the specified WorkingGroupMetadataAction message. Does not implicitly {@link WorkingGroupMetadataAction.verify|verify} messages.
+     * @param message WorkingGroupMetadataAction message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encode(message: IWorkingGroupMetadataAction, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Encodes the specified WorkingGroupMetadataAction message, length delimited. Does not implicitly {@link WorkingGroupMetadataAction.verify|verify} messages.
+     * @param message WorkingGroupMetadataAction message or plain object to encode
+     * @param [writer] Writer to encode to
+     * @returns Writer
+     */
+    public static encodeDelimited(message: IWorkingGroupMetadataAction, writer?: $protobuf.Writer): $protobuf.Writer;
+
+    /**
+     * Decodes a WorkingGroupMetadataAction message from the specified reader or buffer.
+     * @param reader Reader or buffer to decode from
+     * @param [length] Message length if known beforehand
+     * @returns WorkingGroupMetadataAction
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): WorkingGroupMetadataAction;
+
+    /**
+     * Decodes a WorkingGroupMetadataAction message from the specified reader or buffer, length delimited.
+     * @param reader Reader or buffer to decode from
+     * @returns WorkingGroupMetadataAction
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): WorkingGroupMetadataAction;
+
+    /**
+     * Verifies a WorkingGroupMetadataAction message.
+     * @param message Plain object to verify
+     * @returns `null` if valid, otherwise the reason why it is not
+     */
+    public static verify(message: { [k: string]: any }): (string|null);
+
+    /**
+     * Creates a WorkingGroupMetadataAction message from a plain object. Also converts values to their respective internal types.
+     * @param object Plain object
+     * @returns WorkingGroupMetadataAction
+     */
+    public static fromObject(object: { [k: string]: any }): WorkingGroupMetadataAction;
+
+    /**
+     * Creates a plain object from a WorkingGroupMetadataAction message. Also converts values to other types if specified.
+     * @param message WorkingGroupMetadataAction
+     * @param [options] Conversion options
+     * @returns Plain object
+     */
+    public static toObject(message: WorkingGroupMetadataAction, options?: $protobuf.IConversionOptions): { [k: string]: any };
+
+    /**
+     * Converts this WorkingGroupMetadataAction to JSON.
+     * @returns JSON object
+     */
+    public toJSON(): { [k: string]: any };
+}

+ 2666 - 0
metadata-protobuf/compiled/index.js

@@ -0,0 +1,2666 @@
+/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/
+"use strict";
+
+var $protobuf = require("protobufjs/minimal");
+
+// Common aliases
+var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
+
+// Exported root namespace
+var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {});
+
+$root.CouncilCandidacyNoteMetadata = (function() {
+
+    /**
+     * Properties of a CouncilCandidacyNoteMetadata.
+     * @exports ICouncilCandidacyNoteMetadata
+     * @interface ICouncilCandidacyNoteMetadata
+     * @property {string|null} [header] CouncilCandidacyNoteMetadata header
+     * @property {Array.<string>|null} [bulletPoints] CouncilCandidacyNoteMetadata bulletPoints
+     * @property {string|null} [bannerImageUri] CouncilCandidacyNoteMetadata bannerImageUri
+     * @property {string|null} [description] CouncilCandidacyNoteMetadata description
+     */
+
+    /**
+     * Constructs a new CouncilCandidacyNoteMetadata.
+     * @exports CouncilCandidacyNoteMetadata
+     * @classdesc Represents a CouncilCandidacyNoteMetadata.
+     * @implements ICouncilCandidacyNoteMetadata
+     * @constructor
+     * @param {ICouncilCandidacyNoteMetadata=} [properties] Properties to set
+     */
+    function CouncilCandidacyNoteMetadata(properties) {
+        this.bulletPoints = [];
+        if (properties)
+            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                if (properties[keys[i]] != null)
+                    this[keys[i]] = properties[keys[i]];
+    }
+
+    /**
+     * CouncilCandidacyNoteMetadata header.
+     * @member {string} header
+     * @memberof CouncilCandidacyNoteMetadata
+     * @instance
+     */
+    CouncilCandidacyNoteMetadata.prototype.header = "";
+
+    /**
+     * CouncilCandidacyNoteMetadata bulletPoints.
+     * @member {Array.<string>} bulletPoints
+     * @memberof CouncilCandidacyNoteMetadata
+     * @instance
+     */
+    CouncilCandidacyNoteMetadata.prototype.bulletPoints = $util.emptyArray;
+
+    /**
+     * CouncilCandidacyNoteMetadata bannerImageUri.
+     * @member {string} bannerImageUri
+     * @memberof CouncilCandidacyNoteMetadata
+     * @instance
+     */
+    CouncilCandidacyNoteMetadata.prototype.bannerImageUri = "";
+
+    /**
+     * CouncilCandidacyNoteMetadata description.
+     * @member {string} description
+     * @memberof CouncilCandidacyNoteMetadata
+     * @instance
+     */
+    CouncilCandidacyNoteMetadata.prototype.description = "";
+
+    /**
+     * Creates a new CouncilCandidacyNoteMetadata instance using the specified properties.
+     * @function create
+     * @memberof CouncilCandidacyNoteMetadata
+     * @static
+     * @param {ICouncilCandidacyNoteMetadata=} [properties] Properties to set
+     * @returns {CouncilCandidacyNoteMetadata} CouncilCandidacyNoteMetadata instance
+     */
+    CouncilCandidacyNoteMetadata.create = function create(properties) {
+        return new CouncilCandidacyNoteMetadata(properties);
+    };
+
+    /**
+     * Encodes the specified CouncilCandidacyNoteMetadata message. Does not implicitly {@link CouncilCandidacyNoteMetadata.verify|verify} messages.
+     * @function encode
+     * @memberof CouncilCandidacyNoteMetadata
+     * @static
+     * @param {ICouncilCandidacyNoteMetadata} message CouncilCandidacyNoteMetadata message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    CouncilCandidacyNoteMetadata.encode = function encode(message, writer) {
+        if (!writer)
+            writer = $Writer.create();
+        if (message.header != null && Object.hasOwnProperty.call(message, "header"))
+            writer.uint32(/* id 1, wireType 2 =*/10).string(message.header);
+        if (message.bulletPoints != null && message.bulletPoints.length)
+            for (var i = 0; i < message.bulletPoints.length; ++i)
+                writer.uint32(/* id 2, wireType 2 =*/18).string(message.bulletPoints[i]);
+        if (message.bannerImageUri != null && Object.hasOwnProperty.call(message, "bannerImageUri"))
+            writer.uint32(/* id 3, wireType 2 =*/26).string(message.bannerImageUri);
+        if (message.description != null && Object.hasOwnProperty.call(message, "description"))
+            writer.uint32(/* id 4, wireType 2 =*/34).string(message.description);
+        return writer;
+    };
+
+    /**
+     * Encodes the specified CouncilCandidacyNoteMetadata message, length delimited. Does not implicitly {@link CouncilCandidacyNoteMetadata.verify|verify} messages.
+     * @function encodeDelimited
+     * @memberof CouncilCandidacyNoteMetadata
+     * @static
+     * @param {ICouncilCandidacyNoteMetadata} message CouncilCandidacyNoteMetadata message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    CouncilCandidacyNoteMetadata.encodeDelimited = function encodeDelimited(message, writer) {
+        return this.encode(message, writer).ldelim();
+    };
+
+    /**
+     * Decodes a CouncilCandidacyNoteMetadata message from the specified reader or buffer.
+     * @function decode
+     * @memberof CouncilCandidacyNoteMetadata
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @param {number} [length] Message length if known beforehand
+     * @returns {CouncilCandidacyNoteMetadata} CouncilCandidacyNoteMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    CouncilCandidacyNoteMetadata.decode = function decode(reader, length) {
+        if (!(reader instanceof $Reader))
+            reader = $Reader.create(reader);
+        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.CouncilCandidacyNoteMetadata();
+        while (reader.pos < end) {
+            var tag = reader.uint32();
+            switch (tag >>> 3) {
+            case 1:
+                message.header = reader.string();
+                break;
+            case 2:
+                if (!(message.bulletPoints && message.bulletPoints.length))
+                    message.bulletPoints = [];
+                message.bulletPoints.push(reader.string());
+                break;
+            case 3:
+                message.bannerImageUri = reader.string();
+                break;
+            case 4:
+                message.description = reader.string();
+                break;
+            default:
+                reader.skipType(tag & 7);
+                break;
+            }
+        }
+        return message;
+    };
+
+    /**
+     * Decodes a CouncilCandidacyNoteMetadata message from the specified reader or buffer, length delimited.
+     * @function decodeDelimited
+     * @memberof CouncilCandidacyNoteMetadata
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @returns {CouncilCandidacyNoteMetadata} CouncilCandidacyNoteMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    CouncilCandidacyNoteMetadata.decodeDelimited = function decodeDelimited(reader) {
+        if (!(reader instanceof $Reader))
+            reader = new $Reader(reader);
+        return this.decode(reader, reader.uint32());
+    };
+
+    /**
+     * Verifies a CouncilCandidacyNoteMetadata message.
+     * @function verify
+     * @memberof CouncilCandidacyNoteMetadata
+     * @static
+     * @param {Object.<string,*>} message Plain object to verify
+     * @returns {string|null} `null` if valid, otherwise the reason why it is not
+     */
+    CouncilCandidacyNoteMetadata.verify = function verify(message) {
+        if (typeof message !== "object" || message === null)
+            return "object expected";
+        if (message.header != null && message.hasOwnProperty("header"))
+            if (!$util.isString(message.header))
+                return "header: string expected";
+        if (message.bulletPoints != null && message.hasOwnProperty("bulletPoints")) {
+            if (!Array.isArray(message.bulletPoints))
+                return "bulletPoints: array expected";
+            for (var i = 0; i < message.bulletPoints.length; ++i)
+                if (!$util.isString(message.bulletPoints[i]))
+                    return "bulletPoints: string[] expected";
+        }
+        if (message.bannerImageUri != null && message.hasOwnProperty("bannerImageUri"))
+            if (!$util.isString(message.bannerImageUri))
+                return "bannerImageUri: string expected";
+        if (message.description != null && message.hasOwnProperty("description"))
+            if (!$util.isString(message.description))
+                return "description: string expected";
+        return null;
+    };
+
+    /**
+     * Creates a CouncilCandidacyNoteMetadata message from a plain object. Also converts values to their respective internal types.
+     * @function fromObject
+     * @memberof CouncilCandidacyNoteMetadata
+     * @static
+     * @param {Object.<string,*>} object Plain object
+     * @returns {CouncilCandidacyNoteMetadata} CouncilCandidacyNoteMetadata
+     */
+    CouncilCandidacyNoteMetadata.fromObject = function fromObject(object) {
+        if (object instanceof $root.CouncilCandidacyNoteMetadata)
+            return object;
+        var message = new $root.CouncilCandidacyNoteMetadata();
+        if (object.header != null)
+            message.header = String(object.header);
+        if (object.bulletPoints) {
+            if (!Array.isArray(object.bulletPoints))
+                throw TypeError(".CouncilCandidacyNoteMetadata.bulletPoints: array expected");
+            message.bulletPoints = [];
+            for (var i = 0; i < object.bulletPoints.length; ++i)
+                message.bulletPoints[i] = String(object.bulletPoints[i]);
+        }
+        if (object.bannerImageUri != null)
+            message.bannerImageUri = String(object.bannerImageUri);
+        if (object.description != null)
+            message.description = String(object.description);
+        return message;
+    };
+
+    /**
+     * Creates a plain object from a CouncilCandidacyNoteMetadata message. Also converts values to other types if specified.
+     * @function toObject
+     * @memberof CouncilCandidacyNoteMetadata
+     * @static
+     * @param {CouncilCandidacyNoteMetadata} message CouncilCandidacyNoteMetadata
+     * @param {$protobuf.IConversionOptions} [options] Conversion options
+     * @returns {Object.<string,*>} Plain object
+     */
+    CouncilCandidacyNoteMetadata.toObject = function toObject(message, options) {
+        if (!options)
+            options = {};
+        var object = {};
+        if (options.arrays || options.defaults)
+            object.bulletPoints = [];
+        if (options.defaults) {
+            object.header = "";
+            object.bannerImageUri = "";
+            object.description = "";
+        }
+        if (message.header != null && message.hasOwnProperty("header"))
+            object.header = message.header;
+        if (message.bulletPoints && message.bulletPoints.length) {
+            object.bulletPoints = [];
+            for (var j = 0; j < message.bulletPoints.length; ++j)
+                object.bulletPoints[j] = message.bulletPoints[j];
+        }
+        if (message.bannerImageUri != null && message.hasOwnProperty("bannerImageUri"))
+            object.bannerImageUri = message.bannerImageUri;
+        if (message.description != null && message.hasOwnProperty("description"))
+            object.description = message.description;
+        return object;
+    };
+
+    /**
+     * Converts this CouncilCandidacyNoteMetadata to JSON.
+     * @function toJSON
+     * @memberof CouncilCandidacyNoteMetadata
+     * @instance
+     * @returns {Object.<string,*>} JSON object
+     */
+    CouncilCandidacyNoteMetadata.prototype.toJSON = function toJSON() {
+        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
+    };
+
+    return CouncilCandidacyNoteMetadata;
+})();
+
+$root.MembershipMetadata = (function() {
+
+    /**
+     * Properties of a MembershipMetadata.
+     * @exports IMembershipMetadata
+     * @interface IMembershipMetadata
+     * @property {string|null} [name] MembershipMetadata name
+     * @property {number|null} [avatar] MembershipMetadata avatar
+     * @property {string|null} [about] MembershipMetadata about
+     */
+
+    /**
+     * Constructs a new MembershipMetadata.
+     * @exports MembershipMetadata
+     * @classdesc Represents a MembershipMetadata.
+     * @implements IMembershipMetadata
+     * @constructor
+     * @param {IMembershipMetadata=} [properties] Properties to set
+     */
+    function MembershipMetadata(properties) {
+        if (properties)
+            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                if (properties[keys[i]] != null)
+                    this[keys[i]] = properties[keys[i]];
+    }
+
+    /**
+     * MembershipMetadata name.
+     * @member {string} name
+     * @memberof MembershipMetadata
+     * @instance
+     */
+    MembershipMetadata.prototype.name = "";
+
+    /**
+     * MembershipMetadata avatar.
+     * @member {number} avatar
+     * @memberof MembershipMetadata
+     * @instance
+     */
+    MembershipMetadata.prototype.avatar = 0;
+
+    /**
+     * MembershipMetadata about.
+     * @member {string} about
+     * @memberof MembershipMetadata
+     * @instance
+     */
+    MembershipMetadata.prototype.about = "";
+
+    /**
+     * Creates a new MembershipMetadata instance using the specified properties.
+     * @function create
+     * @memberof MembershipMetadata
+     * @static
+     * @param {IMembershipMetadata=} [properties] Properties to set
+     * @returns {MembershipMetadata} MembershipMetadata instance
+     */
+    MembershipMetadata.create = function create(properties) {
+        return new MembershipMetadata(properties);
+    };
+
+    /**
+     * Encodes the specified MembershipMetadata message. Does not implicitly {@link MembershipMetadata.verify|verify} messages.
+     * @function encode
+     * @memberof MembershipMetadata
+     * @static
+     * @param {IMembershipMetadata} message MembershipMetadata message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    MembershipMetadata.encode = function encode(message, writer) {
+        if (!writer)
+            writer = $Writer.create();
+        if (message.name != null && Object.hasOwnProperty.call(message, "name"))
+            writer.uint32(/* id 1, wireType 2 =*/10).string(message.name);
+        if (message.avatar != null && Object.hasOwnProperty.call(message, "avatar"))
+            writer.uint32(/* id 2, wireType 0 =*/16).uint32(message.avatar);
+        if (message.about != null && Object.hasOwnProperty.call(message, "about"))
+            writer.uint32(/* id 3, wireType 2 =*/26).string(message.about);
+        return writer;
+    };
+
+    /**
+     * Encodes the specified MembershipMetadata message, length delimited. Does not implicitly {@link MembershipMetadata.verify|verify} messages.
+     * @function encodeDelimited
+     * @memberof MembershipMetadata
+     * @static
+     * @param {IMembershipMetadata} message MembershipMetadata message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    MembershipMetadata.encodeDelimited = function encodeDelimited(message, writer) {
+        return this.encode(message, writer).ldelim();
+    };
+
+    /**
+     * Decodes a MembershipMetadata message from the specified reader or buffer.
+     * @function decode
+     * @memberof MembershipMetadata
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @param {number} [length] Message length if known beforehand
+     * @returns {MembershipMetadata} MembershipMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    MembershipMetadata.decode = function decode(reader, length) {
+        if (!(reader instanceof $Reader))
+            reader = $Reader.create(reader);
+        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.MembershipMetadata();
+        while (reader.pos < end) {
+            var tag = reader.uint32();
+            switch (tag >>> 3) {
+            case 1:
+                message.name = reader.string();
+                break;
+            case 2:
+                message.avatar = reader.uint32();
+                break;
+            case 3:
+                message.about = reader.string();
+                break;
+            default:
+                reader.skipType(tag & 7);
+                break;
+            }
+        }
+        return message;
+    };
+
+    /**
+     * Decodes a MembershipMetadata message from the specified reader or buffer, length delimited.
+     * @function decodeDelimited
+     * @memberof MembershipMetadata
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @returns {MembershipMetadata} MembershipMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    MembershipMetadata.decodeDelimited = function decodeDelimited(reader) {
+        if (!(reader instanceof $Reader))
+            reader = new $Reader(reader);
+        return this.decode(reader, reader.uint32());
+    };
+
+    /**
+     * Verifies a MembershipMetadata message.
+     * @function verify
+     * @memberof MembershipMetadata
+     * @static
+     * @param {Object.<string,*>} message Plain object to verify
+     * @returns {string|null} `null` if valid, otherwise the reason why it is not
+     */
+    MembershipMetadata.verify = function verify(message) {
+        if (typeof message !== "object" || message === null)
+            return "object expected";
+        if (message.name != null && message.hasOwnProperty("name"))
+            if (!$util.isString(message.name))
+                return "name: string expected";
+        if (message.avatar != null && message.hasOwnProperty("avatar"))
+            if (!$util.isInteger(message.avatar))
+                return "avatar: integer expected";
+        if (message.about != null && message.hasOwnProperty("about"))
+            if (!$util.isString(message.about))
+                return "about: string expected";
+        return null;
+    };
+
+    /**
+     * Creates a MembershipMetadata message from a plain object. Also converts values to their respective internal types.
+     * @function fromObject
+     * @memberof MembershipMetadata
+     * @static
+     * @param {Object.<string,*>} object Plain object
+     * @returns {MembershipMetadata} MembershipMetadata
+     */
+    MembershipMetadata.fromObject = function fromObject(object) {
+        if (object instanceof $root.MembershipMetadata)
+            return object;
+        var message = new $root.MembershipMetadata();
+        if (object.name != null)
+            message.name = String(object.name);
+        if (object.avatar != null)
+            message.avatar = object.avatar >>> 0;
+        if (object.about != null)
+            message.about = String(object.about);
+        return message;
+    };
+
+    /**
+     * Creates a plain object from a MembershipMetadata message. Also converts values to other types if specified.
+     * @function toObject
+     * @memberof MembershipMetadata
+     * @static
+     * @param {MembershipMetadata} message MembershipMetadata
+     * @param {$protobuf.IConversionOptions} [options] Conversion options
+     * @returns {Object.<string,*>} Plain object
+     */
+    MembershipMetadata.toObject = function toObject(message, options) {
+        if (!options)
+            options = {};
+        var object = {};
+        if (options.defaults) {
+            object.name = "";
+            object.avatar = 0;
+            object.about = "";
+        }
+        if (message.name != null && message.hasOwnProperty("name"))
+            object.name = message.name;
+        if (message.avatar != null && message.hasOwnProperty("avatar"))
+            object.avatar = message.avatar;
+        if (message.about != null && message.hasOwnProperty("about"))
+            object.about = message.about;
+        return object;
+    };
+
+    /**
+     * Converts this MembershipMetadata to JSON.
+     * @function toJSON
+     * @memberof MembershipMetadata
+     * @instance
+     * @returns {Object.<string,*>} JSON object
+     */
+    MembershipMetadata.prototype.toJSON = function toJSON() {
+        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
+    };
+
+    return MembershipMetadata;
+})();
+
+$root.OpeningMetadata = (function() {
+
+    /**
+     * Properties of an OpeningMetadata.
+     * @exports IOpeningMetadata
+     * @interface IOpeningMetadata
+     * @property {string|null} [shortDescription] OpeningMetadata shortDescription
+     * @property {string|null} [description] OpeningMetadata description
+     * @property {number|null} [hiringLimit] OpeningMetadata hiringLimit
+     * @property {number|null} [expectedEndingTimestamp] OpeningMetadata expectedEndingTimestamp
+     * @property {string|null} [applicationDetails] OpeningMetadata applicationDetails
+     * @property {Array.<OpeningMetadata.IApplicationFormQuestion>|null} [applicationFormQuestions] OpeningMetadata applicationFormQuestions
+     */
+
+    /**
+     * Constructs a new OpeningMetadata.
+     * @exports OpeningMetadata
+     * @classdesc Represents an OpeningMetadata.
+     * @implements IOpeningMetadata
+     * @constructor
+     * @param {IOpeningMetadata=} [properties] Properties to set
+     */
+    function OpeningMetadata(properties) {
+        this.applicationFormQuestions = [];
+        if (properties)
+            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                if (properties[keys[i]] != null)
+                    this[keys[i]] = properties[keys[i]];
+    }
+
+    /**
+     * OpeningMetadata shortDescription.
+     * @member {string} shortDescription
+     * @memberof OpeningMetadata
+     * @instance
+     */
+    OpeningMetadata.prototype.shortDescription = "";
+
+    /**
+     * OpeningMetadata description.
+     * @member {string} description
+     * @memberof OpeningMetadata
+     * @instance
+     */
+    OpeningMetadata.prototype.description = "";
+
+    /**
+     * OpeningMetadata hiringLimit.
+     * @member {number} hiringLimit
+     * @memberof OpeningMetadata
+     * @instance
+     */
+    OpeningMetadata.prototype.hiringLimit = 0;
+
+    /**
+     * OpeningMetadata expectedEndingTimestamp.
+     * @member {number} expectedEndingTimestamp
+     * @memberof OpeningMetadata
+     * @instance
+     */
+    OpeningMetadata.prototype.expectedEndingTimestamp = 0;
+
+    /**
+     * OpeningMetadata applicationDetails.
+     * @member {string} applicationDetails
+     * @memberof OpeningMetadata
+     * @instance
+     */
+    OpeningMetadata.prototype.applicationDetails = "";
+
+    /**
+     * OpeningMetadata applicationFormQuestions.
+     * @member {Array.<OpeningMetadata.IApplicationFormQuestion>} applicationFormQuestions
+     * @memberof OpeningMetadata
+     * @instance
+     */
+    OpeningMetadata.prototype.applicationFormQuestions = $util.emptyArray;
+
+    /**
+     * Creates a new OpeningMetadata instance using the specified properties.
+     * @function create
+     * @memberof OpeningMetadata
+     * @static
+     * @param {IOpeningMetadata=} [properties] Properties to set
+     * @returns {OpeningMetadata} OpeningMetadata instance
+     */
+    OpeningMetadata.create = function create(properties) {
+        return new OpeningMetadata(properties);
+    };
+
+    /**
+     * Encodes the specified OpeningMetadata message. Does not implicitly {@link OpeningMetadata.verify|verify} messages.
+     * @function encode
+     * @memberof OpeningMetadata
+     * @static
+     * @param {IOpeningMetadata} message OpeningMetadata message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    OpeningMetadata.encode = function encode(message, writer) {
+        if (!writer)
+            writer = $Writer.create();
+        if (message.shortDescription != null && Object.hasOwnProperty.call(message, "shortDescription"))
+            writer.uint32(/* id 1, wireType 2 =*/10).string(message.shortDescription);
+        if (message.description != null && Object.hasOwnProperty.call(message, "description"))
+            writer.uint32(/* id 2, wireType 2 =*/18).string(message.description);
+        if (message.hiringLimit != null && Object.hasOwnProperty.call(message, "hiringLimit"))
+            writer.uint32(/* id 3, wireType 0 =*/24).uint32(message.hiringLimit);
+        if (message.expectedEndingTimestamp != null && Object.hasOwnProperty.call(message, "expectedEndingTimestamp"))
+            writer.uint32(/* id 4, wireType 0 =*/32).uint32(message.expectedEndingTimestamp);
+        if (message.applicationDetails != null && Object.hasOwnProperty.call(message, "applicationDetails"))
+            writer.uint32(/* id 5, wireType 2 =*/42).string(message.applicationDetails);
+        if (message.applicationFormQuestions != null && message.applicationFormQuestions.length)
+            for (var i = 0; i < message.applicationFormQuestions.length; ++i)
+                $root.OpeningMetadata.ApplicationFormQuestion.encode(message.applicationFormQuestions[i], writer.uint32(/* id 6, wireType 2 =*/50).fork()).ldelim();
+        return writer;
+    };
+
+    /**
+     * Encodes the specified OpeningMetadata message, length delimited. Does not implicitly {@link OpeningMetadata.verify|verify} messages.
+     * @function encodeDelimited
+     * @memberof OpeningMetadata
+     * @static
+     * @param {IOpeningMetadata} message OpeningMetadata message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    OpeningMetadata.encodeDelimited = function encodeDelimited(message, writer) {
+        return this.encode(message, writer).ldelim();
+    };
+
+    /**
+     * Decodes an OpeningMetadata message from the specified reader or buffer.
+     * @function decode
+     * @memberof OpeningMetadata
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @param {number} [length] Message length if known beforehand
+     * @returns {OpeningMetadata} OpeningMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    OpeningMetadata.decode = function decode(reader, length) {
+        if (!(reader instanceof $Reader))
+            reader = $Reader.create(reader);
+        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.OpeningMetadata();
+        while (reader.pos < end) {
+            var tag = reader.uint32();
+            switch (tag >>> 3) {
+            case 1:
+                message.shortDescription = reader.string();
+                break;
+            case 2:
+                message.description = reader.string();
+                break;
+            case 3:
+                message.hiringLimit = reader.uint32();
+                break;
+            case 4:
+                message.expectedEndingTimestamp = reader.uint32();
+                break;
+            case 5:
+                message.applicationDetails = reader.string();
+                break;
+            case 6:
+                if (!(message.applicationFormQuestions && message.applicationFormQuestions.length))
+                    message.applicationFormQuestions = [];
+                message.applicationFormQuestions.push($root.OpeningMetadata.ApplicationFormQuestion.decode(reader, reader.uint32()));
+                break;
+            default:
+                reader.skipType(tag & 7);
+                break;
+            }
+        }
+        return message;
+    };
+
+    /**
+     * Decodes an OpeningMetadata message from the specified reader or buffer, length delimited.
+     * @function decodeDelimited
+     * @memberof OpeningMetadata
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @returns {OpeningMetadata} OpeningMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    OpeningMetadata.decodeDelimited = function decodeDelimited(reader) {
+        if (!(reader instanceof $Reader))
+            reader = new $Reader(reader);
+        return this.decode(reader, reader.uint32());
+    };
+
+    /**
+     * Verifies an OpeningMetadata message.
+     * @function verify
+     * @memberof OpeningMetadata
+     * @static
+     * @param {Object.<string,*>} message Plain object to verify
+     * @returns {string|null} `null` if valid, otherwise the reason why it is not
+     */
+    OpeningMetadata.verify = function verify(message) {
+        if (typeof message !== "object" || message === null)
+            return "object expected";
+        if (message.shortDescription != null && message.hasOwnProperty("shortDescription"))
+            if (!$util.isString(message.shortDescription))
+                return "shortDescription: string expected";
+        if (message.description != null && message.hasOwnProperty("description"))
+            if (!$util.isString(message.description))
+                return "description: string expected";
+        if (message.hiringLimit != null && message.hasOwnProperty("hiringLimit"))
+            if (!$util.isInteger(message.hiringLimit))
+                return "hiringLimit: integer expected";
+        if (message.expectedEndingTimestamp != null && message.hasOwnProperty("expectedEndingTimestamp"))
+            if (!$util.isInteger(message.expectedEndingTimestamp))
+                return "expectedEndingTimestamp: integer expected";
+        if (message.applicationDetails != null && message.hasOwnProperty("applicationDetails"))
+            if (!$util.isString(message.applicationDetails))
+                return "applicationDetails: string expected";
+        if (message.applicationFormQuestions != null && message.hasOwnProperty("applicationFormQuestions")) {
+            if (!Array.isArray(message.applicationFormQuestions))
+                return "applicationFormQuestions: array expected";
+            for (var i = 0; i < message.applicationFormQuestions.length; ++i) {
+                var error = $root.OpeningMetadata.ApplicationFormQuestion.verify(message.applicationFormQuestions[i]);
+                if (error)
+                    return "applicationFormQuestions." + error;
+            }
+        }
+        return null;
+    };
+
+    /**
+     * Creates an OpeningMetadata message from a plain object. Also converts values to their respective internal types.
+     * @function fromObject
+     * @memberof OpeningMetadata
+     * @static
+     * @param {Object.<string,*>} object Plain object
+     * @returns {OpeningMetadata} OpeningMetadata
+     */
+    OpeningMetadata.fromObject = function fromObject(object) {
+        if (object instanceof $root.OpeningMetadata)
+            return object;
+        var message = new $root.OpeningMetadata();
+        if (object.shortDescription != null)
+            message.shortDescription = String(object.shortDescription);
+        if (object.description != null)
+            message.description = String(object.description);
+        if (object.hiringLimit != null)
+            message.hiringLimit = object.hiringLimit >>> 0;
+        if (object.expectedEndingTimestamp != null)
+            message.expectedEndingTimestamp = object.expectedEndingTimestamp >>> 0;
+        if (object.applicationDetails != null)
+            message.applicationDetails = String(object.applicationDetails);
+        if (object.applicationFormQuestions) {
+            if (!Array.isArray(object.applicationFormQuestions))
+                throw TypeError(".OpeningMetadata.applicationFormQuestions: array expected");
+            message.applicationFormQuestions = [];
+            for (var i = 0; i < object.applicationFormQuestions.length; ++i) {
+                if (typeof object.applicationFormQuestions[i] !== "object")
+                    throw TypeError(".OpeningMetadata.applicationFormQuestions: object expected");
+                message.applicationFormQuestions[i] = $root.OpeningMetadata.ApplicationFormQuestion.fromObject(object.applicationFormQuestions[i]);
+            }
+        }
+        return message;
+    };
+
+    /**
+     * Creates a plain object from an OpeningMetadata message. Also converts values to other types if specified.
+     * @function toObject
+     * @memberof OpeningMetadata
+     * @static
+     * @param {OpeningMetadata} message OpeningMetadata
+     * @param {$protobuf.IConversionOptions} [options] Conversion options
+     * @returns {Object.<string,*>} Plain object
+     */
+    OpeningMetadata.toObject = function toObject(message, options) {
+        if (!options)
+            options = {};
+        var object = {};
+        if (options.arrays || options.defaults)
+            object.applicationFormQuestions = [];
+        if (options.defaults) {
+            object.shortDescription = "";
+            object.description = "";
+            object.hiringLimit = 0;
+            object.expectedEndingTimestamp = 0;
+            object.applicationDetails = "";
+        }
+        if (message.shortDescription != null && message.hasOwnProperty("shortDescription"))
+            object.shortDescription = message.shortDescription;
+        if (message.description != null && message.hasOwnProperty("description"))
+            object.description = message.description;
+        if (message.hiringLimit != null && message.hasOwnProperty("hiringLimit"))
+            object.hiringLimit = message.hiringLimit;
+        if (message.expectedEndingTimestamp != null && message.hasOwnProperty("expectedEndingTimestamp"))
+            object.expectedEndingTimestamp = message.expectedEndingTimestamp;
+        if (message.applicationDetails != null && message.hasOwnProperty("applicationDetails"))
+            object.applicationDetails = message.applicationDetails;
+        if (message.applicationFormQuestions && message.applicationFormQuestions.length) {
+            object.applicationFormQuestions = [];
+            for (var j = 0; j < message.applicationFormQuestions.length; ++j)
+                object.applicationFormQuestions[j] = $root.OpeningMetadata.ApplicationFormQuestion.toObject(message.applicationFormQuestions[j], options);
+        }
+        return object;
+    };
+
+    /**
+     * Converts this OpeningMetadata to JSON.
+     * @function toJSON
+     * @memberof OpeningMetadata
+     * @instance
+     * @returns {Object.<string,*>} JSON object
+     */
+    OpeningMetadata.prototype.toJSON = function toJSON() {
+        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
+    };
+
+    OpeningMetadata.ApplicationFormQuestion = (function() {
+
+        /**
+         * Properties of an ApplicationFormQuestion.
+         * @memberof OpeningMetadata
+         * @interface IApplicationFormQuestion
+         * @property {string|null} [question] ApplicationFormQuestion question
+         * @property {OpeningMetadata.ApplicationFormQuestion.InputType|null} [type] ApplicationFormQuestion type
+         */
+
+        /**
+         * Constructs a new ApplicationFormQuestion.
+         * @memberof OpeningMetadata
+         * @classdesc Represents an ApplicationFormQuestion.
+         * @implements IApplicationFormQuestion
+         * @constructor
+         * @param {OpeningMetadata.IApplicationFormQuestion=} [properties] Properties to set
+         */
+        function ApplicationFormQuestion(properties) {
+            if (properties)
+                for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                    if (properties[keys[i]] != null)
+                        this[keys[i]] = properties[keys[i]];
+        }
+
+        /**
+         * ApplicationFormQuestion question.
+         * @member {string} question
+         * @memberof OpeningMetadata.ApplicationFormQuestion
+         * @instance
+         */
+        ApplicationFormQuestion.prototype.question = "";
+
+        /**
+         * ApplicationFormQuestion type.
+         * @member {OpeningMetadata.ApplicationFormQuestion.InputType} type
+         * @memberof OpeningMetadata.ApplicationFormQuestion
+         * @instance
+         */
+        ApplicationFormQuestion.prototype.type = 0;
+
+        /**
+         * Creates a new ApplicationFormQuestion instance using the specified properties.
+         * @function create
+         * @memberof OpeningMetadata.ApplicationFormQuestion
+         * @static
+         * @param {OpeningMetadata.IApplicationFormQuestion=} [properties] Properties to set
+         * @returns {OpeningMetadata.ApplicationFormQuestion} ApplicationFormQuestion instance
+         */
+        ApplicationFormQuestion.create = function create(properties) {
+            return new ApplicationFormQuestion(properties);
+        };
+
+        /**
+         * Encodes the specified ApplicationFormQuestion message. Does not implicitly {@link OpeningMetadata.ApplicationFormQuestion.verify|verify} messages.
+         * @function encode
+         * @memberof OpeningMetadata.ApplicationFormQuestion
+         * @static
+         * @param {OpeningMetadata.IApplicationFormQuestion} message ApplicationFormQuestion message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        ApplicationFormQuestion.encode = function encode(message, writer) {
+            if (!writer)
+                writer = $Writer.create();
+            if (message.question != null && Object.hasOwnProperty.call(message, "question"))
+                writer.uint32(/* id 1, wireType 2 =*/10).string(message.question);
+            if (message.type != null && Object.hasOwnProperty.call(message, "type"))
+                writer.uint32(/* id 2, wireType 0 =*/16).int32(message.type);
+            return writer;
+        };
+
+        /**
+         * Encodes the specified ApplicationFormQuestion message, length delimited. Does not implicitly {@link OpeningMetadata.ApplicationFormQuestion.verify|verify} messages.
+         * @function encodeDelimited
+         * @memberof OpeningMetadata.ApplicationFormQuestion
+         * @static
+         * @param {OpeningMetadata.IApplicationFormQuestion} message ApplicationFormQuestion message or plain object to encode
+         * @param {$protobuf.Writer} [writer] Writer to encode to
+         * @returns {$protobuf.Writer} Writer
+         */
+        ApplicationFormQuestion.encodeDelimited = function encodeDelimited(message, writer) {
+            return this.encode(message, writer).ldelim();
+        };
+
+        /**
+         * Decodes an ApplicationFormQuestion message from the specified reader or buffer.
+         * @function decode
+         * @memberof OpeningMetadata.ApplicationFormQuestion
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @param {number} [length] Message length if known beforehand
+         * @returns {OpeningMetadata.ApplicationFormQuestion} ApplicationFormQuestion
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        ApplicationFormQuestion.decode = function decode(reader, length) {
+            if (!(reader instanceof $Reader))
+                reader = $Reader.create(reader);
+            var end = length === undefined ? reader.len : reader.pos + length, message = new $root.OpeningMetadata.ApplicationFormQuestion();
+            while (reader.pos < end) {
+                var tag = reader.uint32();
+                switch (tag >>> 3) {
+                case 1:
+                    message.question = reader.string();
+                    break;
+                case 2:
+                    message.type = reader.int32();
+                    break;
+                default:
+                    reader.skipType(tag & 7);
+                    break;
+                }
+            }
+            return message;
+        };
+
+        /**
+         * Decodes an ApplicationFormQuestion message from the specified reader or buffer, length delimited.
+         * @function decodeDelimited
+         * @memberof OpeningMetadata.ApplicationFormQuestion
+         * @static
+         * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+         * @returns {OpeningMetadata.ApplicationFormQuestion} ApplicationFormQuestion
+         * @throws {Error} If the payload is not a reader or valid buffer
+         * @throws {$protobuf.util.ProtocolError} If required fields are missing
+         */
+        ApplicationFormQuestion.decodeDelimited = function decodeDelimited(reader) {
+            if (!(reader instanceof $Reader))
+                reader = new $Reader(reader);
+            return this.decode(reader, reader.uint32());
+        };
+
+        /**
+         * Verifies an ApplicationFormQuestion message.
+         * @function verify
+         * @memberof OpeningMetadata.ApplicationFormQuestion
+         * @static
+         * @param {Object.<string,*>} message Plain object to verify
+         * @returns {string|null} `null` if valid, otherwise the reason why it is not
+         */
+        ApplicationFormQuestion.verify = function verify(message) {
+            if (typeof message !== "object" || message === null)
+                return "object expected";
+            if (message.question != null && message.hasOwnProperty("question"))
+                if (!$util.isString(message.question))
+                    return "question: string expected";
+            if (message.type != null && message.hasOwnProperty("type"))
+                switch (message.type) {
+                default:
+                    return "type: enum value expected";
+                case 0:
+                case 1:
+                    break;
+                }
+            return null;
+        };
+
+        /**
+         * Creates an ApplicationFormQuestion message from a plain object. Also converts values to their respective internal types.
+         * @function fromObject
+         * @memberof OpeningMetadata.ApplicationFormQuestion
+         * @static
+         * @param {Object.<string,*>} object Plain object
+         * @returns {OpeningMetadata.ApplicationFormQuestion} ApplicationFormQuestion
+         */
+        ApplicationFormQuestion.fromObject = function fromObject(object) {
+            if (object instanceof $root.OpeningMetadata.ApplicationFormQuestion)
+                return object;
+            var message = new $root.OpeningMetadata.ApplicationFormQuestion();
+            if (object.question != null)
+                message.question = String(object.question);
+            switch (object.type) {
+            case "TEXTAREA":
+            case 0:
+                message.type = 0;
+                break;
+            case "TEXT":
+            case 1:
+                message.type = 1;
+                break;
+            }
+            return message;
+        };
+
+        /**
+         * Creates a plain object from an ApplicationFormQuestion message. Also converts values to other types if specified.
+         * @function toObject
+         * @memberof OpeningMetadata.ApplicationFormQuestion
+         * @static
+         * @param {OpeningMetadata.ApplicationFormQuestion} message ApplicationFormQuestion
+         * @param {$protobuf.IConversionOptions} [options] Conversion options
+         * @returns {Object.<string,*>} Plain object
+         */
+        ApplicationFormQuestion.toObject = function toObject(message, options) {
+            if (!options)
+                options = {};
+            var object = {};
+            if (options.defaults) {
+                object.question = "";
+                object.type = options.enums === String ? "TEXTAREA" : 0;
+            }
+            if (message.question != null && message.hasOwnProperty("question"))
+                object.question = message.question;
+            if (message.type != null && message.hasOwnProperty("type"))
+                object.type = options.enums === String ? $root.OpeningMetadata.ApplicationFormQuestion.InputType[message.type] : message.type;
+            return object;
+        };
+
+        /**
+         * Converts this ApplicationFormQuestion to JSON.
+         * @function toJSON
+         * @memberof OpeningMetadata.ApplicationFormQuestion
+         * @instance
+         * @returns {Object.<string,*>} JSON object
+         */
+        ApplicationFormQuestion.prototype.toJSON = function toJSON() {
+            return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
+        };
+
+        /**
+         * InputType enum.
+         * @name OpeningMetadata.ApplicationFormQuestion.InputType
+         * @enum {number}
+         * @property {number} TEXTAREA=0 TEXTAREA value
+         * @property {number} TEXT=1 TEXT value
+         */
+        ApplicationFormQuestion.InputType = (function() {
+            var valuesById = {}, values = Object.create(valuesById);
+            values[valuesById[0] = "TEXTAREA"] = 0;
+            values[valuesById[1] = "TEXT"] = 1;
+            return values;
+        })();
+
+        return ApplicationFormQuestion;
+    })();
+
+    return OpeningMetadata;
+})();
+
+$root.UpcomingOpeningMetadata = (function() {
+
+    /**
+     * Properties of an UpcomingOpeningMetadata.
+     * @exports IUpcomingOpeningMetadata
+     * @interface IUpcomingOpeningMetadata
+     * @property {number|null} [expectedStart] UpcomingOpeningMetadata expectedStart
+     * @property {Long|null} [rewardPerBlock] UpcomingOpeningMetadata rewardPerBlock
+     * @property {Long|null} [minApplicationStake] UpcomingOpeningMetadata minApplicationStake
+     * @property {IOpeningMetadata|null} [metadata] UpcomingOpeningMetadata metadata
+     */
+
+    /**
+     * Constructs a new UpcomingOpeningMetadata.
+     * @exports UpcomingOpeningMetadata
+     * @classdesc Represents an UpcomingOpeningMetadata.
+     * @implements IUpcomingOpeningMetadata
+     * @constructor
+     * @param {IUpcomingOpeningMetadata=} [properties] Properties to set
+     */
+    function UpcomingOpeningMetadata(properties) {
+        if (properties)
+            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                if (properties[keys[i]] != null)
+                    this[keys[i]] = properties[keys[i]];
+    }
+
+    /**
+     * UpcomingOpeningMetadata expectedStart.
+     * @member {number} expectedStart
+     * @memberof UpcomingOpeningMetadata
+     * @instance
+     */
+    UpcomingOpeningMetadata.prototype.expectedStart = 0;
+
+    /**
+     * UpcomingOpeningMetadata rewardPerBlock.
+     * @member {Long} rewardPerBlock
+     * @memberof UpcomingOpeningMetadata
+     * @instance
+     */
+    UpcomingOpeningMetadata.prototype.rewardPerBlock = $util.Long ? $util.Long.fromBits(0,0,true) : 0;
+
+    /**
+     * UpcomingOpeningMetadata minApplicationStake.
+     * @member {Long} minApplicationStake
+     * @memberof UpcomingOpeningMetadata
+     * @instance
+     */
+    UpcomingOpeningMetadata.prototype.minApplicationStake = $util.Long ? $util.Long.fromBits(0,0,true) : 0;
+
+    /**
+     * UpcomingOpeningMetadata metadata.
+     * @member {IOpeningMetadata|null|undefined} metadata
+     * @memberof UpcomingOpeningMetadata
+     * @instance
+     */
+    UpcomingOpeningMetadata.prototype.metadata = null;
+
+    /**
+     * Creates a new UpcomingOpeningMetadata instance using the specified properties.
+     * @function create
+     * @memberof UpcomingOpeningMetadata
+     * @static
+     * @param {IUpcomingOpeningMetadata=} [properties] Properties to set
+     * @returns {UpcomingOpeningMetadata} UpcomingOpeningMetadata instance
+     */
+    UpcomingOpeningMetadata.create = function create(properties) {
+        return new UpcomingOpeningMetadata(properties);
+    };
+
+    /**
+     * Encodes the specified UpcomingOpeningMetadata message. Does not implicitly {@link UpcomingOpeningMetadata.verify|verify} messages.
+     * @function encode
+     * @memberof UpcomingOpeningMetadata
+     * @static
+     * @param {IUpcomingOpeningMetadata} message UpcomingOpeningMetadata message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    UpcomingOpeningMetadata.encode = function encode(message, writer) {
+        if (!writer)
+            writer = $Writer.create();
+        if (message.expectedStart != null && Object.hasOwnProperty.call(message, "expectedStart"))
+            writer.uint32(/* id 1, wireType 0 =*/8).uint32(message.expectedStart);
+        if (message.rewardPerBlock != null && Object.hasOwnProperty.call(message, "rewardPerBlock"))
+            writer.uint32(/* id 2, wireType 0 =*/16).uint64(message.rewardPerBlock);
+        if (message.minApplicationStake != null && Object.hasOwnProperty.call(message, "minApplicationStake"))
+            writer.uint32(/* id 3, wireType 0 =*/24).uint64(message.minApplicationStake);
+        if (message.metadata != null && Object.hasOwnProperty.call(message, "metadata"))
+            $root.OpeningMetadata.encode(message.metadata, writer.uint32(/* id 4, wireType 2 =*/34).fork()).ldelim();
+        return writer;
+    };
+
+    /**
+     * Encodes the specified UpcomingOpeningMetadata message, length delimited. Does not implicitly {@link UpcomingOpeningMetadata.verify|verify} messages.
+     * @function encodeDelimited
+     * @memberof UpcomingOpeningMetadata
+     * @static
+     * @param {IUpcomingOpeningMetadata} message UpcomingOpeningMetadata message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    UpcomingOpeningMetadata.encodeDelimited = function encodeDelimited(message, writer) {
+        return this.encode(message, writer).ldelim();
+    };
+
+    /**
+     * Decodes an UpcomingOpeningMetadata message from the specified reader or buffer.
+     * @function decode
+     * @memberof UpcomingOpeningMetadata
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @param {number} [length] Message length if known beforehand
+     * @returns {UpcomingOpeningMetadata} UpcomingOpeningMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    UpcomingOpeningMetadata.decode = function decode(reader, length) {
+        if (!(reader instanceof $Reader))
+            reader = $Reader.create(reader);
+        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.UpcomingOpeningMetadata();
+        while (reader.pos < end) {
+            var tag = reader.uint32();
+            switch (tag >>> 3) {
+            case 1:
+                message.expectedStart = reader.uint32();
+                break;
+            case 2:
+                message.rewardPerBlock = reader.uint64();
+                break;
+            case 3:
+                message.minApplicationStake = reader.uint64();
+                break;
+            case 4:
+                message.metadata = $root.OpeningMetadata.decode(reader, reader.uint32());
+                break;
+            default:
+                reader.skipType(tag & 7);
+                break;
+            }
+        }
+        return message;
+    };
+
+    /**
+     * Decodes an UpcomingOpeningMetadata message from the specified reader or buffer, length delimited.
+     * @function decodeDelimited
+     * @memberof UpcomingOpeningMetadata
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @returns {UpcomingOpeningMetadata} UpcomingOpeningMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    UpcomingOpeningMetadata.decodeDelimited = function decodeDelimited(reader) {
+        if (!(reader instanceof $Reader))
+            reader = new $Reader(reader);
+        return this.decode(reader, reader.uint32());
+    };
+
+    /**
+     * Verifies an UpcomingOpeningMetadata message.
+     * @function verify
+     * @memberof UpcomingOpeningMetadata
+     * @static
+     * @param {Object.<string,*>} message Plain object to verify
+     * @returns {string|null} `null` if valid, otherwise the reason why it is not
+     */
+    UpcomingOpeningMetadata.verify = function verify(message) {
+        if (typeof message !== "object" || message === null)
+            return "object expected";
+        if (message.expectedStart != null && message.hasOwnProperty("expectedStart"))
+            if (!$util.isInteger(message.expectedStart))
+                return "expectedStart: integer expected";
+        if (message.rewardPerBlock != null && message.hasOwnProperty("rewardPerBlock"))
+            if (!$util.isInteger(message.rewardPerBlock) && !(message.rewardPerBlock && $util.isInteger(message.rewardPerBlock.low) && $util.isInteger(message.rewardPerBlock.high)))
+                return "rewardPerBlock: integer|Long expected";
+        if (message.minApplicationStake != null && message.hasOwnProperty("minApplicationStake"))
+            if (!$util.isInteger(message.minApplicationStake) && !(message.minApplicationStake && $util.isInteger(message.minApplicationStake.low) && $util.isInteger(message.minApplicationStake.high)))
+                return "minApplicationStake: integer|Long expected";
+        if (message.metadata != null && message.hasOwnProperty("metadata")) {
+            var error = $root.OpeningMetadata.verify(message.metadata);
+            if (error)
+                return "metadata." + error;
+        }
+        return null;
+    };
+
+    /**
+     * Creates an UpcomingOpeningMetadata message from a plain object. Also converts values to their respective internal types.
+     * @function fromObject
+     * @memberof UpcomingOpeningMetadata
+     * @static
+     * @param {Object.<string,*>} object Plain object
+     * @returns {UpcomingOpeningMetadata} UpcomingOpeningMetadata
+     */
+    UpcomingOpeningMetadata.fromObject = function fromObject(object) {
+        if (object instanceof $root.UpcomingOpeningMetadata)
+            return object;
+        var message = new $root.UpcomingOpeningMetadata();
+        if (object.expectedStart != null)
+            message.expectedStart = object.expectedStart >>> 0;
+        if (object.rewardPerBlock != null)
+            if ($util.Long)
+                (message.rewardPerBlock = $util.Long.fromValue(object.rewardPerBlock)).unsigned = true;
+            else if (typeof object.rewardPerBlock === "string")
+                message.rewardPerBlock = parseInt(object.rewardPerBlock, 10);
+            else if (typeof object.rewardPerBlock === "number")
+                message.rewardPerBlock = object.rewardPerBlock;
+            else if (typeof object.rewardPerBlock === "object")
+                message.rewardPerBlock = new $util.LongBits(object.rewardPerBlock.low >>> 0, object.rewardPerBlock.high >>> 0).toNumber(true);
+        if (object.minApplicationStake != null)
+            if ($util.Long)
+                (message.minApplicationStake = $util.Long.fromValue(object.minApplicationStake)).unsigned = true;
+            else if (typeof object.minApplicationStake === "string")
+                message.minApplicationStake = parseInt(object.minApplicationStake, 10);
+            else if (typeof object.minApplicationStake === "number")
+                message.minApplicationStake = object.minApplicationStake;
+            else if (typeof object.minApplicationStake === "object")
+                message.minApplicationStake = new $util.LongBits(object.minApplicationStake.low >>> 0, object.minApplicationStake.high >>> 0).toNumber(true);
+        if (object.metadata != null) {
+            if (typeof object.metadata !== "object")
+                throw TypeError(".UpcomingOpeningMetadata.metadata: object expected");
+            message.metadata = $root.OpeningMetadata.fromObject(object.metadata);
+        }
+        return message;
+    };
+
+    /**
+     * Creates a plain object from an UpcomingOpeningMetadata message. Also converts values to other types if specified.
+     * @function toObject
+     * @memberof UpcomingOpeningMetadata
+     * @static
+     * @param {UpcomingOpeningMetadata} message UpcomingOpeningMetadata
+     * @param {$protobuf.IConversionOptions} [options] Conversion options
+     * @returns {Object.<string,*>} Plain object
+     */
+    UpcomingOpeningMetadata.toObject = function toObject(message, options) {
+        if (!options)
+            options = {};
+        var object = {};
+        if (options.defaults) {
+            object.expectedStart = 0;
+            if ($util.Long) {
+                var long = new $util.Long(0, 0, true);
+                object.rewardPerBlock = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
+            } else
+                object.rewardPerBlock = options.longs === String ? "0" : 0;
+            if ($util.Long) {
+                var long = new $util.Long(0, 0, true);
+                object.minApplicationStake = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;
+            } else
+                object.minApplicationStake = options.longs === String ? "0" : 0;
+            object.metadata = null;
+        }
+        if (message.expectedStart != null && message.hasOwnProperty("expectedStart"))
+            object.expectedStart = message.expectedStart;
+        if (message.rewardPerBlock != null && message.hasOwnProperty("rewardPerBlock"))
+            if (typeof message.rewardPerBlock === "number")
+                object.rewardPerBlock = options.longs === String ? String(message.rewardPerBlock) : message.rewardPerBlock;
+            else
+                object.rewardPerBlock = options.longs === String ? $util.Long.prototype.toString.call(message.rewardPerBlock) : options.longs === Number ? new $util.LongBits(message.rewardPerBlock.low >>> 0, message.rewardPerBlock.high >>> 0).toNumber(true) : message.rewardPerBlock;
+        if (message.minApplicationStake != null && message.hasOwnProperty("minApplicationStake"))
+            if (typeof message.minApplicationStake === "number")
+                object.minApplicationStake = options.longs === String ? String(message.minApplicationStake) : message.minApplicationStake;
+            else
+                object.minApplicationStake = options.longs === String ? $util.Long.prototype.toString.call(message.minApplicationStake) : options.longs === Number ? new $util.LongBits(message.minApplicationStake.low >>> 0, message.minApplicationStake.high >>> 0).toNumber(true) : message.minApplicationStake;
+        if (message.metadata != null && message.hasOwnProperty("metadata"))
+            object.metadata = $root.OpeningMetadata.toObject(message.metadata, options);
+        return object;
+    };
+
+    /**
+     * Converts this UpcomingOpeningMetadata to JSON.
+     * @function toJSON
+     * @memberof UpcomingOpeningMetadata
+     * @instance
+     * @returns {Object.<string,*>} JSON object
+     */
+    UpcomingOpeningMetadata.prototype.toJSON = function toJSON() {
+        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
+    };
+
+    return UpcomingOpeningMetadata;
+})();
+
+$root.ApplicationMetadata = (function() {
+
+    /**
+     * Properties of an ApplicationMetadata.
+     * @exports IApplicationMetadata
+     * @interface IApplicationMetadata
+     * @property {Array.<string>|null} [answers] ApplicationMetadata answers
+     */
+
+    /**
+     * Constructs a new ApplicationMetadata.
+     * @exports ApplicationMetadata
+     * @classdesc Represents an ApplicationMetadata.
+     * @implements IApplicationMetadata
+     * @constructor
+     * @param {IApplicationMetadata=} [properties] Properties to set
+     */
+    function ApplicationMetadata(properties) {
+        this.answers = [];
+        if (properties)
+            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                if (properties[keys[i]] != null)
+                    this[keys[i]] = properties[keys[i]];
+    }
+
+    /**
+     * ApplicationMetadata answers.
+     * @member {Array.<string>} answers
+     * @memberof ApplicationMetadata
+     * @instance
+     */
+    ApplicationMetadata.prototype.answers = $util.emptyArray;
+
+    /**
+     * Creates a new ApplicationMetadata instance using the specified properties.
+     * @function create
+     * @memberof ApplicationMetadata
+     * @static
+     * @param {IApplicationMetadata=} [properties] Properties to set
+     * @returns {ApplicationMetadata} ApplicationMetadata instance
+     */
+    ApplicationMetadata.create = function create(properties) {
+        return new ApplicationMetadata(properties);
+    };
+
+    /**
+     * Encodes the specified ApplicationMetadata message. Does not implicitly {@link ApplicationMetadata.verify|verify} messages.
+     * @function encode
+     * @memberof ApplicationMetadata
+     * @static
+     * @param {IApplicationMetadata} message ApplicationMetadata message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    ApplicationMetadata.encode = function encode(message, writer) {
+        if (!writer)
+            writer = $Writer.create();
+        if (message.answers != null && message.answers.length)
+            for (var i = 0; i < message.answers.length; ++i)
+                writer.uint32(/* id 1, wireType 2 =*/10).string(message.answers[i]);
+        return writer;
+    };
+
+    /**
+     * Encodes the specified ApplicationMetadata message, length delimited. Does not implicitly {@link ApplicationMetadata.verify|verify} messages.
+     * @function encodeDelimited
+     * @memberof ApplicationMetadata
+     * @static
+     * @param {IApplicationMetadata} message ApplicationMetadata message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    ApplicationMetadata.encodeDelimited = function encodeDelimited(message, writer) {
+        return this.encode(message, writer).ldelim();
+    };
+
+    /**
+     * Decodes an ApplicationMetadata message from the specified reader or buffer.
+     * @function decode
+     * @memberof ApplicationMetadata
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @param {number} [length] Message length if known beforehand
+     * @returns {ApplicationMetadata} ApplicationMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    ApplicationMetadata.decode = function decode(reader, length) {
+        if (!(reader instanceof $Reader))
+            reader = $Reader.create(reader);
+        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.ApplicationMetadata();
+        while (reader.pos < end) {
+            var tag = reader.uint32();
+            switch (tag >>> 3) {
+            case 1:
+                if (!(message.answers && message.answers.length))
+                    message.answers = [];
+                message.answers.push(reader.string());
+                break;
+            default:
+                reader.skipType(tag & 7);
+                break;
+            }
+        }
+        return message;
+    };
+
+    /**
+     * Decodes an ApplicationMetadata message from the specified reader or buffer, length delimited.
+     * @function decodeDelimited
+     * @memberof ApplicationMetadata
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @returns {ApplicationMetadata} ApplicationMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    ApplicationMetadata.decodeDelimited = function decodeDelimited(reader) {
+        if (!(reader instanceof $Reader))
+            reader = new $Reader(reader);
+        return this.decode(reader, reader.uint32());
+    };
+
+    /**
+     * Verifies an ApplicationMetadata message.
+     * @function verify
+     * @memberof ApplicationMetadata
+     * @static
+     * @param {Object.<string,*>} message Plain object to verify
+     * @returns {string|null} `null` if valid, otherwise the reason why it is not
+     */
+    ApplicationMetadata.verify = function verify(message) {
+        if (typeof message !== "object" || message === null)
+            return "object expected";
+        if (message.answers != null && message.hasOwnProperty("answers")) {
+            if (!Array.isArray(message.answers))
+                return "answers: array expected";
+            for (var i = 0; i < message.answers.length; ++i)
+                if (!$util.isString(message.answers[i]))
+                    return "answers: string[] expected";
+        }
+        return null;
+    };
+
+    /**
+     * Creates an ApplicationMetadata message from a plain object. Also converts values to their respective internal types.
+     * @function fromObject
+     * @memberof ApplicationMetadata
+     * @static
+     * @param {Object.<string,*>} object Plain object
+     * @returns {ApplicationMetadata} ApplicationMetadata
+     */
+    ApplicationMetadata.fromObject = function fromObject(object) {
+        if (object instanceof $root.ApplicationMetadata)
+            return object;
+        var message = new $root.ApplicationMetadata();
+        if (object.answers) {
+            if (!Array.isArray(object.answers))
+                throw TypeError(".ApplicationMetadata.answers: array expected");
+            message.answers = [];
+            for (var i = 0; i < object.answers.length; ++i)
+                message.answers[i] = String(object.answers[i]);
+        }
+        return message;
+    };
+
+    /**
+     * Creates a plain object from an ApplicationMetadata message. Also converts values to other types if specified.
+     * @function toObject
+     * @memberof ApplicationMetadata
+     * @static
+     * @param {ApplicationMetadata} message ApplicationMetadata
+     * @param {$protobuf.IConversionOptions} [options] Conversion options
+     * @returns {Object.<string,*>} Plain object
+     */
+    ApplicationMetadata.toObject = function toObject(message, options) {
+        if (!options)
+            options = {};
+        var object = {};
+        if (options.arrays || options.defaults)
+            object.answers = [];
+        if (message.answers && message.answers.length) {
+            object.answers = [];
+            for (var j = 0; j < message.answers.length; ++j)
+                object.answers[j] = message.answers[j];
+        }
+        return object;
+    };
+
+    /**
+     * Converts this ApplicationMetadata to JSON.
+     * @function toJSON
+     * @memberof ApplicationMetadata
+     * @instance
+     * @returns {Object.<string,*>} JSON object
+     */
+    ApplicationMetadata.prototype.toJSON = function toJSON() {
+        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
+    };
+
+    return ApplicationMetadata;
+})();
+
+$root.WorkingGroupMetadata = (function() {
+
+    /**
+     * Properties of a WorkingGroupMetadata.
+     * @exports IWorkingGroupMetadata
+     * @interface IWorkingGroupMetadata
+     * @property {string|null} [description] WorkingGroupMetadata description
+     * @property {string|null} [about] WorkingGroupMetadata about
+     * @property {string|null} [status] WorkingGroupMetadata status
+     * @property {string|null} [statusMessage] WorkingGroupMetadata statusMessage
+     */
+
+    /**
+     * Constructs a new WorkingGroupMetadata.
+     * @exports WorkingGroupMetadata
+     * @classdesc Represents a WorkingGroupMetadata.
+     * @implements IWorkingGroupMetadata
+     * @constructor
+     * @param {IWorkingGroupMetadata=} [properties] Properties to set
+     */
+    function WorkingGroupMetadata(properties) {
+        if (properties)
+            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                if (properties[keys[i]] != null)
+                    this[keys[i]] = properties[keys[i]];
+    }
+
+    /**
+     * WorkingGroupMetadata description.
+     * @member {string} description
+     * @memberof WorkingGroupMetadata
+     * @instance
+     */
+    WorkingGroupMetadata.prototype.description = "";
+
+    /**
+     * WorkingGroupMetadata about.
+     * @member {string} about
+     * @memberof WorkingGroupMetadata
+     * @instance
+     */
+    WorkingGroupMetadata.prototype.about = "";
+
+    /**
+     * WorkingGroupMetadata status.
+     * @member {string} status
+     * @memberof WorkingGroupMetadata
+     * @instance
+     */
+    WorkingGroupMetadata.prototype.status = "";
+
+    /**
+     * WorkingGroupMetadata statusMessage.
+     * @member {string} statusMessage
+     * @memberof WorkingGroupMetadata
+     * @instance
+     */
+    WorkingGroupMetadata.prototype.statusMessage = "";
+
+    /**
+     * Creates a new WorkingGroupMetadata instance using the specified properties.
+     * @function create
+     * @memberof WorkingGroupMetadata
+     * @static
+     * @param {IWorkingGroupMetadata=} [properties] Properties to set
+     * @returns {WorkingGroupMetadata} WorkingGroupMetadata instance
+     */
+    WorkingGroupMetadata.create = function create(properties) {
+        return new WorkingGroupMetadata(properties);
+    };
+
+    /**
+     * Encodes the specified WorkingGroupMetadata message. Does not implicitly {@link WorkingGroupMetadata.verify|verify} messages.
+     * @function encode
+     * @memberof WorkingGroupMetadata
+     * @static
+     * @param {IWorkingGroupMetadata} message WorkingGroupMetadata message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    WorkingGroupMetadata.encode = function encode(message, writer) {
+        if (!writer)
+            writer = $Writer.create();
+        if (message.description != null && Object.hasOwnProperty.call(message, "description"))
+            writer.uint32(/* id 1, wireType 2 =*/10).string(message.description);
+        if (message.about != null && Object.hasOwnProperty.call(message, "about"))
+            writer.uint32(/* id 2, wireType 2 =*/18).string(message.about);
+        if (message.status != null && Object.hasOwnProperty.call(message, "status"))
+            writer.uint32(/* id 3, wireType 2 =*/26).string(message.status);
+        if (message.statusMessage != null && Object.hasOwnProperty.call(message, "statusMessage"))
+            writer.uint32(/* id 4, wireType 2 =*/34).string(message.statusMessage);
+        return writer;
+    };
+
+    /**
+     * Encodes the specified WorkingGroupMetadata message, length delimited. Does not implicitly {@link WorkingGroupMetadata.verify|verify} messages.
+     * @function encodeDelimited
+     * @memberof WorkingGroupMetadata
+     * @static
+     * @param {IWorkingGroupMetadata} message WorkingGroupMetadata message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    WorkingGroupMetadata.encodeDelimited = function encodeDelimited(message, writer) {
+        return this.encode(message, writer).ldelim();
+    };
+
+    /**
+     * Decodes a WorkingGroupMetadata message from the specified reader or buffer.
+     * @function decode
+     * @memberof WorkingGroupMetadata
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @param {number} [length] Message length if known beforehand
+     * @returns {WorkingGroupMetadata} WorkingGroupMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    WorkingGroupMetadata.decode = function decode(reader, length) {
+        if (!(reader instanceof $Reader))
+            reader = $Reader.create(reader);
+        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.WorkingGroupMetadata();
+        while (reader.pos < end) {
+            var tag = reader.uint32();
+            switch (tag >>> 3) {
+            case 1:
+                message.description = reader.string();
+                break;
+            case 2:
+                message.about = reader.string();
+                break;
+            case 3:
+                message.status = reader.string();
+                break;
+            case 4:
+                message.statusMessage = reader.string();
+                break;
+            default:
+                reader.skipType(tag & 7);
+                break;
+            }
+        }
+        return message;
+    };
+
+    /**
+     * Decodes a WorkingGroupMetadata message from the specified reader or buffer, length delimited.
+     * @function decodeDelimited
+     * @memberof WorkingGroupMetadata
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @returns {WorkingGroupMetadata} WorkingGroupMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    WorkingGroupMetadata.decodeDelimited = function decodeDelimited(reader) {
+        if (!(reader instanceof $Reader))
+            reader = new $Reader(reader);
+        return this.decode(reader, reader.uint32());
+    };
+
+    /**
+     * Verifies a WorkingGroupMetadata message.
+     * @function verify
+     * @memberof WorkingGroupMetadata
+     * @static
+     * @param {Object.<string,*>} message Plain object to verify
+     * @returns {string|null} `null` if valid, otherwise the reason why it is not
+     */
+    WorkingGroupMetadata.verify = function verify(message) {
+        if (typeof message !== "object" || message === null)
+            return "object expected";
+        if (message.description != null && message.hasOwnProperty("description"))
+            if (!$util.isString(message.description))
+                return "description: string expected";
+        if (message.about != null && message.hasOwnProperty("about"))
+            if (!$util.isString(message.about))
+                return "about: string expected";
+        if (message.status != null && message.hasOwnProperty("status"))
+            if (!$util.isString(message.status))
+                return "status: string expected";
+        if (message.statusMessage != null && message.hasOwnProperty("statusMessage"))
+            if (!$util.isString(message.statusMessage))
+                return "statusMessage: string expected";
+        return null;
+    };
+
+    /**
+     * Creates a WorkingGroupMetadata message from a plain object. Also converts values to their respective internal types.
+     * @function fromObject
+     * @memberof WorkingGroupMetadata
+     * @static
+     * @param {Object.<string,*>} object Plain object
+     * @returns {WorkingGroupMetadata} WorkingGroupMetadata
+     */
+    WorkingGroupMetadata.fromObject = function fromObject(object) {
+        if (object instanceof $root.WorkingGroupMetadata)
+            return object;
+        var message = new $root.WorkingGroupMetadata();
+        if (object.description != null)
+            message.description = String(object.description);
+        if (object.about != null)
+            message.about = String(object.about);
+        if (object.status != null)
+            message.status = String(object.status);
+        if (object.statusMessage != null)
+            message.statusMessage = String(object.statusMessage);
+        return message;
+    };
+
+    /**
+     * Creates a plain object from a WorkingGroupMetadata message. Also converts values to other types if specified.
+     * @function toObject
+     * @memberof WorkingGroupMetadata
+     * @static
+     * @param {WorkingGroupMetadata} message WorkingGroupMetadata
+     * @param {$protobuf.IConversionOptions} [options] Conversion options
+     * @returns {Object.<string,*>} Plain object
+     */
+    WorkingGroupMetadata.toObject = function toObject(message, options) {
+        if (!options)
+            options = {};
+        var object = {};
+        if (options.defaults) {
+            object.description = "";
+            object.about = "";
+            object.status = "";
+            object.statusMessage = "";
+        }
+        if (message.description != null && message.hasOwnProperty("description"))
+            object.description = message.description;
+        if (message.about != null && message.hasOwnProperty("about"))
+            object.about = message.about;
+        if (message.status != null && message.hasOwnProperty("status"))
+            object.status = message.status;
+        if (message.statusMessage != null && message.hasOwnProperty("statusMessage"))
+            object.statusMessage = message.statusMessage;
+        return object;
+    };
+
+    /**
+     * Converts this WorkingGroupMetadata to JSON.
+     * @function toJSON
+     * @memberof WorkingGroupMetadata
+     * @instance
+     * @returns {Object.<string,*>} JSON object
+     */
+    WorkingGroupMetadata.prototype.toJSON = function toJSON() {
+        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
+    };
+
+    return WorkingGroupMetadata;
+})();
+
+$root.SetGroupMetadata = (function() {
+
+    /**
+     * Properties of a SetGroupMetadata.
+     * @exports ISetGroupMetadata
+     * @interface ISetGroupMetadata
+     * @property {IWorkingGroupMetadata|null} [newMetadata] SetGroupMetadata newMetadata
+     */
+
+    /**
+     * Constructs a new SetGroupMetadata.
+     * @exports SetGroupMetadata
+     * @classdesc Represents a SetGroupMetadata.
+     * @implements ISetGroupMetadata
+     * @constructor
+     * @param {ISetGroupMetadata=} [properties] Properties to set
+     */
+    function SetGroupMetadata(properties) {
+        if (properties)
+            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                if (properties[keys[i]] != null)
+                    this[keys[i]] = properties[keys[i]];
+    }
+
+    /**
+     * SetGroupMetadata newMetadata.
+     * @member {IWorkingGroupMetadata|null|undefined} newMetadata
+     * @memberof SetGroupMetadata
+     * @instance
+     */
+    SetGroupMetadata.prototype.newMetadata = null;
+
+    /**
+     * Creates a new SetGroupMetadata instance using the specified properties.
+     * @function create
+     * @memberof SetGroupMetadata
+     * @static
+     * @param {ISetGroupMetadata=} [properties] Properties to set
+     * @returns {SetGroupMetadata} SetGroupMetadata instance
+     */
+    SetGroupMetadata.create = function create(properties) {
+        return new SetGroupMetadata(properties);
+    };
+
+    /**
+     * Encodes the specified SetGroupMetadata message. Does not implicitly {@link SetGroupMetadata.verify|verify} messages.
+     * @function encode
+     * @memberof SetGroupMetadata
+     * @static
+     * @param {ISetGroupMetadata} message SetGroupMetadata message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    SetGroupMetadata.encode = function encode(message, writer) {
+        if (!writer)
+            writer = $Writer.create();
+        if (message.newMetadata != null && Object.hasOwnProperty.call(message, "newMetadata"))
+            $root.WorkingGroupMetadata.encode(message.newMetadata, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
+        return writer;
+    };
+
+    /**
+     * Encodes the specified SetGroupMetadata message, length delimited. Does not implicitly {@link SetGroupMetadata.verify|verify} messages.
+     * @function encodeDelimited
+     * @memberof SetGroupMetadata
+     * @static
+     * @param {ISetGroupMetadata} message SetGroupMetadata message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    SetGroupMetadata.encodeDelimited = function encodeDelimited(message, writer) {
+        return this.encode(message, writer).ldelim();
+    };
+
+    /**
+     * Decodes a SetGroupMetadata message from the specified reader or buffer.
+     * @function decode
+     * @memberof SetGroupMetadata
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @param {number} [length] Message length if known beforehand
+     * @returns {SetGroupMetadata} SetGroupMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    SetGroupMetadata.decode = function decode(reader, length) {
+        if (!(reader instanceof $Reader))
+            reader = $Reader.create(reader);
+        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.SetGroupMetadata();
+        while (reader.pos < end) {
+            var tag = reader.uint32();
+            switch (tag >>> 3) {
+            case 1:
+                message.newMetadata = $root.WorkingGroupMetadata.decode(reader, reader.uint32());
+                break;
+            default:
+                reader.skipType(tag & 7);
+                break;
+            }
+        }
+        return message;
+    };
+
+    /**
+     * Decodes a SetGroupMetadata message from the specified reader or buffer, length delimited.
+     * @function decodeDelimited
+     * @memberof SetGroupMetadata
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @returns {SetGroupMetadata} SetGroupMetadata
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    SetGroupMetadata.decodeDelimited = function decodeDelimited(reader) {
+        if (!(reader instanceof $Reader))
+            reader = new $Reader(reader);
+        return this.decode(reader, reader.uint32());
+    };
+
+    /**
+     * Verifies a SetGroupMetadata message.
+     * @function verify
+     * @memberof SetGroupMetadata
+     * @static
+     * @param {Object.<string,*>} message Plain object to verify
+     * @returns {string|null} `null` if valid, otherwise the reason why it is not
+     */
+    SetGroupMetadata.verify = function verify(message) {
+        if (typeof message !== "object" || message === null)
+            return "object expected";
+        if (message.newMetadata != null && message.hasOwnProperty("newMetadata")) {
+            var error = $root.WorkingGroupMetadata.verify(message.newMetadata);
+            if (error)
+                return "newMetadata." + error;
+        }
+        return null;
+    };
+
+    /**
+     * Creates a SetGroupMetadata message from a plain object. Also converts values to their respective internal types.
+     * @function fromObject
+     * @memberof SetGroupMetadata
+     * @static
+     * @param {Object.<string,*>} object Plain object
+     * @returns {SetGroupMetadata} SetGroupMetadata
+     */
+    SetGroupMetadata.fromObject = function fromObject(object) {
+        if (object instanceof $root.SetGroupMetadata)
+            return object;
+        var message = new $root.SetGroupMetadata();
+        if (object.newMetadata != null) {
+            if (typeof object.newMetadata !== "object")
+                throw TypeError(".SetGroupMetadata.newMetadata: object expected");
+            message.newMetadata = $root.WorkingGroupMetadata.fromObject(object.newMetadata);
+        }
+        return message;
+    };
+
+    /**
+     * Creates a plain object from a SetGroupMetadata message. Also converts values to other types if specified.
+     * @function toObject
+     * @memberof SetGroupMetadata
+     * @static
+     * @param {SetGroupMetadata} message SetGroupMetadata
+     * @param {$protobuf.IConversionOptions} [options] Conversion options
+     * @returns {Object.<string,*>} Plain object
+     */
+    SetGroupMetadata.toObject = function toObject(message, options) {
+        if (!options)
+            options = {};
+        var object = {};
+        if (options.defaults)
+            object.newMetadata = null;
+        if (message.newMetadata != null && message.hasOwnProperty("newMetadata"))
+            object.newMetadata = $root.WorkingGroupMetadata.toObject(message.newMetadata, options);
+        return object;
+    };
+
+    /**
+     * Converts this SetGroupMetadata to JSON.
+     * @function toJSON
+     * @memberof SetGroupMetadata
+     * @instance
+     * @returns {Object.<string,*>} JSON object
+     */
+    SetGroupMetadata.prototype.toJSON = function toJSON() {
+        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
+    };
+
+    return SetGroupMetadata;
+})();
+
+$root.AddUpcomingOpening = (function() {
+
+    /**
+     * Properties of an AddUpcomingOpening.
+     * @exports IAddUpcomingOpening
+     * @interface IAddUpcomingOpening
+     * @property {IUpcomingOpeningMetadata|null} [metadata] AddUpcomingOpening metadata
+     */
+
+    /**
+     * Constructs a new AddUpcomingOpening.
+     * @exports AddUpcomingOpening
+     * @classdesc Represents an AddUpcomingOpening.
+     * @implements IAddUpcomingOpening
+     * @constructor
+     * @param {IAddUpcomingOpening=} [properties] Properties to set
+     */
+    function AddUpcomingOpening(properties) {
+        if (properties)
+            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                if (properties[keys[i]] != null)
+                    this[keys[i]] = properties[keys[i]];
+    }
+
+    /**
+     * AddUpcomingOpening metadata.
+     * @member {IUpcomingOpeningMetadata|null|undefined} metadata
+     * @memberof AddUpcomingOpening
+     * @instance
+     */
+    AddUpcomingOpening.prototype.metadata = null;
+
+    /**
+     * Creates a new AddUpcomingOpening instance using the specified properties.
+     * @function create
+     * @memberof AddUpcomingOpening
+     * @static
+     * @param {IAddUpcomingOpening=} [properties] Properties to set
+     * @returns {AddUpcomingOpening} AddUpcomingOpening instance
+     */
+    AddUpcomingOpening.create = function create(properties) {
+        return new AddUpcomingOpening(properties);
+    };
+
+    /**
+     * Encodes the specified AddUpcomingOpening message. Does not implicitly {@link AddUpcomingOpening.verify|verify} messages.
+     * @function encode
+     * @memberof AddUpcomingOpening
+     * @static
+     * @param {IAddUpcomingOpening} message AddUpcomingOpening message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    AddUpcomingOpening.encode = function encode(message, writer) {
+        if (!writer)
+            writer = $Writer.create();
+        if (message.metadata != null && Object.hasOwnProperty.call(message, "metadata"))
+            $root.UpcomingOpeningMetadata.encode(message.metadata, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
+        return writer;
+    };
+
+    /**
+     * Encodes the specified AddUpcomingOpening message, length delimited. Does not implicitly {@link AddUpcomingOpening.verify|verify} messages.
+     * @function encodeDelimited
+     * @memberof AddUpcomingOpening
+     * @static
+     * @param {IAddUpcomingOpening} message AddUpcomingOpening message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    AddUpcomingOpening.encodeDelimited = function encodeDelimited(message, writer) {
+        return this.encode(message, writer).ldelim();
+    };
+
+    /**
+     * Decodes an AddUpcomingOpening message from the specified reader or buffer.
+     * @function decode
+     * @memberof AddUpcomingOpening
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @param {number} [length] Message length if known beforehand
+     * @returns {AddUpcomingOpening} AddUpcomingOpening
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    AddUpcomingOpening.decode = function decode(reader, length) {
+        if (!(reader instanceof $Reader))
+            reader = $Reader.create(reader);
+        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.AddUpcomingOpening();
+        while (reader.pos < end) {
+            var tag = reader.uint32();
+            switch (tag >>> 3) {
+            case 1:
+                message.metadata = $root.UpcomingOpeningMetadata.decode(reader, reader.uint32());
+                break;
+            default:
+                reader.skipType(tag & 7);
+                break;
+            }
+        }
+        return message;
+    };
+
+    /**
+     * Decodes an AddUpcomingOpening message from the specified reader or buffer, length delimited.
+     * @function decodeDelimited
+     * @memberof AddUpcomingOpening
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @returns {AddUpcomingOpening} AddUpcomingOpening
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    AddUpcomingOpening.decodeDelimited = function decodeDelimited(reader) {
+        if (!(reader instanceof $Reader))
+            reader = new $Reader(reader);
+        return this.decode(reader, reader.uint32());
+    };
+
+    /**
+     * Verifies an AddUpcomingOpening message.
+     * @function verify
+     * @memberof AddUpcomingOpening
+     * @static
+     * @param {Object.<string,*>} message Plain object to verify
+     * @returns {string|null} `null` if valid, otherwise the reason why it is not
+     */
+    AddUpcomingOpening.verify = function verify(message) {
+        if (typeof message !== "object" || message === null)
+            return "object expected";
+        if (message.metadata != null && message.hasOwnProperty("metadata")) {
+            var error = $root.UpcomingOpeningMetadata.verify(message.metadata);
+            if (error)
+                return "metadata." + error;
+        }
+        return null;
+    };
+
+    /**
+     * Creates an AddUpcomingOpening message from a plain object. Also converts values to their respective internal types.
+     * @function fromObject
+     * @memberof AddUpcomingOpening
+     * @static
+     * @param {Object.<string,*>} object Plain object
+     * @returns {AddUpcomingOpening} AddUpcomingOpening
+     */
+    AddUpcomingOpening.fromObject = function fromObject(object) {
+        if (object instanceof $root.AddUpcomingOpening)
+            return object;
+        var message = new $root.AddUpcomingOpening();
+        if (object.metadata != null) {
+            if (typeof object.metadata !== "object")
+                throw TypeError(".AddUpcomingOpening.metadata: object expected");
+            message.metadata = $root.UpcomingOpeningMetadata.fromObject(object.metadata);
+        }
+        return message;
+    };
+
+    /**
+     * Creates a plain object from an AddUpcomingOpening message. Also converts values to other types if specified.
+     * @function toObject
+     * @memberof AddUpcomingOpening
+     * @static
+     * @param {AddUpcomingOpening} message AddUpcomingOpening
+     * @param {$protobuf.IConversionOptions} [options] Conversion options
+     * @returns {Object.<string,*>} Plain object
+     */
+    AddUpcomingOpening.toObject = function toObject(message, options) {
+        if (!options)
+            options = {};
+        var object = {};
+        if (options.defaults)
+            object.metadata = null;
+        if (message.metadata != null && message.hasOwnProperty("metadata"))
+            object.metadata = $root.UpcomingOpeningMetadata.toObject(message.metadata, options);
+        return object;
+    };
+
+    /**
+     * Converts this AddUpcomingOpening to JSON.
+     * @function toJSON
+     * @memberof AddUpcomingOpening
+     * @instance
+     * @returns {Object.<string,*>} JSON object
+     */
+    AddUpcomingOpening.prototype.toJSON = function toJSON() {
+        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
+    };
+
+    return AddUpcomingOpening;
+})();
+
+$root.RemoveUpcomingOpening = (function() {
+
+    /**
+     * Properties of a RemoveUpcomingOpening.
+     * @exports IRemoveUpcomingOpening
+     * @interface IRemoveUpcomingOpening
+     * @property {string|null} [id] RemoveUpcomingOpening id
+     */
+
+    /**
+     * Constructs a new RemoveUpcomingOpening.
+     * @exports RemoveUpcomingOpening
+     * @classdesc Represents a RemoveUpcomingOpening.
+     * @implements IRemoveUpcomingOpening
+     * @constructor
+     * @param {IRemoveUpcomingOpening=} [properties] Properties to set
+     */
+    function RemoveUpcomingOpening(properties) {
+        if (properties)
+            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                if (properties[keys[i]] != null)
+                    this[keys[i]] = properties[keys[i]];
+    }
+
+    /**
+     * RemoveUpcomingOpening id.
+     * @member {string} id
+     * @memberof RemoveUpcomingOpening
+     * @instance
+     */
+    RemoveUpcomingOpening.prototype.id = "";
+
+    /**
+     * Creates a new RemoveUpcomingOpening instance using the specified properties.
+     * @function create
+     * @memberof RemoveUpcomingOpening
+     * @static
+     * @param {IRemoveUpcomingOpening=} [properties] Properties to set
+     * @returns {RemoveUpcomingOpening} RemoveUpcomingOpening instance
+     */
+    RemoveUpcomingOpening.create = function create(properties) {
+        return new RemoveUpcomingOpening(properties);
+    };
+
+    /**
+     * Encodes the specified RemoveUpcomingOpening message. Does not implicitly {@link RemoveUpcomingOpening.verify|verify} messages.
+     * @function encode
+     * @memberof RemoveUpcomingOpening
+     * @static
+     * @param {IRemoveUpcomingOpening} message RemoveUpcomingOpening message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    RemoveUpcomingOpening.encode = function encode(message, writer) {
+        if (!writer)
+            writer = $Writer.create();
+        if (message.id != null && Object.hasOwnProperty.call(message, "id"))
+            writer.uint32(/* id 1, wireType 2 =*/10).string(message.id);
+        return writer;
+    };
+
+    /**
+     * Encodes the specified RemoveUpcomingOpening message, length delimited. Does not implicitly {@link RemoveUpcomingOpening.verify|verify} messages.
+     * @function encodeDelimited
+     * @memberof RemoveUpcomingOpening
+     * @static
+     * @param {IRemoveUpcomingOpening} message RemoveUpcomingOpening message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    RemoveUpcomingOpening.encodeDelimited = function encodeDelimited(message, writer) {
+        return this.encode(message, writer).ldelim();
+    };
+
+    /**
+     * Decodes a RemoveUpcomingOpening message from the specified reader or buffer.
+     * @function decode
+     * @memberof RemoveUpcomingOpening
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @param {number} [length] Message length if known beforehand
+     * @returns {RemoveUpcomingOpening} RemoveUpcomingOpening
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    RemoveUpcomingOpening.decode = function decode(reader, length) {
+        if (!(reader instanceof $Reader))
+            reader = $Reader.create(reader);
+        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.RemoveUpcomingOpening();
+        while (reader.pos < end) {
+            var tag = reader.uint32();
+            switch (tag >>> 3) {
+            case 1:
+                message.id = reader.string();
+                break;
+            default:
+                reader.skipType(tag & 7);
+                break;
+            }
+        }
+        return message;
+    };
+
+    /**
+     * Decodes a RemoveUpcomingOpening message from the specified reader or buffer, length delimited.
+     * @function decodeDelimited
+     * @memberof RemoveUpcomingOpening
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @returns {RemoveUpcomingOpening} RemoveUpcomingOpening
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    RemoveUpcomingOpening.decodeDelimited = function decodeDelimited(reader) {
+        if (!(reader instanceof $Reader))
+            reader = new $Reader(reader);
+        return this.decode(reader, reader.uint32());
+    };
+
+    /**
+     * Verifies a RemoveUpcomingOpening message.
+     * @function verify
+     * @memberof RemoveUpcomingOpening
+     * @static
+     * @param {Object.<string,*>} message Plain object to verify
+     * @returns {string|null} `null` if valid, otherwise the reason why it is not
+     */
+    RemoveUpcomingOpening.verify = function verify(message) {
+        if (typeof message !== "object" || message === null)
+            return "object expected";
+        if (message.id != null && message.hasOwnProperty("id"))
+            if (!$util.isString(message.id))
+                return "id: string expected";
+        return null;
+    };
+
+    /**
+     * Creates a RemoveUpcomingOpening message from a plain object. Also converts values to their respective internal types.
+     * @function fromObject
+     * @memberof RemoveUpcomingOpening
+     * @static
+     * @param {Object.<string,*>} object Plain object
+     * @returns {RemoveUpcomingOpening} RemoveUpcomingOpening
+     */
+    RemoveUpcomingOpening.fromObject = function fromObject(object) {
+        if (object instanceof $root.RemoveUpcomingOpening)
+            return object;
+        var message = new $root.RemoveUpcomingOpening();
+        if (object.id != null)
+            message.id = String(object.id);
+        return message;
+    };
+
+    /**
+     * Creates a plain object from a RemoveUpcomingOpening message. Also converts values to other types if specified.
+     * @function toObject
+     * @memberof RemoveUpcomingOpening
+     * @static
+     * @param {RemoveUpcomingOpening} message RemoveUpcomingOpening
+     * @param {$protobuf.IConversionOptions} [options] Conversion options
+     * @returns {Object.<string,*>} Plain object
+     */
+    RemoveUpcomingOpening.toObject = function toObject(message, options) {
+        if (!options)
+            options = {};
+        var object = {};
+        if (options.defaults)
+            object.id = "";
+        if (message.id != null && message.hasOwnProperty("id"))
+            object.id = message.id;
+        return object;
+    };
+
+    /**
+     * Converts this RemoveUpcomingOpening to JSON.
+     * @function toJSON
+     * @memberof RemoveUpcomingOpening
+     * @instance
+     * @returns {Object.<string,*>} JSON object
+     */
+    RemoveUpcomingOpening.prototype.toJSON = function toJSON() {
+        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
+    };
+
+    return RemoveUpcomingOpening;
+})();
+
+$root.WorkingGroupMetadataAction = (function() {
+
+    /**
+     * Properties of a WorkingGroupMetadataAction.
+     * @exports IWorkingGroupMetadataAction
+     * @interface IWorkingGroupMetadataAction
+     * @property {ISetGroupMetadata|null} [setGroupMetadata] WorkingGroupMetadataAction setGroupMetadata
+     * @property {IAddUpcomingOpening|null} [addUpcomingOpening] WorkingGroupMetadataAction addUpcomingOpening
+     * @property {IRemoveUpcomingOpening|null} [removeUpcomingOpening] WorkingGroupMetadataAction removeUpcomingOpening
+     */
+
+    /**
+     * Constructs a new WorkingGroupMetadataAction.
+     * @exports WorkingGroupMetadataAction
+     * @classdesc Represents a WorkingGroupMetadataAction.
+     * @implements IWorkingGroupMetadataAction
+     * @constructor
+     * @param {IWorkingGroupMetadataAction=} [properties] Properties to set
+     */
+    function WorkingGroupMetadataAction(properties) {
+        if (properties)
+            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
+                if (properties[keys[i]] != null)
+                    this[keys[i]] = properties[keys[i]];
+    }
+
+    /**
+     * WorkingGroupMetadataAction setGroupMetadata.
+     * @member {ISetGroupMetadata|null|undefined} setGroupMetadata
+     * @memberof WorkingGroupMetadataAction
+     * @instance
+     */
+    WorkingGroupMetadataAction.prototype.setGroupMetadata = null;
+
+    /**
+     * WorkingGroupMetadataAction addUpcomingOpening.
+     * @member {IAddUpcomingOpening|null|undefined} addUpcomingOpening
+     * @memberof WorkingGroupMetadataAction
+     * @instance
+     */
+    WorkingGroupMetadataAction.prototype.addUpcomingOpening = null;
+
+    /**
+     * WorkingGroupMetadataAction removeUpcomingOpening.
+     * @member {IRemoveUpcomingOpening|null|undefined} removeUpcomingOpening
+     * @memberof WorkingGroupMetadataAction
+     * @instance
+     */
+    WorkingGroupMetadataAction.prototype.removeUpcomingOpening = null;
+
+    // OneOf field names bound to virtual getters and setters
+    var $oneOfFields;
+
+    /**
+     * WorkingGroupMetadataAction action.
+     * @member {"setGroupMetadata"|"addUpcomingOpening"|"removeUpcomingOpening"|undefined} action
+     * @memberof WorkingGroupMetadataAction
+     * @instance
+     */
+    Object.defineProperty(WorkingGroupMetadataAction.prototype, "action", {
+        get: $util.oneOfGetter($oneOfFields = ["setGroupMetadata", "addUpcomingOpening", "removeUpcomingOpening"]),
+        set: $util.oneOfSetter($oneOfFields)
+    });
+
+    /**
+     * Creates a new WorkingGroupMetadataAction instance using the specified properties.
+     * @function create
+     * @memberof WorkingGroupMetadataAction
+     * @static
+     * @param {IWorkingGroupMetadataAction=} [properties] Properties to set
+     * @returns {WorkingGroupMetadataAction} WorkingGroupMetadataAction instance
+     */
+    WorkingGroupMetadataAction.create = function create(properties) {
+        return new WorkingGroupMetadataAction(properties);
+    };
+
+    /**
+     * Encodes the specified WorkingGroupMetadataAction message. Does not implicitly {@link WorkingGroupMetadataAction.verify|verify} messages.
+     * @function encode
+     * @memberof WorkingGroupMetadataAction
+     * @static
+     * @param {IWorkingGroupMetadataAction} message WorkingGroupMetadataAction message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    WorkingGroupMetadataAction.encode = function encode(message, writer) {
+        if (!writer)
+            writer = $Writer.create();
+        if (message.setGroupMetadata != null && Object.hasOwnProperty.call(message, "setGroupMetadata"))
+            $root.SetGroupMetadata.encode(message.setGroupMetadata, writer.uint32(/* id 1, wireType 2 =*/10).fork()).ldelim();
+        if (message.addUpcomingOpening != null && Object.hasOwnProperty.call(message, "addUpcomingOpening"))
+            $root.AddUpcomingOpening.encode(message.addUpcomingOpening, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
+        if (message.removeUpcomingOpening != null && Object.hasOwnProperty.call(message, "removeUpcomingOpening"))
+            $root.RemoveUpcomingOpening.encode(message.removeUpcomingOpening, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
+        return writer;
+    };
+
+    /**
+     * Encodes the specified WorkingGroupMetadataAction message, length delimited. Does not implicitly {@link WorkingGroupMetadataAction.verify|verify} messages.
+     * @function encodeDelimited
+     * @memberof WorkingGroupMetadataAction
+     * @static
+     * @param {IWorkingGroupMetadataAction} message WorkingGroupMetadataAction message or plain object to encode
+     * @param {$protobuf.Writer} [writer] Writer to encode to
+     * @returns {$protobuf.Writer} Writer
+     */
+    WorkingGroupMetadataAction.encodeDelimited = function encodeDelimited(message, writer) {
+        return this.encode(message, writer).ldelim();
+    };
+
+    /**
+     * Decodes a WorkingGroupMetadataAction message from the specified reader or buffer.
+     * @function decode
+     * @memberof WorkingGroupMetadataAction
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @param {number} [length] Message length if known beforehand
+     * @returns {WorkingGroupMetadataAction} WorkingGroupMetadataAction
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    WorkingGroupMetadataAction.decode = function decode(reader, length) {
+        if (!(reader instanceof $Reader))
+            reader = $Reader.create(reader);
+        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.WorkingGroupMetadataAction();
+        while (reader.pos < end) {
+            var tag = reader.uint32();
+            switch (tag >>> 3) {
+            case 1:
+                message.setGroupMetadata = $root.SetGroupMetadata.decode(reader, reader.uint32());
+                break;
+            case 2:
+                message.addUpcomingOpening = $root.AddUpcomingOpening.decode(reader, reader.uint32());
+                break;
+            case 3:
+                message.removeUpcomingOpening = $root.RemoveUpcomingOpening.decode(reader, reader.uint32());
+                break;
+            default:
+                reader.skipType(tag & 7);
+                break;
+            }
+        }
+        return message;
+    };
+
+    /**
+     * Decodes a WorkingGroupMetadataAction message from the specified reader or buffer, length delimited.
+     * @function decodeDelimited
+     * @memberof WorkingGroupMetadataAction
+     * @static
+     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
+     * @returns {WorkingGroupMetadataAction} WorkingGroupMetadataAction
+     * @throws {Error} If the payload is not a reader or valid buffer
+     * @throws {$protobuf.util.ProtocolError} If required fields are missing
+     */
+    WorkingGroupMetadataAction.decodeDelimited = function decodeDelimited(reader) {
+        if (!(reader instanceof $Reader))
+            reader = new $Reader(reader);
+        return this.decode(reader, reader.uint32());
+    };
+
+    /**
+     * Verifies a WorkingGroupMetadataAction message.
+     * @function verify
+     * @memberof WorkingGroupMetadataAction
+     * @static
+     * @param {Object.<string,*>} message Plain object to verify
+     * @returns {string|null} `null` if valid, otherwise the reason why it is not
+     */
+    WorkingGroupMetadataAction.verify = function verify(message) {
+        if (typeof message !== "object" || message === null)
+            return "object expected";
+        var properties = {};
+        if (message.setGroupMetadata != null && message.hasOwnProperty("setGroupMetadata")) {
+            properties.action = 1;
+            {
+                var error = $root.SetGroupMetadata.verify(message.setGroupMetadata);
+                if (error)
+                    return "setGroupMetadata." + error;
+            }
+        }
+        if (message.addUpcomingOpening != null && message.hasOwnProperty("addUpcomingOpening")) {
+            if (properties.action === 1)
+                return "action: multiple values";
+            properties.action = 1;
+            {
+                var error = $root.AddUpcomingOpening.verify(message.addUpcomingOpening);
+                if (error)
+                    return "addUpcomingOpening." + error;
+            }
+        }
+        if (message.removeUpcomingOpening != null && message.hasOwnProperty("removeUpcomingOpening")) {
+            if (properties.action === 1)
+                return "action: multiple values";
+            properties.action = 1;
+            {
+                var error = $root.RemoveUpcomingOpening.verify(message.removeUpcomingOpening);
+                if (error)
+                    return "removeUpcomingOpening." + error;
+            }
+        }
+        return null;
+    };
+
+    /**
+     * Creates a WorkingGroupMetadataAction message from a plain object. Also converts values to their respective internal types.
+     * @function fromObject
+     * @memberof WorkingGroupMetadataAction
+     * @static
+     * @param {Object.<string,*>} object Plain object
+     * @returns {WorkingGroupMetadataAction} WorkingGroupMetadataAction
+     */
+    WorkingGroupMetadataAction.fromObject = function fromObject(object) {
+        if (object instanceof $root.WorkingGroupMetadataAction)
+            return object;
+        var message = new $root.WorkingGroupMetadataAction();
+        if (object.setGroupMetadata != null) {
+            if (typeof object.setGroupMetadata !== "object")
+                throw TypeError(".WorkingGroupMetadataAction.setGroupMetadata: object expected");
+            message.setGroupMetadata = $root.SetGroupMetadata.fromObject(object.setGroupMetadata);
+        }
+        if (object.addUpcomingOpening != null) {
+            if (typeof object.addUpcomingOpening !== "object")
+                throw TypeError(".WorkingGroupMetadataAction.addUpcomingOpening: object expected");
+            message.addUpcomingOpening = $root.AddUpcomingOpening.fromObject(object.addUpcomingOpening);
+        }
+        if (object.removeUpcomingOpening != null) {
+            if (typeof object.removeUpcomingOpening !== "object")
+                throw TypeError(".WorkingGroupMetadataAction.removeUpcomingOpening: object expected");
+            message.removeUpcomingOpening = $root.RemoveUpcomingOpening.fromObject(object.removeUpcomingOpening);
+        }
+        return message;
+    };
+
+    /**
+     * Creates a plain object from a WorkingGroupMetadataAction message. Also converts values to other types if specified.
+     * @function toObject
+     * @memberof WorkingGroupMetadataAction
+     * @static
+     * @param {WorkingGroupMetadataAction} message WorkingGroupMetadataAction
+     * @param {$protobuf.IConversionOptions} [options] Conversion options
+     * @returns {Object.<string,*>} Plain object
+     */
+    WorkingGroupMetadataAction.toObject = function toObject(message, options) {
+        if (!options)
+            options = {};
+        var object = {};
+        if (message.setGroupMetadata != null && message.hasOwnProperty("setGroupMetadata")) {
+            object.setGroupMetadata = $root.SetGroupMetadata.toObject(message.setGroupMetadata, options);
+            if (options.oneofs)
+                object.action = "setGroupMetadata";
+        }
+        if (message.addUpcomingOpening != null && message.hasOwnProperty("addUpcomingOpening")) {
+            object.addUpcomingOpening = $root.AddUpcomingOpening.toObject(message.addUpcomingOpening, options);
+            if (options.oneofs)
+                object.action = "addUpcomingOpening";
+        }
+        if (message.removeUpcomingOpening != null && message.hasOwnProperty("removeUpcomingOpening")) {
+            object.removeUpcomingOpening = $root.RemoveUpcomingOpening.toObject(message.removeUpcomingOpening, options);
+            if (options.oneofs)
+                object.action = "removeUpcomingOpening";
+        }
+        return object;
+    };
+
+    /**
+     * Converts this WorkingGroupMetadataAction to JSON.
+     * @function toJSON
+     * @memberof WorkingGroupMetadataAction
+     * @instance
+     * @returns {Object.<string,*>} JSON object
+     */
+    WorkingGroupMetadataAction.prototype.toJSON = function toJSON() {
+        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
+    };
+
+    return WorkingGroupMetadataAction;
+})();
+
+module.exports = $root;

+ 127 - 42
metadata-protobuf/doc/index.md

@@ -5,18 +5,23 @@
 
 - [proto/Council.proto](#proto/Council.proto)
     - [CouncilCandidacyNoteMetadata](#.CouncilCandidacyNoteMetadata)
-  
+
 - [proto/Membership.proto](#proto/Membership.proto)
     - [MembershipMetadata](#.MembershipMetadata)
-  
+
 - [proto/WorkingGroups.proto](#proto/WorkingGroups.proto)
+    - [AddUpcomingOpening](#.AddUpcomingOpening)
     - [ApplicationMetadata](#.ApplicationMetadata)
     - [OpeningMetadata](#.OpeningMetadata)
     - [OpeningMetadata.ApplicationFormQuestion](#.OpeningMetadata.ApplicationFormQuestion)
-    - [WorkingGroupStatusMetadata](#.WorkingGroupStatusMetadata)
-  
+    - [RemoveUpcomingOpening](#.RemoveUpcomingOpening)
+    - [SetGroupMetadata](#.SetGroupMetadata)
+    - [UpcomingOpeningMetadata](#.UpcomingOpeningMetadata)
+    - [WorkingGroupMetadata](#.WorkingGroupMetadata)
+    - [WorkingGroupMetadataAction](#.WorkingGroupMetadataAction)
+
     - [OpeningMetadata.ApplicationFormQuestion.InputType](#.OpeningMetadata.ApplicationFormQuestion.InputType)
-  
+
 - [Scalar Value Types](#scalar-value-types)
 
 
@@ -36,22 +41,22 @@
 
 | Field | Type | Label | Description |
 | ----- | ---- | ----- | ----------- |
-| header | [string](#string) | optional |  |
-| bullet_points | [string](#string) | repeated |  |
-| cover_image | [string](#string) | optional |  |
-| description | [string](#string) | optional |  |
+| header | [string](#string) | optional | Candidacy header text |
+| bullet_points | [string](#string) | repeated | Candidate program in form of bullet points |
+| banner_image_uri | [string](#string) | optional | Image uri of candidate&#39;s banner |
+| description | [string](#string) | optional | Candidacy description (md-formatted) |
+
+
+
+
 
 
 
 
 
- 
 
- 
 
- 
 
- 
 
 
 
@@ -70,21 +75,21 @@
 
 | Field | Type | Label | Description |
 | ----- | ---- | ----- | ----------- |
-| name | [string](#string) | optional |  |
-| avatar_uri | [string](#string) | optional |  |
-| about | [string](#string) | optional |  |
+| name | [string](#string) | optional | Member&#39;s real name |
+| avatar | [uint32](#uint32) | optional | Member&#39;s avatar - index into external [assets array](#.Assets) |
+| about | [string](#string) | optional | Member&#39;s md-formatted about text |
+
+
+
+
 
 
 
 
 
- 
 
- 
 
- 
 
- 
 
 
 
@@ -95,6 +100,21 @@
 
 
 
+<a name=".AddUpcomingOpening"></a>
+
+### AddUpcomingOpening
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| metadata | [UpcomingOpeningMetadata](#UpcomingOpeningMetadata) | optional | Upcoming opening metadata |
+
+
+
+
+
+
 <a name=".ApplicationMetadata"></a>
 
 ### ApplicationMetadata
@@ -103,7 +123,7 @@
 
 | Field | Type | Label | Description |
 | ----- | ---- | ----- | ----------- |
-| answers | [string](#string) | repeated |  |
+| answers | [string](#string) | repeated | List of answers to opening application form questions |
 
 
 
@@ -118,12 +138,12 @@
 
 | Field | Type | Label | Description |
 | ----- | ---- | ----- | ----------- |
-| short_description | [string](#string) | required |  |
-| description | [string](#string) | required |  |
-| hiring_limit | [uint32](#uint32) | required |  |
-| expected_duration | [uint32](#uint32) | required |  |
-| application_details | [string](#string) | required |  |
-| application_form_questions | [OpeningMetadata.ApplicationFormQuestion](#OpeningMetadata.ApplicationFormQuestion) | repeated |  |
+| short_description | [string](#string) | optional | Short description of the opening |
+| description | [string](#string) | optional | Full description of the opening |
+| hiring_limit | [uint32](#uint32) | optional | Expected number of hired applicants |
+| expected_ending_timestamp | [uint32](#uint32) | optional | Expected time when the opening will close (Unix timestamp) |
+| application_details | [string](#string) | optional | Md-formatted text explaining the application process |
+| application_form_questions | [OpeningMetadata.ApplicationFormQuestion](#OpeningMetadata.ApplicationFormQuestion) | repeated | List of questions that should be answered during application |
 
 
 
@@ -138,32 +158,97 @@
 
 | Field | Type | Label | Description |
 | ----- | ---- | ----- | ----------- |
-| question | [string](#string) | required |  |
-| type | [OpeningMetadata.ApplicationFormQuestion.InputType](#OpeningMetadata.ApplicationFormQuestion.InputType) | required |  |
+| question | [string](#string) | optional | The question itself (ie. &#34;What is your name?&#34;&#34;) |
+| type | [OpeningMetadata.ApplicationFormQuestion.InputType](#OpeningMetadata.ApplicationFormQuestion.InputType) | optional | Suggested type of the UI answer input |
+
+
+
+
+
+
+<a name=".RemoveUpcomingOpening"></a>
+
+### RemoveUpcomingOpening
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| id | [string](#string) | optional | Upcoming opening query-node id |
+
+
+
+
+
+
+<a name=".SetGroupMetadata"></a>
+
+### SetGroupMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| new_metadata | [WorkingGroupMetadata](#WorkingGroupMetadata) | optional | New working group metadata to set (can be a partial update) |
+
+
+
+
+
+
+<a name=".UpcomingOpeningMetadata"></a>
+
+### UpcomingOpeningMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| expected_start | [uint32](#uint32) | optional | Expected opening start (timestamp) |
+| reward_per_block | [uint64](#uint64) | optional | Expected reward per block |
+| min_application_stake | [uint64](#uint64) | optional | Expected min. application stake |
+| metadata | [OpeningMetadata](#OpeningMetadata) | optional | Opening metadata |
 
 
 
 
 
 
-<a name=".WorkingGroupStatusMetadata"></a>
+<a name=".WorkingGroupMetadata"></a>
 
-### WorkingGroupStatusMetadata
+### WorkingGroupMetadata
 
 
 
 | Field | Type | Label | Description |
 | ----- | ---- | ----- | ----------- |
-| description | [string](#string) | optional |  |
-| about | [string](#string) | optional |  |
-| status | [string](#string) | optional | Can also be an enum if we only want a limited set |
-| status_message | [string](#string) | optional |  |
+| description | [string](#string) | optional | Group description text (md-formatted) |
+| about | [string](#string) | optional | Group about text (md-formatted) |
+| status | [string](#string) | optional | Current group status (expected to be 1-3 words) |
+| status_message | [string](#string) | optional | Short status message associated with the status |
+
+
+
+
+
+
+<a name=".WorkingGroupMetadataAction"></a>
+
+### WorkingGroupMetadataAction
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| set_group_metadata | [SetGroupMetadata](#SetGroupMetadata) | optional |  |
+| add_upcoming_opening | [AddUpcomingOpening](#AddUpcomingOpening) | optional |  |
+| remove_upcoming_opening | [RemoveUpcomingOpening](#RemoveUpcomingOpening) | optional |  |
+
 
 
 
 
 
- 
 
 
 <a name=".OpeningMetadata.ApplicationFormQuestion.InputType"></a>
@@ -173,15 +258,15 @@
 
 | Name | Number | Description |
 | ---- | ------ | ----------- |
+| TEXTAREA | 0 |  |
 | TEXT | 1 |  |
-| TEXTAREA | 2 |  |
 
 
- 
 
- 
 
- 
+
+
+
 
 
 
@@ -205,7 +290,7 @@
 | <a name="string" /> string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
 | <a name="bytes" /> bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |
 
-<!-- 
+<!--
     This extra documentation will be appended to the generated docs.
 -->
 
@@ -245,4 +330,4 @@ meta = VideoMetadata {
     thumbnail_photo: 0,
     ...
 };
-```
+```

+ 6 - 4
metadata-protobuf/package.json

@@ -9,7 +9,7 @@
   "license": "MIT",
   "private": false,
   "scripts": {
-    "build": "tsc",
+    "build": "yarn compile && tsc",
     "compile": "./compile.sh",
     "generate-doc": "./generate-md-doc.sh",
     "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha -r ts-node/register 'test/**/*.ts'",
@@ -25,7 +25,9 @@
     "README.md"
   ],
   "dependencies": {
-    "google-protobuf": "^3.14.0"
+    "google-protobuf": "^3.14.0",
+    "long": "^4.0.0",
+    "@types/long": "^4.0.1"
   },
   "devDependencies": {
     "@types/chai": "^4.2.11",
@@ -35,7 +37,7 @@
     "mocha": "^8.2.1",
     "prettier": "2.0.2",
     "ts-node": "^8.8.1",
-    "ts-protoc-gen": "^0.14.0",
-    "typescript": "^4.1.3"
+    "typescript": "^4.1.3",
+    "protobufjs": "^6.10.2"
   }
 }

+ 4 - 4
metadata-protobuf/proto/Council.proto

@@ -1,8 +1,8 @@
 syntax = "proto2";
 
 message CouncilCandidacyNoteMetadata {
-  optional string header = 1;
-  repeated string bullet_points = 2;
-  optional string cover_image = 3;
-  optional string description = 4;
+  optional string header = 1; // Candidacy header text
+  repeated string bullet_points = 2; // Candidate program in form of bullet points
+  optional string banner_image_uri = 3; // Image uri of candidate's banner
+  optional string description = 4; // Candidacy description (md-formatted)
 }

+ 3 - 3
metadata-protobuf/proto/Membership.proto

@@ -1,7 +1,7 @@
 syntax = "proto2";
 
 message MembershipMetadata {
-  optional string name = 1;
-  optional string avatar_uri = 2;
-  optional string about = 3;
+  optional string name = 1; // Member's real name
+  optional uint32 avatar = 2; // Member's avatar - index into external [assets array](#.Assets)
+  optional string about = 3; // Member's md-formatted about text
 }

+ 44 - 15
metadata-protobuf/proto/WorkingGroups.proto

@@ -1,29 +1,58 @@
 syntax = "proto2";
 
 message OpeningMetadata {
-  required string short_description = 1;
-  required string description = 2;
-  required uint32 hiring_limit = 3;
-  required uint32 expected_duration = 4;
-  required string application_details = 5;
+  optional string short_description = 1; // Short description of the opening
+  optional string description = 2; // Full description of the opening
+  optional uint32 hiring_limit = 3; // Expected number of hired applicants
+  optional uint32 expected_ending_timestamp = 4; // Expected time when the opening will close (Unix timestamp)
+  optional string application_details = 5; // Md-formatted text explaining the application process
   message ApplicationFormQuestion {
-    required string question = 1;
+    optional string question = 1; // The question itself (ie. "What is your name?"")
     enum InputType {
+      TEXTAREA = 0;
       TEXT = 1;
-      TEXTAREA = 2;
     }
-    required InputType type = 2;
+    optional InputType type = 2; // Suggested type of the UI answer input
   }
-  repeated ApplicationFormQuestion application_form_questions = 6;
+  repeated ApplicationFormQuestion application_form_questions = 6; // List of questions that should be answered during application
+}
+
+message UpcomingOpeningMetadata {
+  optional uint32 expected_start = 1; // Expected opening start (timestamp)
+  optional uint64 reward_per_block = 2; // Expected reward per block
+  optional uint64 min_application_stake = 3; // Expected min. application stake
+  optional OpeningMetadata metadata = 4; // Opening metadata
 }
 
 message ApplicationMetadata {
-  repeated string answers = 1;
+  repeated string answers = 1; // List of answers to opening application form questions
+}
+
+// set_status_text extrinsic messages:
+
+message WorkingGroupMetadata {
+  optional string description = 1; // Group description text (md-formatted)
+  optional string about = 2; // Group about text (md-formatted)
+  optional string status = 3; // Current group status (expected to be 1-3 words)
+  optional string status_message = 4; // Short status message associated with the status
+}
+
+message SetGroupMetadata {
+  optional WorkingGroupMetadata new_metadata = 1; // New working group metadata to set (can be a partial update)
+}
+
+message AddUpcomingOpening {
+  optional UpcomingOpeningMetadata metadata = 1; // Upcoming opening metadata
 }
 
-message WorkingGroupStatusMetadata {
-  optional string description = 1;
-  optional string about = 2;
-  optional string status = 3; // Can also be an enum if we only want a limited set
-  optional string status_message = 4;
+message RemoveUpcomingOpening {
+  optional string id = 1; // Upcoming opening query-node id
+}
+
+message WorkingGroupMetadataAction {
+  oneof action {
+    SetGroupMetadata set_group_metadata = 1;
+    AddUpcomingOpening add_upcoming_opening = 2;
+    RemoveUpcomingOpening remove_upcoming_opening = 3;
+  }
 }

+ 1 - 3
metadata-protobuf/src/index.ts

@@ -1,4 +1,2 @@
 // protobuf message constructors
-export * from '../compiled/proto/Council_pb'
-export * from '../compiled/proto/Membership_pb'
-export * from '../compiled/proto/WorkingGroups_pb'
+export * from '../compiled'

+ 2 - 1
package.json

@@ -45,7 +45,8 @@
     "babel-core": "^7.0.0-bridge.0",
     "typescript": "^3.9.7",
     "bn.js": "^5.1.2",
-    "typeorm": "^0.2.31"
+    "typeorm": "^0.2.31",
+    "pg": "^8.4.0"
   },
   "devDependencies": {
     "eslint": "^7.6.0",

+ 1 - 3
query-node/build.sh

@@ -22,12 +22,10 @@ yarn typegen
 yarn codegen:noinstall
 yarn format
 
-# FIXME: Tmp add "declaration": true to query-node tsconfig
-sed -i 's/"compilerOptions": {/"compilerOptions": {\n    "declaration": true,/' ./generated/graphql-server/tsconfig.json
-
 # We run yarn again to ensure graphql-server dependencies are installed
 # and are inline with root workspace resolutions
 yarn
 
 yarn workspace query-node build:dev
+
 yarn workspace query-node-mappings build

+ 2 - 2
query-node/codegen/package.json

@@ -5,7 +5,7 @@
   "author": "",
   "license": "ISC",
   "dependencies": {
-    "@dzlzv/hydra-cli": "2.0.1-beta.15",
-    "@dzlzv/hydra-typegen": "2.0.1-beta.15"
+    "@dzlzv/hydra-cli": "3.0.0-beta.6",
+    "@dzlzv/hydra-typegen": "3.0.0-beta.6"
   }
 }

+ 344 - 247
query-node/codegen/yarn.lock

@@ -69,17 +69,17 @@
     chalk "^2.0.0"
     js-tokens "^4.0.0"
 
-"@babel/runtime@^7.12.5":
+"@babel/runtime@^7.13.10", "@babel/runtime@^7.13.9":
   version "7.13.10"
   resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d"
   integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==
   dependencies:
     regenerator-runtime "^0.13.4"
 
-"@dzlzv/hydra-cli@2.0.1-beta.15":
-  version "2.0.1-beta.15"
-  resolved "https://registry.yarnpkg.com/@dzlzv/hydra-cli/-/hydra-cli-2.0.1-beta.15.tgz#8d4c21e95835e83e84acc76b917c8e069aec6c48"
-  integrity sha512-GE6D7YKMzQOyinaxaDDrASeraH4jmZrTIGCwlTtADdz/f5Qq50mbMECiJq4Fi0LJfh0RTuOUU/Zk9thCtaVNnA==
+"@dzlzv/hydra-cli@3.0.0-beta.6":
+  version "3.0.0-beta.6"
+  resolved "https://registry.yarnpkg.com/@dzlzv/hydra-cli/-/hydra-cli-3.0.0-beta.6.tgz#b85504ed9f4ec939b7108094fd7969d60a9b1f45"
+  integrity sha512-3ENzap6vq2DKOV8gA5Qq9ZX9xDJvP6WXpRvp+Aedf2yTms/gWB9vbhkp2oCZGnjqZqGZ9d2jIBBFJOwiRWpqsA==
   dependencies:
     "@inquirer/input" "^0.0.13-alpha.0"
     "@inquirer/password" "^0.0.12-alpha.0"
@@ -90,6 +90,7 @@
     "@oclif/plugin-help" "^2"
     "@oclif/plugin-plugins" "^1.9.4"
     "@types/chalk" "^2.2.0"
+    "@types/copyfiles" "^2.4.0"
     "@types/fs-extra" "^8.1.0"
     "@types/graphql" "^14.5.0"
     "@types/listr" "^0.14.2"
@@ -97,6 +98,7 @@
     "@types/node" "^12.12.30"
     chalk "^4.1.0"
     cli-ux "^5.4.9"
+    copyfiles "^2.4.1"
     execa "^4.0.3"
     fs-extra "^9.0.0"
     glob "^7.1.6"
@@ -107,17 +109,17 @@
     mustache "^4.0.1"
     pluralize "^8.0.0"
     tslib "1.11.2"
-    warthog "https://github.com/metmirr/warthog/releases/download/v2.23.0/warthog-v2.23.0.tgz"
+    warthog "https://github.com/metmirr/warthog/releases/download/v2.30.0/warthog-v2.30.0.tgz"
 
-"@dzlzv/hydra-typegen@2.0.1-beta.15":
-  version "2.0.1-beta.15"
-  resolved "https://registry.yarnpkg.com/@dzlzv/hydra-typegen/-/hydra-typegen-2.0.1-beta.15.tgz#daa98df326d6e4871e7b710350c03ae076ada768"
-  integrity sha512-/xrmve0+DCP7HDsN9r/z33WGjMqq6fZJwwdoKX3+0Zdj+MSaB0sQu66sLQbPHe74k9x+6oRft2/kLQgFy2IgrA==
+"@dzlzv/hydra-typegen@3.0.0-beta.6":
+  version "3.0.0-beta.6"
+  resolved "https://registry.yarnpkg.com/@dzlzv/hydra-typegen/-/hydra-typegen-3.0.0-beta.6.tgz#665364fdde787a293df58196f81abd517847e976"
+  integrity sha512-mYDh3G8tHjPIy6lUhXS2lNNOs27SxW580ODd3Ib87sR/scHv3Xmdv2Tgcu3lDj367MeKfhQ0hRfFDdLZnxaHeA==
   dependencies:
     "@oclif/command" "^1.8.0"
     "@oclif/config" "^1"
     "@oclif/errors" "^1.3.3"
-    "@polkadot/api" "^2.10.1"
+    "@polkadot/api" "4.2.1"
     debug "^4.3.1"
     handlebars "^4.7.6"
     lodash "^4.17.20"
@@ -300,196 +302,236 @@
   resolved "https://registry.yarnpkg.com/@oclif/screen/-/screen-1.0.4.tgz#b740f68609dfae8aa71c3a6cab15d816407ba493"
   integrity sha512-60CHpq+eqnTxLZQ4PGHYNwUX572hgpMHGPtTWMjdTMsAvlm69lZV/4ly6O3sAYkomo4NggGcomrDpBe34rxUqw==
 
-"@polkadot/api-derive@2.10.1":
-  version "2.10.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-2.10.1.tgz#6dc6c0030e036e8a38d44b7e06fd884e9c1b32fb"
-  integrity sha512-cMbXrOyHWJ/uLxNiAjmRa6a8WM/FEDMansWbQGJtN7ebHrJD3t1SE53aM4zgD+AgaEJgPAUfI5RuOrEzxDDTdw==
-  dependencies:
-    "@babel/runtime" "^7.12.5"
-    "@polkadot/api" "2.10.1"
-    "@polkadot/rpc-core" "2.10.1"
-    "@polkadot/types" "2.10.1"
-    "@polkadot/util" "^4.2.1"
-    "@polkadot/util-crypto" "^4.2.1"
+"@polkadot/api-derive@4.2.1":
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-4.2.1.tgz#848a2a9ef947f08660af2571f72ca2b06969f2e3"
+  integrity sha512-TQqhK356IEk7ksMDE/tA3ZKqFEI8O8virZItd/w+RFaBs/HfbDNP8p+xPM5+6Rif3kuBzdubMv3Bdq/OIAJc6g==
+  dependencies:
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/api" "4.2.1"
+    "@polkadot/rpc-core" "4.2.1"
+    "@polkadot/types" "4.2.1"
+    "@polkadot/util" "^6.0.5"
+    "@polkadot/util-crypto" "^6.0.5"
+    "@polkadot/x-rxjs" "^6.0.5"
     bn.js "^4.11.9"
-    memoizee "^0.4.14"
-    rxjs "^6.6.3"
-
-"@polkadot/api@2.10.1", "@polkadot/api@^2.10.1":
-  version "2.10.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-2.10.1.tgz#750987bccbf8e607c3690a7bdfed818bfc2c7571"
-  integrity sha512-C/vd5eGK3SDpPBWfs6tbNJM6uKpThE9GiTs5Lb5yR83J2ssvnZnn4qGOoEZnpPH+2iW7hVS4GR5sE9YcZxUXTg==
-  dependencies:
-    "@babel/runtime" "^7.12.5"
-    "@polkadot/api-derive" "2.10.1"
-    "@polkadot/keyring" "^4.2.1"
-    "@polkadot/metadata" "2.10.1"
-    "@polkadot/rpc-core" "2.10.1"
-    "@polkadot/rpc-provider" "2.10.1"
-    "@polkadot/types" "2.10.1"
-    "@polkadot/types-known" "2.10.1"
-    "@polkadot/util" "^4.2.1"
-    "@polkadot/util-crypto" "^4.2.1"
+
+"@polkadot/api@4.2.1":
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-4.2.1.tgz#8eb0997dc148a34a4aca3a0dcaabad9954565909"
+  integrity sha512-PbXwcLnZr5V5LfKsovMS0TRG+rfJp8lJxluCyOSABDpaz2h1B5R8rdYEZCmXI3qSrT0yu2C6Pp8AjTQHRd7SAA==
+  dependencies:
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/api-derive" "4.2.1"
+    "@polkadot/keyring" "^6.0.5"
+    "@polkadot/metadata" "4.2.1"
+    "@polkadot/rpc-core" "4.2.1"
+    "@polkadot/rpc-provider" "4.2.1"
+    "@polkadot/types" "4.2.1"
+    "@polkadot/types-known" "4.2.1"
+    "@polkadot/util" "^6.0.5"
+    "@polkadot/util-crypto" "^6.0.5"
+    "@polkadot/x-rxjs" "^6.0.5"
     bn.js "^4.11.9"
     eventemitter3 "^4.0.7"
-    rxjs "^6.6.3"
 
-"@polkadot/keyring@^4.2.1":
+"@polkadot/keyring@^6.0.5":
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-6.1.1.tgz#937103e3c98bb92942f91502577fcc3b6bcd4aef"
+  integrity sha512-gpOJ8L7MyuFe9/bYOJ+0qIXZIqob1IMl1xrsULTlF03ijENv7XvMeUUf6hN8hbxkgEWugow060M7SUnLQ4zTTA==
+  dependencies:
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/util" "6.1.1"
+    "@polkadot/util-crypto" "6.1.1"
+
+"@polkadot/metadata@4.2.1":
   version "4.2.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-4.2.1.tgz#34bf18ae8cb5822f2ea522c8db62dd0086725ffa"
-  integrity sha512-8kH8jXSIA3I2Gn96o7KjGoLBa7fmc2iB/VKOmEEcMCgJR32HyE8YbeXwc/85OQCheQjG4rJA3RxPQ4CsTsjO7w==
-  dependencies:
-    "@babel/runtime" "^7.12.5"
-    "@polkadot/util" "4.2.1"
-    "@polkadot/util-crypto" "4.2.1"
-
-"@polkadot/metadata@2.10.1":
-  version "2.10.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/metadata/-/metadata-2.10.1.tgz#bea4696c8773af4214c071ab5017bef215d978c1"
-  integrity sha512-ilB81k4ZDFVLHYo8mhxs9VFpL7Vi/Q0tqTSuQ+ziD3U7fYh0QV5si+1nqo5EBzvIKws6hsC7B4bTPQLJHHTC9w==
-  dependencies:
-    "@babel/runtime" "^7.12.5"
-    "@polkadot/types" "2.10.1"
-    "@polkadot/types-known" "2.10.1"
-    "@polkadot/util" "^4.2.1"
-    "@polkadot/util-crypto" "^4.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/metadata/-/metadata-4.2.1.tgz#7bff99e44992708469e7b2aa70d0865637d8febe"
+  integrity sha512-oXuKOrKTU0wys5pedKd1OVUDWK8/NoBRCrUYN8fxq3Qq/J9Sz6lF4ZbgX3w22C75l1z2+acsebiZBwlpWgKeqw==
+  dependencies:
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/types" "4.2.1"
+    "@polkadot/types-known" "4.2.1"
+    "@polkadot/util" "^6.0.5"
+    "@polkadot/util-crypto" "^6.0.5"
     bn.js "^4.11.9"
 
-"@polkadot/networks@4.2.1":
+"@polkadot/networks@6.1.1", "@polkadot/networks@^6.0.5":
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-6.1.1.tgz#7725b75a421e80ad6bc152c6ba0e0b5f82153939"
+  integrity sha512-QJynYW/S00UT9R59w+RPPhUG7zCQURqCDwyJQWKc+yWxnVacBFKvtokrCbYZIViE1lMY4FvdA6blUT3eYmABYg==
+  dependencies:
+    "@babel/runtime" "^7.13.10"
+
+"@polkadot/rpc-core@4.2.1":
   version "4.2.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-4.2.1.tgz#b0ca69807ed60189f1c958bb27cfeb3cb1c6b12b"
-  integrity sha512-T1tg0V0uG09Vdce2O4KfEcWO3/fZh4VYt0bmJ6iPwC+x6yv939X2BKvuFTDDVNT3fqBpGzWQlwiTXYQ15o9bGA==
-  dependencies:
-    "@babel/runtime" "^7.12.5"
-
-"@polkadot/rpc-core@2.10.1":
-  version "2.10.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-2.10.1.tgz#6d9cca349dc03324dbf9c3bfe2a9db555808a664"
-  integrity sha512-oyEEhSwlKW3FNO5v7MJYSoiF5kIxcJKMKVJSIpLHp6G2oHhgKRZtsGlX4n6QJYxIBWb0EueewpkuEMCGAv3R7g==
-  dependencies:
-    "@babel/runtime" "^7.12.5"
-    "@polkadot/metadata" "2.10.1"
-    "@polkadot/rpc-provider" "2.10.1"
-    "@polkadot/types" "2.10.1"
-    "@polkadot/util" "^4.2.1"
-    memoizee "^0.4.14"
-    rxjs "^6.6.3"
-
-"@polkadot/rpc-provider@2.10.1":
-  version "2.10.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-2.10.1.tgz#7929b5aa8899033ba127984b4411baef92a1232d"
-  integrity sha512-VvrFedxIbPrcm3CadZLdVwm3eWyyaZV1Sh0BSGZ2u9Pi2JkONshWrg7mf32SbKhckXWt/BNwUnpCQfIUjnKaDw==
-  dependencies:
-    "@babel/runtime" "^7.12.5"
-    "@polkadot/types" "2.10.1"
-    "@polkadot/util" "^4.2.1"
-    "@polkadot/util-crypto" "^4.2.1"
-    "@polkadot/x-fetch" "^4.2.1"
-    "@polkadot/x-ws" "^4.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-4.2.1.tgz#249f2e8f359450e365b0784d494814c7348e9a3e"
+  integrity sha512-A67Rt7lFpdauj7O7fRGn9yhII0SpCRJ/NkHWKo/whj8RwIAuOdxLnekGC9Qr26FPi0mAqN5DBQ8vYSDUiLFXxA==
+  dependencies:
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/metadata" "4.2.1"
+    "@polkadot/rpc-provider" "4.2.1"
+    "@polkadot/types" "4.2.1"
+    "@polkadot/util" "^6.0.5"
+    "@polkadot/x-rxjs" "^6.0.5"
+
+"@polkadot/rpc-provider@4.2.1":
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-4.2.1.tgz#2dbb217773a57fde2a70fc15628e2682e3ac81f8"
+  integrity sha512-Gwfs6JAD4Sp+Uz1kEtBSt1P6C3Lwn9xZ64CupU1/6w3qj9QzTFOKHKoznnekiH5HXSh53qVz2c2OSXptSrwL0Q==
+  dependencies:
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/types" "4.2.1"
+    "@polkadot/util" "^6.0.5"
+    "@polkadot/util-crypto" "^6.0.5"
+    "@polkadot/x-fetch" "^6.0.5"
+    "@polkadot/x-global" "^6.0.5"
+    "@polkadot/x-ws" "^6.0.5"
     bn.js "^4.11.9"
     eventemitter3 "^4.0.7"
 
-"@polkadot/types-known@2.10.1":
-  version "2.10.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-2.10.1.tgz#37bc032aae7db12e9a4480caf5aa65f619cffac9"
-  integrity sha512-RmnRPMoypxodfXRRqO+t4ogeaHTEC1S968+Djo8SYeSSmeUrlo9LdoJ5DZBXd0dTOUJbo0wXl9DOjL5qVnRy6A==
+"@polkadot/types-known@4.2.1":
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-4.2.1.tgz#0f1ccef363359de0370cd5b3cc3e6dfe51a18f38"
+  integrity sha512-/zbvzcCiv6yLhnikVWrN03uJk/3Vuer+sbK8G/pVtLOUhRYdDLOet7VPmRnjH9CGsEGJDQebu0zqW77npg5V2Q==
   dependencies:
-    "@babel/runtime" "^7.12.5"
-    "@polkadot/types" "2.10.1"
-    "@polkadot/util" "^4.2.1"
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/networks" "^6.0.5"
+    "@polkadot/types" "4.2.1"
+    "@polkadot/util" "^6.0.5"
     bn.js "^4.11.9"
 
-"@polkadot/types@2.10.1":
-  version "2.10.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-2.10.1.tgz#84189d508c28d375ec562a049aaf58aa34256a74"
-  integrity sha512-wRs9X7uiSRNQBFxcuCDv++FU+HgFml55U73zsqxDgBb7+bor4QGLPpki8rV+xQOpqhfPjKHN1gosK99sFcC3Aw==
-  dependencies:
-    "@babel/runtime" "^7.12.5"
-    "@polkadot/metadata" "2.10.1"
-    "@polkadot/util" "^4.2.1"
-    "@polkadot/util-crypto" "^4.2.1"
+"@polkadot/types@4.2.1":
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-4.2.1.tgz#7be97d3abda4bb3f9031b43602062ed464596696"
+  integrity sha512-xl8QnbXiJmSm6MUZH/U/ov3ZSXMN+KgNjsTCCzfz2xR5B3eK9ClYcstYYkNSyF12K90Gut9bnNSGZvaCfT2hNQ==
+  dependencies:
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/metadata" "4.2.1"
+    "@polkadot/util" "^6.0.5"
+    "@polkadot/util-crypto" "^6.0.5"
+    "@polkadot/x-rxjs" "^6.0.5"
     "@types/bn.js" "^4.11.6"
     bn.js "^4.11.9"
-    memoizee "^0.4.14"
-    rxjs "^6.6.3"
 
-"@polkadot/util-crypto@4.2.1", "@polkadot/util-crypto@^4.2.1":
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-4.2.1.tgz#a342cd6b400c69ed61cd929917030ed2f43c59d1"
-  integrity sha512-U1rCdzBQxVTA854HRpt2d4InDnPCfHD15JiWAwIzjBvq7i59EcTbVSqV02fcwet/KpmT3XYa25xoiff+alzCBA==
-  dependencies:
-    "@babel/runtime" "^7.12.5"
-    "@polkadot/networks" "4.2.1"
-    "@polkadot/util" "4.2.1"
-    "@polkadot/wasm-crypto" "^2.0.1"
-    "@polkadot/x-randomvalues" "4.2.1"
+"@polkadot/util-crypto@6.1.1", "@polkadot/util-crypto@^6.0.5":
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-6.1.1.tgz#dc9ee86656bbaf59b41c5a1cf40fa025b44aaf27"
+  integrity sha512-xKDqudvMCirQZ4df2PiWEdlNntNn5gUx/2gTNId7MoE4j4y0edLTwiQ6B2EgRCyLxCaIY+sw6Z5NL5ik1NHdcw==
+  dependencies:
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/networks" "6.1.1"
+    "@polkadot/util" "6.1.1"
+    "@polkadot/wasm-crypto" "^4.0.2"
+    "@polkadot/x-randomvalues" "6.1.1"
     base-x "^3.0.8"
+    base64-js "^1.5.1"
     blakejs "^1.1.0"
     bn.js "^4.11.9"
     create-hash "^1.2.0"
-    elliptic "^6.5.3"
+    elliptic "^6.5.4"
     hash.js "^1.1.7"
     js-sha3 "^0.8.0"
     scryptsy "^2.1.0"
     tweetnacl "^1.0.3"
     xxhashjs "^0.2.2"
 
-"@polkadot/util@4.2.1", "@polkadot/util@^4.2.1":
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-4.2.1.tgz#1845d03be7e418a14ec2ef929d6288f326f2145d"
-  integrity sha512-eO/IFbSDjqVPPWPnARDFydy2Kt992Th+8ByleTkCRqWk0aNYaseO1pGKNdwrYbLfUR3JlyWqvJ60lITeS+qAfQ==
+"@polkadot/util@6.1.1", "@polkadot/util@^6.0.5":
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-6.1.1.tgz#d4ab0bf8f0d38f60b93124e7efb4339c16d0b1a1"
+  integrity sha512-xdm2UF6SIjW50jnIyzT1+m1sLBjulExDAo+7JnrTZe4OQfUL8JyQzJ3jdy9hFNBHjXkLRENc94DR4HSJ+n3Uyg==
   dependencies:
-    "@babel/runtime" "^7.12.5"
-    "@polkadot/x-textdecoder" "4.2.1"
-    "@polkadot/x-textencoder" "4.2.1"
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/x-textdecoder" "6.1.1"
+    "@polkadot/x-textencoder" "6.1.1"
     "@types/bn.js" "^4.11.6"
     bn.js "^4.11.9"
     camelcase "^5.3.1"
-    ip-regex "^4.2.0"
+    ip-regex "^4.3.0"
 
-"@polkadot/wasm-crypto@^2.0.1":
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-2.0.1.tgz#cf7384385f832f6389520cc00e52a87fda6f29b6"
-  integrity sha512-Vb0q4NToCRHXYJwhLWc4NTy77+n1dtJmkiE1tt8j1pmY4IJ4UL25yBxaS8NCS1LGqofdUYK1wwgrHiq5A78PFA==
+"@polkadot/wasm-crypto-asmjs@^4.0.2":
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-4.0.2.tgz#f42c353a64e1243841daf90e4bd54eff01a4e3cf"
+  integrity sha512-hlebqtGvfjg2ZNm4scwBGVHwOwfUhy2yw5RBHmPwkccUif3sIy4SAzstpcVBIVMdAEvo746bPWEInA8zJRcgJA==
+  dependencies:
+    "@babel/runtime" "^7.13.9"
 
-"@polkadot/x-fetch@^4.2.1":
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-4.2.1.tgz#6cd157da6f98f97395c3f01849ccdd3de23ee44f"
-  integrity sha512-dfVYvCQQXo2AgoWPi4jQp47eIMjAi6glQQ8Y1OsK4sCqmX7BSkNl9ONUKQuH27oi0BkJ/BL7fwDg55JeB5QrKg==
+"@polkadot/wasm-crypto-wasm@^4.0.2":
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-4.0.2.tgz#89f9e0a1e4d076784d4a42bea37fc8b06bdd8bb6"
+  integrity sha512-de/AfNPZ0uDKFWzOZ1rJCtaUbakGN29ks6IRYu6HZTRg7+RtqvE1rIkxabBvYgQVHIesmNwvEA9DlIkS6hYRFQ==
+  dependencies:
+    "@babel/runtime" "^7.13.9"
+
+"@polkadot/wasm-crypto@^4.0.2":
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-4.0.2.tgz#9649057adee8383cc86433d107ba526b718c5a3b"
+  integrity sha512-2h9FuQFkBc+B3TwSapt6LtyPvgtd0Hq9QsHW8g8FrmKBFRiiFKYRpfJKHCk0aCZzuRf9h95bQl/X6IXAIWF2ng==
+  dependencies:
+    "@babel/runtime" "^7.13.9"
+    "@polkadot/wasm-crypto-asmjs" "^4.0.2"
+    "@polkadot/wasm-crypto-wasm" "^4.0.2"
+
+"@polkadot/x-fetch@^6.0.5":
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-6.1.1.tgz#433300cd6c9ca98c8e610e34bf30922f480879d9"
+  integrity sha512-9idoVhFjEZYTRhufqqVXSParVebRwTCGYhZx2yYsF5R9+BKS/noTSBBtOmhdICtCT9evl3xgUdZkiiGVfD6sJw==
   dependencies:
-    "@babel/runtime" "^7.12.5"
-    "@types/node-fetch" "^2.5.7"
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/x-global" "6.1.1"
+    "@types/node-fetch" "^2.5.10"
     node-fetch "^2.6.1"
 
-"@polkadot/x-randomvalues@4.2.1":
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-4.2.1.tgz#91fd272f8bb79a59b20055a4514f944888a6ee76"
-  integrity sha512-eOfz/KnHYFVl9l0zlhlwomKMzFASgolaQV6uXSN38np+99/+F38wlbOSXFbfZ5H3vmMCt4y/UUTLtoGV/44yLg==
+"@polkadot/x-global@6.1.1", "@polkadot/x-global@^6.0.5":
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-6.1.1.tgz#c9dab736cb0ff3274bebabeb5a9f1c57d126b73c"
+  integrity sha512-h/5K2i8S7oteQITD2aF3Scxd7uOPH4HaBk/DDiM7M89TvzMp+QLISkBapK2boAKRejceKULuKlFVKFGzryF1NA==
   dependencies:
-    "@babel/runtime" "^7.12.5"
+    "@babel/runtime" "^7.13.10"
+    "@types/node-fetch" "^2.5.10"
+    node-fetch "^2.6.1"
 
-"@polkadot/x-textdecoder@4.2.1":
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-4.2.1.tgz#c2fe9f5da9498d982f8fd9244a52e039c0f0dacc"
-  integrity sha512-B5t20PryMKr7kdd7q+kmzJPU01l28ZDD06cQ/ZFkybI7avI6PIz/U33ctXxiHOatbBRO6Ez8uzrWd3JmaQ2bGQ==
+"@polkadot/x-randomvalues@6.1.1":
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-6.1.1.tgz#e57a31bc51513c88fd8228a24a154b5e426dcff1"
+  integrity sha512-b6IFmV64YdyWwWYnnqD/piQALRA4Xs/eQklBaldoBzg/INTWx8sA3M43HUOZlmcY4TLNAOG8mBxzrDmsFj3Ezw==
   dependencies:
-    "@babel/runtime" "^7.12.5"
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/x-global" "6.1.1"
 
-"@polkadot/x-textencoder@4.2.1":
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-4.2.1.tgz#cf6b92d7de0fb2dde8314e0f359dd83dc9f25036"
-  integrity sha512-EHc6RS9kjdP28q6EYlSgHF2MrJCdOTc5EVlqHL7V1UKLh3vD6QaWGYBwbzXNFPXO3RYPO/DKYCu4RxAVSM1OOg==
+"@polkadot/x-rxjs@^6.0.5":
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-rxjs/-/x-rxjs-6.1.1.tgz#dae950f5034c3f357baaea9ad5be3ac6e990c49f"
+  integrity sha512-Hfpb3aIQkVlGM2bknMVZBudW2F7t5TJepPiiLoHJKA6IJ8mpQYZAUOQMUMt/teM8Ni4fTNGqrCGgR/xLm62mRA==
   dependencies:
-    "@babel/runtime" "^7.12.5"
+    "@babel/runtime" "^7.13.10"
+    rxjs "^6.6.7"
 
-"@polkadot/x-ws@^4.2.1":
-  version "4.2.1"
-  resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-4.2.1.tgz#f160a0c61227419b1d7da623a72ce21063ef69ee"
-  integrity sha512-7L1ve2rshBFI/00/0zkX1k0OP/rSD6Tp0Mj/GSg2UvnsmUb2Bb3OpwUJ4aTDr1En6OVGWj9c0fNO0tZR7rtoYA==
+"@polkadot/x-textdecoder@6.1.1":
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-6.1.1.tgz#b19bfc375224c8c4069a6d69bc813419b1715942"
+  integrity sha512-z4a91pNkD6WNDp+Jl4nf6kLM5ZM1x5Zmrrs2qDmX3WP+/okJUb5J+RYXSDnPnKeuoyQHHV0cNuWos5nQZxmmrA==
+  dependencies:
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/x-global" "6.1.1"
+
+"@polkadot/x-textencoder@6.1.1":
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-6.1.1.tgz#1963034091398e93465ec2709d68ced88008a62e"
+  integrity sha512-NLL9HxigxKeI30X89z40m6DWu1RrL9mZvXwLbl5Se1ditNsOK5/3+gBSlLqZiuB7LuY0YJCCbkqMSp/mAANglA==
   dependencies:
-    "@babel/runtime" "^7.12.5"
-    "@types/websocket" "^1.0.1"
-    websocket "^1.0.32"
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/x-global" "6.1.1"
+
+"@polkadot/x-ws@^6.0.5":
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-6.1.1.tgz#a1685366c2ee741968dcbcf35787d23b6db84a5a"
+  integrity sha512-deUXlOeTiPPukc5B/KwNg24xGSuTOqCE1SF5CjLX2R4e/ypjcjjO34zmmTHPEQBH4ms5t1amwRwyg8WYDXwARw==
+  dependencies:
+    "@babel/runtime" "^7.13.10"
+    "@polkadot/x-global" "6.1.1"
+    "@types/websocket" "^1.0.2"
+    websocket "^1.0.33"
 
 "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
   version "1.1.2"
@@ -617,6 +659,11 @@
     "@types/keygrip" "*"
     "@types/node" "*"
 
+"@types/copyfiles@^2.4.0":
+  version "2.4.0"
+  resolved "https://registry.yarnpkg.com/@types/copyfiles/-/copyfiles-2.4.0.tgz#877ef9aa9def7df889fb1ca900206c79a873d113"
+  integrity sha512-ujm66wtJzW0ok5bIfwSZdvI4C4E6rbAvG58zow71wLjPPj65rIMu4Uy5LOx5H4eRvaagGUrrKTxqfLiDSsHEGQ==
+
 "@types/cors@2.8.8":
   version "2.8.8"
   resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.8.tgz#317a8d8561995c60e35b9e0fcaa8d36660c98092"
@@ -825,10 +872,10 @@
     "@types/node" "*"
     form-data "^3.0.0"
 
-"@types/node-fetch@^2.5.7":
-  version "2.5.8"
-  resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.8.tgz#e199c835d234c7eb0846f6618012e558544ee2fb"
-  integrity sha512-fbjI6ja0N5ZA8TV53RUqzsKNkl9fv8Oj3T7zxW7FGv1GSH7gwJaNF8dzCjrqKaxKeUpTz4yT1DaJFq/omNpGfw==
+"@types/node-fetch@^2.5.10":
+  version "2.5.10"
+  resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.10.tgz#9b4d4a0425562f9fcea70b12cb3fcdd946ca8132"
+  integrity sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ==
   dependencies:
     "@types/node" "*"
     form-data "^3.0.0"
@@ -912,7 +959,7 @@
   resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.1.3.tgz#366b394aa3fbeed2392bf0a20ded606fa4a3d35e"
   integrity sha512-DaOWN1zf7j+8nHhqXhIgNmS+ltAC53NXqGxYuBhWqWgqolRhddKzfZU814lkHQSTG0IUfQxU7Cg0gb8fFWo2mA==
 
-"@types/websocket@^1.0.1":
+"@types/websocket@^1.0.2":
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.2.tgz#d2855c6a312b7da73ed16ba6781815bf30c6187a"
   integrity sha512-B5m9aq7cbbD/5/jThEr33nUY8WEfVi6A2YKCTOvw5Ldy7mtsOkqRvGjnzy6g7iMMDsgu7xREuCzqATLDLQVKcQ==
@@ -1308,7 +1355,7 @@ base-x@^3.0.8:
   dependencies:
     safe-buffer "^5.0.1"
 
-base64-js@^1.3.1:
+base64-js@^1.3.1, base64-js@^1.5.1:
   version "1.5.1"
   resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
   integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
@@ -1328,6 +1375,11 @@ bn.js@^4.11.9:
   resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
   integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
 
+bn.js@^5.2.0:
+  version "5.2.0"
+  resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002"
+  integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==
+
 body-parser@1.19.0, body-parser@^1.18.3:
   version "1.19.0"
   resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a"
@@ -1717,11 +1769,29 @@ cookie@0.4.0:
   resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
   integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
 
+copyfiles@^2.4.1:
+  version "2.4.1"
+  resolved "https://registry.yarnpkg.com/copyfiles/-/copyfiles-2.4.1.tgz#d2dcff60aaad1015f09d0b66e7f0f1c5cd3c5da5"
+  integrity sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==
+  dependencies:
+    glob "^7.0.5"
+    minimatch "^3.0.3"
+    mkdirp "^1.0.4"
+    noms "0.0.0"
+    through2 "^2.0.1"
+    untildify "^4.0.0"
+    yargs "^16.1.0"
+
 core-js@^3.0.1:
   version "3.9.1"
   resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.9.1.tgz#cec8de593db8eb2a85ffb0dbdeb312cb6e5460ae"
   integrity sha512-gSjRvzkxQc1zjM/5paAmL4idJBFzuJoo+jDjF1tStYFMV2ERfD02HhahhCGXUyHxQRG4yFKVSdO6g62eoRMcDg==
 
+core-util-is@~1.0.0:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
+  integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
+
 cors@^2.8.4:
   version "2.8.5"
   resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
@@ -1920,7 +1990,7 @@ elegant-spinner@^1.0.1:
   resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
   integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=
 
-elliptic@^6.5.3:
+elliptic@^6.5.4:
   version "6.5.4"
   resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
   integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
@@ -2000,7 +2070,7 @@ es-to-primitive@^1.2.1:
     is-date-object "^1.0.1"
     is-symbol "^1.0.2"
 
-es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46:
+es5-ext@^0.10.35, es5-ext@^0.10.50:
   version "0.10.53"
   resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1"
   integrity sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==
@@ -2009,7 +2079,7 @@ es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@
     es6-symbol "~3.1.3"
     next-tick "~1.0.0"
 
-es6-iterator@^2.0.3, es6-iterator@~2.0.3:
+es6-iterator@~2.0.3:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7"
   integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c=
@@ -2026,16 +2096,6 @@ es6-symbol@^3.1.1, es6-symbol@~3.1.3:
     d "^1.0.1"
     ext "^1.1.2"
 
-es6-weak-map@^2.0.3:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53"
-  integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==
-  dependencies:
-    d "1"
-    es5-ext "^0.10.46"
-    es6-iterator "^2.0.3"
-    es6-symbol "^3.1.1"
-
 escalade@^3.1.1:
   version "3.1.1"
   resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
@@ -2066,14 +2126,6 @@ etag@~1.8.1:
   resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
   integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
 
-event-emitter@^0.3.5:
-  version "0.3.5"
-  resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
-  integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=
-  dependencies:
-    d "1"
-    es5-ext "~0.10.14"
-
 eventemitter3@^3.1.0:
   version "3.1.2"
   resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7"
@@ -2380,7 +2432,7 @@ glob-parent@^5.1.0:
   dependencies:
     is-glob "^4.0.1"
 
-glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
+glob@^7.0.5, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
   version "7.1.6"
   resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
   integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
@@ -2742,7 +2794,7 @@ inflight@^1.0.4:
     once "^1.3.0"
     wrappy "1"
 
-inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4:
+inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3:
   version "2.0.4"
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
   integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -2762,7 +2814,7 @@ invert-kv@^2.0.0:
   resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
   integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
 
-ip-regex@^4.2.0:
+ip-regex@^4.3.0:
   version "4.3.0"
   resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5"
   integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==
@@ -2874,7 +2926,7 @@ is-plain-object@3.0.0:
   dependencies:
     isobject "^4.0.0"
 
-is-promise@^2.1.0, is-promise@^2.2.2:
+is-promise@^2.1.0:
   version "2.2.2"
   resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1"
   integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==
@@ -2931,6 +2983,16 @@ is-wsl@^2.1.1, is-wsl@^2.2.0:
   dependencies:
     is-docker "^2.0.0"
 
+isarray@0.0.1:
+  version "0.0.1"
+  resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
+  integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
+
+isarray@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
+  integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
+
 isexe@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@@ -3268,13 +3330,6 @@ lru-cache@^6.0.0:
   dependencies:
     yallist "^4.0.0"
 
-lru-queue@^0.1.0:
-  version "0.1.0"
-  resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3"
-  integrity sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=
-  dependencies:
-    es5-ext "~0.10.2"
-
 make-error@^1.1.1:
   version "1.3.6"
   resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
@@ -3310,20 +3365,6 @@ mem@^4.0.0:
     mimic-fn "^2.0.0"
     p-is-promise "^2.0.0"
 
-memoizee@^0.4.14:
-  version "0.4.15"
-  resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.15.tgz#e6f3d2da863f318d02225391829a6c5956555b72"
-  integrity sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==
-  dependencies:
-    d "^1.0.1"
-    es5-ext "^0.10.53"
-    es6-weak-map "^2.0.3"
-    event-emitter "^0.3.5"
-    is-promise "^2.2.2"
-    lru-queue "^0.1.0"
-    next-tick "^1.1.0"
-    timers-ext "^0.1.7"
-
 merge-descriptors@1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
@@ -3389,7 +3430,7 @@ minimalistic-crypto-utils@^1.0.1:
   resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
   integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
 
-minimatch@^3.0.2, minimatch@^3.0.4:
+minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
   version "3.0.4"
   resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
   integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
@@ -3467,11 +3508,6 @@ neo-async@^2.6.0:
   resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
   integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
 
-next-tick@1, next-tick@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb"
-  integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==
-
 next-tick@~1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
@@ -3499,6 +3535,14 @@ node-gyp-build@^4.2.0:
   resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739"
   integrity sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==
 
+noms@0.0.0:
+  version "0.0.0"
+  resolved "https://registry.yarnpkg.com/noms/-/noms-0.0.0.tgz#da8ebd9f3af9d6760919b27d9cdc8092a7332859"
+  integrity sha1-2o69nzr51nYJGbJ9nNyAkqczKFk=
+  dependencies:
+    inherits "^2.0.1"
+    readable-stream "~1.0.31"
+
 normalize-package-data@^2.3.2:
   version "2.5.0"
   resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
@@ -3848,15 +3892,10 @@ pg-int8@1.0.1:
   resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c"
   integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==
 
-pg-packet-stream@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/pg-packet-stream/-/pg-packet-stream-1.1.0.tgz#e45c3ae678b901a2873af1e17b92d787962ef914"
-  integrity sha512-kRBH0tDIW/8lfnnOyTwKD23ygJ/kexQVXZs7gEyBljw4FYqimZFxnMMx50ndZ8In77QgfGuItS5LLclC2TtjYg==
-
-pg-pool@^2.0.10:
-  version "2.0.10"
-  resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-2.0.10.tgz#842ee23b04e86824ce9d786430f8365082d81c4a"
-  integrity sha512-qdwzY92bHf3nwzIUcj+zJ0Qo5lpG/YxchahxIN8+ZVmXqkahKXsnl2aiJPHLYN9o5mB/leG+Xh6XKxtP7e0sjg==
+pg-pool@^3.1.1:
+  version "3.3.0"
+  resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.3.0.tgz#12d5c7f65ea18a6e99ca9811bd18129071e562fc"
+  integrity sha512-0O5huCql8/D6PIRFAlmccjphLYWC+JIzvUhSzXSpGaf+tjTZc4nn+Lr7mLXBbFJfvwbP0ywDv73EiaBsxn7zdg==
 
 pg-pool@^3.2.2:
   version "3.2.2"
@@ -3868,6 +3907,11 @@ pg-protocol@^1.2.0, pg-protocol@^1.4.0:
   resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.4.0.tgz#43a71a92f6fe3ac559952555aa3335c8cb4908be"
   integrity sha512-El+aXWcwG/8wuFICMQjM5ZSAm6OWiJicFdNYo+VY3QP+8vI4SvLIWVe51PppTzMhikUJR+PsyIFKqfdXPz/yxA==
 
+pg-protocol@^1.2.2:
+  version "1.5.0"
+  resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.5.0.tgz#b5dd452257314565e2d54ab3c132adc46565a6a0"
+  integrity sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ==
+
 pg-types@^2.1.0, pg-types@^2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3"
@@ -3879,16 +3923,16 @@ pg-types@^2.1.0, pg-types@^2.2.0:
     postgres-date "~1.0.4"
     postgres-interval "^1.1.0"
 
-pg@^7.12.1:
-  version "7.18.2"
-  resolved "https://registry.yarnpkg.com/pg/-/pg-7.18.2.tgz#4e219f05a00aff4db6aab1ba02f28ffa4513b0bb"
-  integrity sha512-Mvt0dGYMwvEADNKy5PMQGlzPudKcKKzJds/VbOeZJpb6f/pI3mmoXX0JksPgI3l3JPP/2Apq7F36O63J7mgveA==
+pg@8.0.3:
+  version "8.0.3"
+  resolved "https://registry.yarnpkg.com/pg/-/pg-8.0.3.tgz#b220ee468a1819e1c7e9ca9878f8ae50ba8e1952"
+  integrity sha512-fvcNXn4o/iq4jKq15Ix/e58q3jPSmzOp6/8C3CaHoSR/bsxdg+1FXfDRePdtE/zBb3++TytvOrS1hNef3WC/Kg==
   dependencies:
     buffer-writer "2.0.0"
     packet-reader "1.0.0"
     pg-connection-string "0.1.3"
-    pg-packet-stream "^1.1.0"
-    pg-pool "^2.0.10"
+    pg-pool "^3.1.1"
+    pg-protocol "^1.2.2"
     pg-types "^2.1.0"
     pgpass "1.x"
     semver "4.3.2"
@@ -3987,6 +4031,11 @@ prettier@^1.19.1:
   resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
   integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
 
+process-nextick-args@~2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
+  integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
+
 proxy-addr@~2.0.5:
   version "2.0.6"
   resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf"
@@ -4071,6 +4120,29 @@ readable-stream@^3.0.0, readable-stream@^3.6.0:
     string_decoder "^1.1.1"
     util-deprecate "^1.0.1"
 
+readable-stream@~1.0.31:
+  version "1.0.34"
+  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c"
+  integrity sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=
+  dependencies:
+    core-util-is "~1.0.0"
+    inherits "~2.0.1"
+    isarray "0.0.1"
+    string_decoder "~0.10.x"
+
+readable-stream@~2.3.6:
+  version "2.3.7"
+  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
+  integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
+  dependencies:
+    core-util-is "~1.0.0"
+    inherits "~2.0.3"
+    isarray "~1.0.0"
+    process-nextick-args "~2.0.0"
+    safe-buffer "~5.1.1"
+    string_decoder "~1.1.1"
+    util-deprecate "~1.0.1"
+
 redeyed@~2.1.0:
   version "2.1.1"
   resolved "https://registry.yarnpkg.com/redeyed/-/redeyed-2.1.1.tgz#8984b5815d99cb220469c99eeeffe38913e6cc0b"
@@ -4176,14 +4248,21 @@ run-parallel@^1.1.9:
   dependencies:
     queue-microtask "^1.2.2"
 
-rxjs@^6.3.3, rxjs@^6.5.1, rxjs@^6.6.3:
+rxjs@^6.3.3, rxjs@^6.5.1:
   version "6.6.6"
   resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.6.tgz#14d8417aa5a07c5e633995b525e1e3c0dec03b70"
   integrity sha512-/oTwee4N4iWzAMAL9xdGKjkEHmIwupR3oXbQjCKywF1BeFohswF3vZdogbmEF6pZkOsXTzWkrZszrWpQTByYVg==
   dependencies:
     tslib "^1.9.0"
 
-safe-buffer@5.1.2:
+rxjs@^6.6.7:
+  version "6.6.7"
+  resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"
+  integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==
+  dependencies:
+    tslib "^1.9.0"
+
+safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
   version "5.1.2"
   resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
   integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
@@ -4452,6 +4531,18 @@ string_decoder@^1.1.1:
   dependencies:
     safe-buffer "~5.2.0"
 
+string_decoder@~0.10.x:
+  version "0.10.31"
+  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
+  integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
+
+string_decoder@~1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
+  integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
+  dependencies:
+    safe-buffer "~5.1.0"
+
 strip-ansi@^3.0.0, strip-ansi@^3.0.1:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
@@ -4559,13 +4650,13 @@ thenify-all@^1.0.0:
   dependencies:
     any-promise "^1.0.0"
 
-timers-ext@^0.1.7:
-  version "0.1.7"
-  resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6"
-  integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==
+through2@^2.0.1:
+  version "2.0.5"
+  resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
+  integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==
   dependencies:
-    es5-ext "~0.10.46"
-    next-tick "1"
+    readable-stream "~2.3.6"
+    xtend "~4.0.1"
 
 to-regex-range@^5.0.1:
   version "5.0.1"
@@ -4756,6 +4847,11 @@ unpipe@1.0.0, unpipe@~1.0.0:
   resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
   integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=
 
+untildify@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b"
+  integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
+
 utf-8-validate@^5.0.2:
   version "5.0.4"
   resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.4.tgz#72a1735983ddf7a05a43a9c6b67c5ce1c910f9b8"
@@ -4763,7 +4859,7 @@ utf-8-validate@^5.0.2:
   dependencies:
     node-gyp-build "^4.2.0"
 
-util-deprecate@^1.0.1:
+util-deprecate@^1.0.1, util-deprecate@~1.0.1:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
   integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
@@ -4817,9 +4913,9 @@ vary@^1, vary@~1.1.2:
   resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
   integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
 
-"warthog@https://github.com/metmirr/warthog/releases/download/v2.23.0/warthog-v2.23.0.tgz":
-  version "2.23.0"
-  resolved "https://github.com/metmirr/warthog/releases/download/v2.23.0/warthog-v2.23.0.tgz#4582fc35554580e0af0f43a9b3725aad2eb808c6"
+"warthog@https://github.com/metmirr/warthog/releases/download/v2.30.0/warthog-v2.30.0.tgz":
+  version "2.30.0"
+  resolved "https://github.com/metmirr/warthog/releases/download/v2.30.0/warthog-v2.30.0.tgz#24a0b975f2ad5cba17a934752ac07052e856b49c"
   dependencies:
     "@types/app-root-path" "^1.2.4"
     "@types/bn.js" "^4.11.6"
@@ -4847,6 +4943,7 @@ vary@^1, vary@~1.1.2:
     apollo-server "^2.9.9"
     apollo-server-express "^2.9.9"
     app-root-path "^3.0.0"
+    bn.js "^5.2.0"
     caller "^1.0.1"
     class-transformer "^0.2.3"
     class-validator "^0.11.0"
@@ -4869,7 +4966,7 @@ vary@^1, vary@~1.1.2:
     mkdirp "^0.5.1"
     node-emoji "^1.10.0"
     open "^7.0.0"
-    pg "^7.12.1"
+    pg "8.0.3"
     pgtools "^0.3.0"
     prettier "^1.19.1"
     reflect-metadata "^0.1.13"
@@ -4887,7 +4984,7 @@ wcwidth@^1.0.1:
   dependencies:
     defaults "^1.0.3"
 
-websocket@^1.0.32:
+websocket@^1.0.33:
   version "1.0.33"
   resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.33.tgz#407f763fc58e74a3fa41ca3ae5d78d3f5e3b82a5"
   integrity sha512-XwNqM2rN5eh3G2CUQE3OHZj+0xfdH42+OFK6LdC2yqiC0YU8e5UK0nYre220T0IyyN031V/XOvtHvXozvJYFWA==
@@ -5037,7 +5134,7 @@ xss@^1.0.8:
     commander "^2.20.3"
     cssfilter "0.0.10"
 
-xtend@^4.0.0:
+xtend@^4.0.0, xtend@~4.0.1:
   version "4.0.2"
   resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
   integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
@@ -5144,7 +5241,7 @@ yargs@^12.0.2:
     y18n "^3.2.1 || ^4.0.0"
     yargs-parser "^11.1.1"
 
-yargs@^16.0.0, yargs@^16.0.3:
+yargs@^16.0.0, yargs@^16.0.3, yargs@^16.1.0:
   version "16.2.0"
   resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
   integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==

+ 225 - 19
query-node/manifest.yml

@@ -1,11 +1,10 @@
-version: '0.1'
+version: '3.0'
 description: Joystream query-node manifest file for olympia
 repository: https://github.com/Joystream/joystream
-hydraVersion: "2"
+hydraVersion: "3"
 dataSource:
   kind: substrate
   chain: joystream
-  indexerVersion: '0.1.6'
 entities:
   - generated/graphql-server/dist/src/modules/**/*.model.js
 typegen:
@@ -18,12 +17,37 @@ typegen:
     - members.MemberVerificationStatusUpdated
     - members.InvitesTransferred
     - members.MemberInvited
+    - members.StakingAccountAdded
     - members.StakingAccountConfirmed
     - members.StakingAccountRemoved
     - members.InitialInvitationCountUpdated
     - members.MembershipPriceUpdated
     - members.ReferralCutUpdated
     - members.InitialInvitationBalanceUpdated
+    - members.LeaderInvitationQuotaUpdated
+    # Use Storage Working Group as a reference group (all groups emit the same events)
+    - storageWorkingGroup.OpeningAdded
+    - storageWorkingGroup.AppliedOnOpening
+    - storageWorkingGroup.OpeningFilled
+    - storageWorkingGroup.LeaderSet
+    - storageWorkingGroup.WorkerRoleAccountUpdated
+    - storageWorkingGroup.LeaderUnset
+    - storageWorkingGroup.WorkerStartedLeaving
+    - storageWorkingGroup.WorkerExited
+    - storageWorkingGroup.TerminatedWorker
+    - storageWorkingGroup.TerminatedLeader
+    - storageWorkingGroup.StakeSlashed
+    - storageWorkingGroup.StakeDecreased
+    - storageWorkingGroup.StakeIncreased
+    - storageWorkingGroup.ApplicationWithdrawn
+    - storageWorkingGroup.OpeningCanceled
+    - storageWorkingGroup.BudgetSet
+    - storageWorkingGroup.WorkerRewardAccountUpdated
+    - storageWorkingGroup.WorkerRewardAmountUpdated
+    - storageWorkingGroup.StatusTextChanged
+    - storageWorkingGroup.BudgetSpending
+    - storageWorkingGroup.RewardPaid
+    - storageWorkingGroup.NewMissedRewardLevelReached
   calls:
     - members.updateProfile
     - members.updateAccounts
@@ -32,40 +56,222 @@ typegen:
     lib: '@joystream/types/augment/all/types'
     typedefsLoc: '../types/augment/all/defs.json'
 mappings:
-  hydraCommonVersion: '0.0.3'
-  # process only blocks with height >= 1M
-  # blockInterval: '[1000000,]'
   # js module that exports the handler functions
-  mappingsModule: mappings/lib/mappings
+  mappingsModule: mappings/lib
   # additinal libraries the processor loads
   # typically it is a module with event and extrinsic types generated by hydra-typegen
   imports:
     - mappings/lib/generated/types
   eventHandlers:
+    # Membership module
     - event: members.MembershipBought
-      handler: members_MembershipBought(DatabaseManager, SubstrateEvent)
+      handler: members_MembershipBought
     - event: members.MemberProfileUpdated
-      handler: members_MemberProfileUpdated(DatabaseManager, SubstrateEvent)
+      handler: members_MemberProfileUpdated
     - event: members.MemberAccountsUpdated
-      handler: members_MemberAccountsUpdated(DatabaseManager, SubstrateEvent)
+      handler: members_MemberAccountsUpdated
     - event: members.MemberVerificationStatusUpdated
-      handler: members_MemberVerificationStatusUpdated(DatabaseManager, SubstrateEvent)
+      handler: members_MemberVerificationStatusUpdated
     - event: members.InvitesTransferred
-      handler: members_InvitesTransferred(DatabaseManager, SubstrateEvent)
+      handler: members_InvitesTransferred
     - event: members.MemberInvited
-      handler: members_MemberInvited(DatabaseManager, SubstrateEvent)
+      handler: members_MemberInvited
+    - event: members.StakingAccountAdded
+      handler: members_StakingAccountAdded
     - event: members.StakingAccountConfirmed
-      handler: members_StakingAccountConfirmed(DatabaseManager, SubstrateEvent)
+      handler: members_StakingAccountConfirmed
     - event: members.StakingAccountRemoved
-      handler: members_StakingAccountRemoved(DatabaseManager, SubstrateEvent)
+      handler: members_StakingAccountRemoved
     - event: members.InitialInvitationCountUpdated
-      handler: members_InitialInvitationCountUpdated(DatabaseManager, SubstrateEvent)
+      handler: members_InitialInvitationCountUpdated
     - event: members.MembershipPriceUpdated
-      handler: members_MembershipPriceUpdated(DatabaseManager, SubstrateEvent)
+      handler: members_MembershipPriceUpdated
     - event: members.ReferralCutUpdated
-      handler: members_ReferralCutUpdated(DatabaseManager, SubstrateEvent)
+      handler: members_ReferralCutUpdated
     - event: members.InitialInvitationBalanceUpdated
-      handler: members_InitialInvitationBalanceUpdated(DatabaseManager, SubstrateEvent)
+      handler: members_InitialInvitationBalanceUpdated
+    - event: members.LeaderInvitationQuotaUpdated
+      handler: members_LeaderInvitationQuotaUpdated
+    # Storage working group
+    - event: storageWorkingGroup.OpeningAdded
+      handler: workingGroups_OpeningAdded
+    - event: storageWorkingGroup.AppliedOnOpening
+      handler: workingGroups_AppliedOnOpening
+    - event: storageWorkingGroup.OpeningFilled
+      handler: workingGroups_OpeningFilled
+    - event: storageWorkingGroup.LeaderSet
+      handler: workingGroups_LeaderSet
+    - event: storageWorkingGroup.WorkerRoleAccountUpdated
+      handler: workingGroups_WorkerRoleAccountUpdated
+    - event: storageWorkingGroup.LeaderUnset
+      handler: workingGroups_LeaderUnset
+    - event: storageWorkingGroup.WorkerExited
+      handler: workingGroups_WorkerExited
+    - event: storageWorkingGroup.TerminatedWorker
+      handler: workingGroups_TerminatedWorker
+    - event: storageWorkingGroup.TerminatedLeader
+      handler: workingGroups_TerminatedLeader
+    - event: storageWorkingGroup.StakeSlashed
+      handler: workingGroups_StakeSlashed
+    - event: storageWorkingGroup.StakeDecreased
+      handler: workingGroups_StakeDecreased
+    - event: storageWorkingGroup.StakeIncreased
+      handler: workingGroups_StakeIncreased
+    - event: storageWorkingGroup.ApplicationWithdrawn
+      handler: workingGroups_ApplicationWithdrawn
+    - event: storageWorkingGroup.OpeningCanceled
+      handler: workingGroups_OpeningCanceled
+    - event: storageWorkingGroup.BudgetSet
+      handler: workingGroups_BudgetSet
+    - event: storageWorkingGroup.WorkerRewardAccountUpdated
+      handler: workingGroups_WorkerRewardAccountUpdated
+    - event: storageWorkingGroup.WorkerRewardAmountUpdated
+      handler: workingGroups_WorkerRewardAmountUpdated
+    - event: storageWorkingGroup.StatusTextChanged
+      handler: workingGroups_StatusTextChanged
+    - event: storageWorkingGroup.BudgetSpending
+      handler: workingGroups_BudgetSpending
+    - event: storageWorkingGroup.RewardPaid
+      handler: workingGroups_RewardPaid
+    - event: storageWorkingGroup.NewMissedRewardLevelReached
+      handler: workingGroups_NewMissedRewardLevelReached
+    - event: storageWorkingGroup.WorkerStartedLeaving
+      handler: workingGroups_WorkerStartedLeaving
+    # Forum working group
+    - event: forumWorkingGroup.OpeningAdded
+      handler: workingGroups_OpeningAdded
+    - event: forumWorkingGroup.AppliedOnOpening
+      handler: workingGroups_AppliedOnOpening
+    - event: forumWorkingGroup.OpeningFilled
+      handler: workingGroups_OpeningFilled
+    - event: forumWorkingGroup.LeaderSet
+      handler: workingGroups_LeaderSet
+    - event: forumWorkingGroup.WorkerRoleAccountUpdated
+      handler: workingGroups_WorkerRoleAccountUpdated
+    - event: forumWorkingGroup.LeaderUnset
+      handler: workingGroups_LeaderUnset
+    - event: forumWorkingGroup.WorkerExited
+      handler: workingGroups_WorkerExited
+    - event: forumWorkingGroup.TerminatedWorker
+      handler: workingGroups_TerminatedWorker
+    - event: forumWorkingGroup.TerminatedLeader
+      handler: workingGroups_TerminatedLeader
+    - event: forumWorkingGroup.StakeSlashed
+      handler: workingGroups_StakeSlashed
+    - event: forumWorkingGroup.StakeDecreased
+      handler: workingGroups_StakeDecreased
+    - event: forumWorkingGroup.StakeIncreased
+      handler: workingGroups_StakeIncreased
+    - event: forumWorkingGroup.ApplicationWithdrawn
+      handler: workingGroups_ApplicationWithdrawn
+    - event: forumWorkingGroup.OpeningCanceled
+      handler: workingGroups_OpeningCanceled
+    - event: forumWorkingGroup.BudgetSet
+      handler: workingGroups_BudgetSet
+    - event: forumWorkingGroup.WorkerRewardAccountUpdated
+      handler: workingGroups_WorkerRewardAccountUpdated
+    - event: forumWorkingGroup.WorkerRewardAmountUpdated
+      handler: workingGroups_WorkerRewardAmountUpdated
+    - event: forumWorkingGroup.StatusTextChanged
+      handler: workingGroups_StatusTextChanged
+    - event: forumWorkingGroup.BudgetSpending
+      handler: workingGroups_BudgetSpending
+    - event: forumWorkingGroup.RewardPaid
+      handler: workingGroups_RewardPaid
+    - event: forumWorkingGroup.NewMissedRewardLevelReached
+      handler: workingGroups_NewMissedRewardLevelReached
+    - event: forumWorkingGroup.WorkerStartedLeaving
+      handler: workingGroups_WorkerStartedLeaving
+    # Membership working group
+    - event: membershipWorkingGroup.OpeningAdded
+      handler: workingGroups_OpeningAdded
+    - event: membershipWorkingGroup.AppliedOnOpening
+      handler: workingGroups_AppliedOnOpening
+    - event: membershipWorkingGroup.OpeningFilled
+      handler: workingGroups_OpeningFilled
+    - event: membershipWorkingGroup.LeaderSet
+      handler: workingGroups_LeaderSet
+    - event: membershipWorkingGroup.WorkerRoleAccountUpdated
+      handler: workingGroups_WorkerRoleAccountUpdated
+    - event: membershipWorkingGroup.LeaderUnset
+      handler: workingGroups_LeaderUnset
+    - event: membershipWorkingGroup.WorkerExited
+      handler: workingGroups_WorkerExited
+    - event: membershipWorkingGroup.TerminatedWorker
+      handler: workingGroups_TerminatedWorker
+    - event: membershipWorkingGroup.TerminatedLeader
+      handler: workingGroups_TerminatedLeader
+    - event: membershipWorkingGroup.StakeSlashed
+      handler: workingGroups_StakeSlashed
+    - event: membershipWorkingGroup.StakeDecreased
+      handler: workingGroups_StakeDecreased
+    - event: membershipWorkingGroup.StakeIncreased
+      handler: workingGroups_StakeIncreased
+    - event: membershipWorkingGroup.ApplicationWithdrawn
+      handler: workingGroups_ApplicationWithdrawn
+    - event: membershipWorkingGroup.OpeningCanceled
+      handler: workingGroups_OpeningCanceled
+    - event: membershipWorkingGroup.BudgetSet
+      handler: workingGroups_BudgetSet
+    - event: membershipWorkingGroup.WorkerRewardAccountUpdated
+      handler: workingGroups_WorkerRewardAccountUpdated
+    - event: membershipWorkingGroup.WorkerRewardAmountUpdated
+      handler: workingGroups_WorkerRewardAmountUpdated
+    - event: membershipWorkingGroup.StatusTextChanged
+      handler: workingGroups_StatusTextChanged
+    - event: membershipWorkingGroup.BudgetSpending
+      handler: workingGroups_BudgetSpending
+    - event: membershipWorkingGroup.RewardPaid
+      handler: workingGroups_RewardPaid
+    - event: membershipWorkingGroup.NewMissedRewardLevelReached
+      handler: workingGroups_NewMissedRewardLevelReached
+    - event: membershipWorkingGroup.WorkerStartedLeaving
+      handler: workingGroups_WorkerStartedLeaving
+    # Content directory working group
+    - event: contentDirectoryWorkingGroup.OpeningAdded
+      handler: workingGroups_OpeningAdded
+    - event: contentDirectoryWorkingGroup.AppliedOnOpening
+      handler: workingGroups_AppliedOnOpening
+    - event: contentDirectoryWorkingGroup.OpeningFilled
+      handler: workingGroups_OpeningFilled
+    - event: contentDirectoryWorkingGroup.LeaderSet
+      handler: workingGroups_LeaderSet
+    - event: contentDirectoryWorkingGroup.WorkerRoleAccountUpdated
+      handler: workingGroups_WorkerRoleAccountUpdated
+    - event: contentDirectoryWorkingGroup.LeaderUnset
+      handler: workingGroups_LeaderUnset
+    - event: contentDirectoryWorkingGroup.WorkerExited
+      handler: workingGroups_WorkerExited
+    - event: contentDirectoryWorkingGroup.TerminatedWorker
+      handler: workingGroups_TerminatedWorker
+    - event: contentDirectoryWorkingGroup.TerminatedLeader
+      handler: workingGroups_TerminatedLeader
+    - event: contentDirectoryWorkingGroup.StakeSlashed
+      handler: workingGroups_StakeSlashed
+    - event: contentDirectoryWorkingGroup.StakeDecreased
+      handler: workingGroups_StakeDecreased
+    - event: contentDirectoryWorkingGroup.StakeIncreased
+      handler: workingGroups_StakeIncreased
+    - event: contentDirectoryWorkingGroup.ApplicationWithdrawn
+      handler: workingGroups_ApplicationWithdrawn
+    - event: contentDirectoryWorkingGroup.OpeningCanceled
+      handler: workingGroups_OpeningCanceled
+    - event: contentDirectoryWorkingGroup.BudgetSet
+      handler: workingGroups_BudgetSet
+    - event: contentDirectoryWorkingGroup.WorkerRewardAccountUpdated
+      handler: workingGroups_WorkerRewardAccountUpdated
+    - event: contentDirectoryWorkingGroup.WorkerRewardAmountUpdated
+      handler: workingGroups_WorkerRewardAmountUpdated
+    - event: contentDirectoryWorkingGroup.StatusTextChanged
+      handler: workingGroups_StatusTextChanged
+    - event: contentDirectoryWorkingGroup.BudgetSpending
+      handler: workingGroups_BudgetSpending
+    - event: contentDirectoryWorkingGroup.RewardPaid
+      handler: workingGroups_RewardPaid
+    - event: contentDirectoryWorkingGroup.NewMissedRewardLevelReached
+      handler: workingGroups_NewMissedRewardLevelReached
+    - event: contentDirectoryWorkingGroup.WorkerStartedLeaving
+      handler: workingGroups_WorkerStartedLeaving
   extrinsicHandlers:
     # infer defaults here
     #- extrinsic: Balances.Transfer

+ 49 - 11
query-node/mappings/common.ts

@@ -1,20 +1,58 @@
 import { SubstrateEvent } from '@dzlzv/hydra-common'
-import { DatabaseManager } from '@dzlzv/hydra-db-utils'
-import { Block } from 'query-node/dist/src/modules/block/block.model'
 import { Network } from 'query-node/dist/src/modules/enums/enums'
+import { Event } from 'query-node/dist/src/modules/event/event.model'
+import { Bytes } from '@polkadot/types'
 
-const currentNetwork = Network.OLYMPIA
+export const CURRENT_NETWORK = Network.OLYMPIA
 
-export async function prepareBlock(db: DatabaseManager, event: SubstrateEvent): Promise<Block> {
-  const block = await db.get(Block, { where: { block: event.blockNumber } })
+export function genericEventFields(substrateEvent: SubstrateEvent): Partial<Event> {
+  const { blockNumber, indexInBlock, extrinsic, blockTimestamp } = substrateEvent
+  const eventTime = new Date(blockTimestamp)
+  return {
+    createdAt: eventTime,
+    updatedAt: eventTime,
+    id: `${CURRENT_NETWORK}-${blockNumber}-${indexInBlock}`,
+    inBlock: blockNumber,
+    network: CURRENT_NETWORK,
+    inExtrinsic: extrinsic?.hash,
+    indexInBlock,
+  }
+}
 
-  if (block) {
-    return block
+type AnyMessage<T> = T & {
+  toJSON(): Record<string, unknown>
+}
+
+type AnyMetadataClass<T> = {
+  name: string
+  decode(binary: Uint8Array): AnyMessage<T>
+  encode(obj: T): { finish(): Uint8Array }
+  toObject(obj: AnyMessage<T>): Record<string, unknown>
+}
+
+export function deserializeMetadata<T>(metadataType: AnyMetadataClass<T>, metadataBytes: Bytes): T | null {
+  try {
+    // We use `toObject()` to get rid of .prototype defaults for optional fields
+    return metadataType.toObject(metadataType.decode(metadataBytes.toU8a(true))) as T
+  } catch (e) {
+    console.error(`Cannot deserialize ${metadataType.name}! Provided bytes: (${metadataBytes.toHex()})`)
+    return null
   }
+}
+
+export function bytesToString(b: Bytes): string {
+  return Buffer.from(b.toU8a(true)).toString()
+}
 
-  return new Block({
-    block: event.blockNumber,
-    executedAt: new Date(event.blockTimestamp.toNumber()),
-    network: currentNetwork,
+export function hasValuesForProperties<
+  T extends Record<string, unknown>,
+  P extends keyof T & string,
+  PA extends readonly P[]
+>(obj: T, props: PA): obj is T & { [K in PA[number]]: NonNullable<K> } {
+  props.forEach((p) => {
+    if (obj[p] === null || obj[p] === undefined) {
+      return false
+    }
   })
+  return true
 }

+ 2 - 1
query-node/mappings/index.ts

@@ -1 +1,2 @@
-export * from './mappings'
+export * from './membership'
+export * from './workingGroups'

+ 8 - 14
query-node/mappings/init.ts

@@ -1,28 +1,22 @@
 import { ApiPromise, WsProvider } from '@polkadot/api'
 import { types } from '@joystream/types'
-import { makeDatabaseManager } from '@dzlzv/hydra-db-utils'
 import { createDBConnection } from '@dzlzv/hydra-processor'
-import { MembershipSystem } from 'query-node/dist/src/modules/membership-system/membership-system.model'
+import { makeDatabaseManager } from '@dzlzv/hydra-processor/lib/executor/TransactionalExecutor'
 import path from 'path'
 
-// Temporary script to initialize processor database with some confing values initially hardcoded in the runtime
+// A script to initialize processor database with some initial values that cannot be fetched from events / extrinics
 async function init() {
   const provider = new WsProvider(process.env.WS_PROVIDER_ENDPOINT_URI)
   const api = await ApiPromise.create({ provider, types })
   const entitiesPath = path.resolve(__dirname, '../../generated/graphql-server/dist/src/modules/**/*.model.js')
+  // We need to create db connection (and configure env) before importing any warthog models
   const dbConnection = await createDBConnection([entitiesPath])
-  const initialInvitationCount = await api.query.members.initialInvitationCount()
-  const initialInvitationBalance = await api.query.members.initialInvitationBalance()
-  const referralCut = await api.query.members.referralCut()
-  const membershipPrice = await api.query.members.membershipPrice()
   const db = makeDatabaseManager(dbConnection.createEntityManager())
-  const membershipSystem = new MembershipSystem({
-    defaultInviteCount: initialInvitationCount.toNumber(),
-    membershipPrice,
-    referralCut,
-    invitedInitialBalance: initialInvitationBalance,
-  })
-  await db.save<MembershipSystem>(membershipSystem)
+  // Only now we can import the initialization scripts (which include warthog models imports)
+  // eslint-disable-next-line @typescript-eslint/no-var-requires
+  const initializeDb = require('./initializeDb').default
+
+  await initializeDb(api, db)
 }
 
 init()

+ 45 - 0
query-node/mappings/initializeDb.ts

@@ -0,0 +1,45 @@
+import { ApiPromise } from '@polkadot/api'
+import { BalanceOf } from '@polkadot/types/interfaces'
+import { DatabaseManager } from '@dzlzv/hydra-common'
+import { MembershipSystemSnapshot, WorkingGroup } from 'query-node/dist/model'
+
+async function initMembershipSystem(api: ApiPromise, db: DatabaseManager) {
+  const initialInvitationCount = await api.query.members.initialInvitationCount.at(api.genesisHash)
+  const initialInvitationBalance = await api.query.members.initialInvitationBalance.at(api.genesisHash)
+  const referralCut = await api.query.members.referralCut.at(api.genesisHash)
+  const membershipPrice = await api.query.members.membershipPrice.at(api.genesisHash)
+  const membershipSystem = new MembershipSystemSnapshot({
+    createdAt: new Date(0),
+    updatedAt: new Date(0),
+    snapshotBlock: 0,
+    defaultInviteCount: initialInvitationCount.toNumber(),
+    membershipPrice,
+    referralCut: referralCut.toNumber(),
+    invitedInitialBalance: initialInvitationBalance,
+  })
+  await db.save<MembershipSystemSnapshot>(membershipSystem)
+}
+
+async function initWorkingGroups(api: ApiPromise, db: DatabaseManager) {
+  const groupNames = Object.keys(api.query).filter((k) => k.endsWith('WorkingGroup'))
+  const groups = await Promise.all(
+    groupNames.map(async (groupName) => {
+      const budget = await api.query[groupName].budget.at<BalanceOf>(api.genesisHash)
+      return new WorkingGroup({
+        createdAt: new Date(0),
+        updatedAt: new Date(0),
+        id: groupName,
+        name: groupName,
+        workers: [],
+        openings: [],
+        budget,
+      })
+    })
+  )
+  await Promise.all(groups.map((g) => db.save<WorkingGroup>(g)))
+}
+
+export default async function initializeDb(api: ApiPromise, db: DatabaseManager): Promise<void> {
+  await initMembershipSystem(api, db)
+  await initWorkingGroups(api, db)
+}

+ 0 - 216
query-node/mappings/mappings.ts

@@ -1,216 +0,0 @@
-/*
-eslint-disable @typescript-eslint/naming-convention
-*/
-import { SubstrateEvent } from '@dzlzv/hydra-common'
-import { DatabaseManager } from '@dzlzv/hydra-db-utils'
-import { Membership, MembershipEntryMethod } from 'query-node/dist/src/modules/membership/membership.model'
-import { Members } from './generated/types'
-import { prepareBlock } from './common'
-import BN from 'bn.js'
-import { Block } from 'query-node/dist/src/modules/block/block.model'
-import { Bytes } from '@polkadot/types'
-import { MembershipSystem } from 'query-node/dist/src/modules/membership-system/membership-system.model'
-import { MemberId, BuyMembershipParameters, InviteMembershipParameters } from '@joystream/types/augment/all'
-import { MembershipMetadata } from '@joystream/metadata-protobuf'
-
-async function getMemberById(db: DatabaseManager, id: MemberId): Promise<Membership> {
-  const member = await db.get(Membership, { where: { id: id.toString() } })
-  if (!member) {
-    throw new Error(`Member(${id}) not found`)
-  }
-  return member
-}
-
-async function getMembershipSystem(db: DatabaseManager) {
-  const membershipSystem = await db.get(MembershipSystem, {})
-  if (!membershipSystem) {
-    throw new Error(`Membership system entity not found! Forgot to run "yarn workspace query-node-root db:init"?`)
-  }
-  return membershipSystem
-}
-
-function bytesToString(b: Bytes): string {
-  return Buffer.from(b.toU8a(true)).toString()
-}
-
-function deserializeMemberMeta(metadataBytes: Bytes): MembershipMetadata | null {
-  try {
-    return MembershipMetadata.deserializeBinary(metadataBytes.toU8a(true))
-  } catch (e) {
-    console.error(`Invalid membership metadata! (${metadataBytes.toHex()})`)
-    return null
-  }
-}
-
-async function newMembershipFromParams(
-  db: DatabaseManager,
-  event_: SubstrateEvent,
-  memberId: MemberId,
-  entryMethod: MembershipEntryMethod,
-  params: BuyMembershipParameters | InviteMembershipParameters
-): Promise<void> {
-  event_.blockTimestamp = new BN(event_.blockTimestamp) // FIXME: Temporary fix for wrong blockTimestamp type
-  const membershipSystem = await getMembershipSystem(db)
-  const { root_account: rootAccount, controller_account: controllerAccount, handle, metadata: metatadaBytes } = params
-  const metadata = deserializeMemberMeta(metatadaBytes)
-  const member = new Membership({
-    id: memberId.toString(),
-    name: metadata?.getName(),
-    rootAccount: rootAccount.toString(),
-    controllerAccount: controllerAccount.toString(),
-    handle: handle.unwrap().toString(),
-    about: metadata?.getAbout(),
-    avatarUri: metadata?.getAvatarUri(),
-    registeredAtBlock: await prepareBlock(db, event_),
-    registeredAtTime: new Date(event_.blockTimestamp.toNumber()),
-    entry: entryMethod,
-    referredBy:
-      entryMethod === MembershipEntryMethod.PAID && (params as BuyMembershipParameters).referrer_id.isSome
-        ? new Membership({ id: (params as BuyMembershipParameters).referrer_id.unwrap().toString() })
-        : undefined,
-    isVerified: false,
-    inviteCount: membershipSystem.defaultInviteCount,
-    boundAccounts: [],
-    invitees: [],
-    referredMembers: [],
-    invitedBy:
-      entryMethod === MembershipEntryMethod.INVITED
-        ? new Membership({ id: (params as InviteMembershipParameters).inviting_member_id.toString() })
-        : undefined,
-  })
-
-  await db.save<Block>(member.registeredAtBlock)
-  await db.save<Membership>(member)
-}
-
-export async function members_MembershipBought(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
-  const { memberId, buyMembershipParameters } = new Members.MembershipBoughtEvent(event_).data
-  await newMembershipFromParams(db, event_, memberId, MembershipEntryMethod.PAID, buyMembershipParameters)
-}
-
-export async function members_MemberProfileUpdated(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
-  const { memberId } = new Members.MemberProfileUpdatedEvent(event_).data
-  const { metadata: metadataBytesOpt, handle } = new Members.UpdateProfileCall(event_).args
-  const metadata = metadataBytesOpt.isSome ? deserializeMemberMeta(metadataBytesOpt.unwrap()) : undefined
-  const member = await getMemberById(db, memberId)
-  if (metadata?.hasName()) {
-    member.name = metadata.getName()
-  }
-  if (metadata?.hasAbout()) {
-    member.about = metadata.getAbout()
-  }
-  if (metadata?.hasAvatarUri()) {
-    member.avatarUri = metadata.getAvatarUri()
-  }
-  if (handle.isSome) {
-    member.handle = bytesToString(handle.unwrap())
-  }
-
-  await db.save<Membership>(member)
-}
-
-export async function members_MemberAccountsUpdated(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
-  const { memberId } = new Members.MemberAccountsUpdatedEvent(event_).data
-  const { newRootAccount, newControllerAccount } = new Members.UpdateAccountsCall(event_).args
-  const member = await getMemberById(db, memberId)
-  if (newControllerAccount.isSome) {
-    member.controllerAccount = newControllerAccount.unwrap().toString()
-  }
-  if (newRootAccount.isSome) {
-    member.rootAccount = newRootAccount.unwrap().toString()
-  }
-
-  await db.save<Membership>(member)
-}
-
-export async function members_MemberVerificationStatusUpdated(
-  db: DatabaseManager,
-  event_: SubstrateEvent
-): Promise<void> {
-  const { memberId, bool: verificationStatus } = new Members.MemberVerificationStatusUpdatedEvent(event_).data
-  const member = await getMemberById(db, memberId)
-  member.isVerified = verificationStatus.valueOf()
-
-  await db.save<Membership>(member)
-}
-
-export async function members_InvitesTransferred(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
-  const {
-    memberIds: { 0: sourceMemberId, 1: targetMemberId },
-    u32: numberOfInvites,
-  } = new Members.InvitesTransferredEvent(event_).data
-  const sourceMember = await getMemberById(db, sourceMemberId)
-  const targetMember = await getMemberById(db, targetMemberId)
-  sourceMember.inviteCount -= numberOfInvites.toNumber()
-  targetMember.inviteCount += numberOfInvites.toNumber()
-
-  await db.save<Membership>(sourceMember)
-  await db.save<Membership>(targetMember)
-}
-
-export async function members_MemberInvited(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
-  const { memberId, inviteMembershipParameters } = new Members.MemberInvitedEvent(event_).data
-  await newMembershipFromParams(db, event_, memberId, MembershipEntryMethod.INVITED, inviteMembershipParameters)
-
-  // Decrease invite count of inviting member
-  const invitingMember = await getMemberById(db, inviteMembershipParameters.inviting_member_id)
-  invitingMember.inviteCount -= 1
-  await db.save<Membership>(invitingMember)
-}
-
-export async function members_StakingAccountConfirmed(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
-  const { memberId, accountId } = new Members.StakingAccountConfirmedEvent(event_).data
-  const member = await getMemberById(db, memberId)
-  member.boundAccounts.push(accountId.toString())
-
-  await db.save<Membership>(member)
-}
-
-export async function members_StakingAccountRemoved(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
-  const { memberId, accountId } = new Members.StakingAccountRemovedEvent(event_).data
-  const member = await getMemberById(db, memberId)
-  member.boundAccounts.splice(
-    member.boundAccounts.findIndex((a) => a === accountId.toString()),
-    1
-  )
-
-  await db.save<Membership>(member)
-}
-
-export async function members_InitialInvitationCountUpdated(
-  db: DatabaseManager,
-  event_: SubstrateEvent
-): Promise<void> {
-  const { u32: newDefaultInviteCount } = new Members.InitialInvitationCountUpdatedEvent(event_).data
-  const membershipSystem = await getMembershipSystem(db)
-  membershipSystem.defaultInviteCount = newDefaultInviteCount.toNumber()
-
-  await db.save<MembershipSystem>(membershipSystem)
-}
-
-export async function members_MembershipPriceUpdated(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
-  const { balance: newMembershipPrice } = new Members.MembershipPriceUpdatedEvent(event_).data
-  const membershipSystem = await getMembershipSystem(db)
-  membershipSystem.membershipPrice = newMembershipPrice
-
-  await db.save<MembershipSystem>(membershipSystem)
-}
-
-export async function members_ReferralCutUpdated(db: DatabaseManager, event_: SubstrateEvent): Promise<void> {
-  const { balance: newReferralCut } = new Members.ReferralCutUpdatedEvent(event_).data
-  const membershipSystem = await getMembershipSystem(db)
-  membershipSystem.referralCut = newReferralCut
-
-  await db.save<MembershipSystem>(membershipSystem)
-}
-
-export async function members_InitialInvitationBalanceUpdated(
-  db: DatabaseManager,
-  event_: SubstrateEvent
-): Promise<void> {
-  const { balance: newInvitedInitialBalance } = new Members.InitialInvitationBalanceUpdatedEvent(event_).data
-  const membershipSystem = await getMembershipSystem(db)
-  membershipSystem.invitedInitialBalance = newInvitedInitialBalance
-
-  await db.save<MembershipSystem>(membershipSystem)
-}

+ 419 - 0
query-node/mappings/membership.ts

@@ -0,0 +1,419 @@
+/*
+eslint-disable @typescript-eslint/naming-convention
+*/
+import { EventContext, StoreContext, DatabaseManager, SubstrateEvent } from '@dzlzv/hydra-common'
+import { Members } from './generated/types'
+import { MemberId, BuyMembershipParameters, InviteMembershipParameters } from '@joystream/types/augment/all'
+import { MembershipMetadata } from '@joystream/metadata-protobuf'
+import { bytesToString, deserializeMetadata, genericEventFields } from './common'
+import {
+  Membership,
+  MembershipEntryMethod,
+  MembershipSystemSnapshot,
+  MemberMetadata,
+  MembershipBoughtEvent,
+  MemberProfileUpdatedEvent,
+  MemberAccountsUpdatedEvent,
+  MemberInvitedEvent,
+  MemberVerificationStatusUpdatedEvent,
+  InvitesTransferredEvent,
+  StakingAccountConfirmedEvent,
+  StakingAccountRemovedEvent,
+  InitialInvitationCountUpdatedEvent,
+  MembershipPriceUpdatedEvent,
+  ReferralCutUpdatedEvent,
+  InitialInvitationBalanceUpdatedEvent,
+  StakingAccountAddedEvent,
+  LeaderInvitationQuotaUpdatedEvent,
+  MembershipEntryPaid,
+  MembershipEntryInvited,
+} from 'query-node/dist/model'
+
+async function getMemberById(store: DatabaseManager, id: MemberId): Promise<Membership> {
+  const member = await store.get(Membership, { where: { id: id.toString() }, relations: ['metadata'] })
+  if (!member) {
+    throw new Error(`Member(${id}) not found`)
+  }
+  return member
+}
+
+async function getLatestMembershipSystemSnapshot(store: DatabaseManager): Promise<MembershipSystemSnapshot> {
+  const membershipSystem = await store.get(MembershipSystemSnapshot, {
+    order: { snapshotBlock: 'DESC' },
+  })
+  if (!membershipSystem) {
+    throw new Error(`Membership system snapshot not found! Forgot to run "yarn workspace query-node-root store:init"?`)
+  }
+  return membershipSystem
+}
+
+async function getOrCreateMembershipSnapshot({ store, event }: EventContext & StoreContext) {
+  const latestSnapshot = await getLatestMembershipSystemSnapshot(store)
+  const eventTime = new Date(event.blockTimestamp)
+  return latestSnapshot.snapshotBlock === event.blockNumber
+    ? latestSnapshot
+    : new MembershipSystemSnapshot({
+        ...latestSnapshot,
+        createdAt: eventTime,
+        updatedAt: eventTime,
+        id: undefined,
+        snapshotBlock: event.blockNumber,
+      })
+}
+
+async function createNewMemberFromParams(
+  store: DatabaseManager,
+  event: SubstrateEvent,
+  memberId: MemberId,
+  entryMethod: typeof MembershipEntryMethod,
+  params: BuyMembershipParameters | InviteMembershipParameters
+): Promise<Membership> {
+  const { defaultInviteCount } = await getLatestMembershipSystemSnapshot(store)
+  const { root_account: rootAccount, controller_account: controllerAccount, handle, metadata: metatadaBytes } = params
+  const metadata = deserializeMetadata(MembershipMetadata, metatadaBytes)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const metadataEntity = new MemberMetadata({
+    createdAt: eventTime,
+    updatedAt: eventTime,
+    name: metadata?.name || undefined,
+    about: metadata?.about || undefined,
+    // TODO: avatar
+  })
+
+  const member = new Membership({
+    createdAt: eventTime,
+    updatedAt: eventTime,
+    id: memberId.toString(),
+    rootAccount: rootAccount.toString(),
+    controllerAccount: controllerAccount.toString(),
+    handle: handle.unwrap().toString(),
+    metadata: metadataEntity,
+    entry: entryMethod,
+    referredBy:
+      entryMethod.isTypeOf === 'MembershipEntryPaid' && (params as BuyMembershipParameters).referrer_id.isSome
+        ? new Membership({ id: (params as BuyMembershipParameters).referrer_id.unwrap().toString() })
+        : undefined,
+    isVerified: false,
+    inviteCount: defaultInviteCount,
+    boundAccounts: [],
+    invitees: [],
+    referredMembers: [],
+    invitedBy:
+      entryMethod.isTypeOf === 'MembershipEntryInvited'
+        ? new Membership({ id: (params as InviteMembershipParameters).inviting_member_id.toString() })
+        : undefined,
+    isFoundingMember: false,
+  })
+
+  await store.save<MemberMetadata>(member.metadata)
+  await store.save<Membership>(member)
+
+  return member
+}
+
+export async function members_MembershipBought({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [memberId, buyMembershipParameters] = new Members.MembershipBoughtEvent(event).params
+
+  const memberEntry = new MembershipEntryPaid()
+  const member = await createNewMemberFromParams(store, event, memberId, memberEntry, buyMembershipParameters)
+
+  const membershipBoughtEvent = new MembershipBoughtEvent({
+    ...genericEventFields(event),
+    newMember: member,
+    controllerAccount: member.controllerAccount,
+    rootAccount: member.rootAccount,
+    handle: member.handle,
+    metadata: new MemberMetadata({
+      ...member.metadata,
+      id: undefined,
+    }),
+    referrer: member.referredBy,
+  })
+
+  await store.save<MemberMetadata>(membershipBoughtEvent.metadata)
+  await store.save<MembershipBoughtEvent>(membershipBoughtEvent)
+
+  // Update the other side of event<->membership relation
+  memberEntry.membershipBoughtEventId = membershipBoughtEvent.id
+  await store.save<Membership>(member)
+}
+
+export async function members_MemberProfileUpdated({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [memberId] = new Members.MemberProfileUpdatedEvent(event).params
+  const { metadata: metadataBytesOpt, handle } = new Members.UpdateProfileCall(event).args
+  const metadata = metadataBytesOpt.isSome
+    ? deserializeMetadata(MembershipMetadata, metadataBytesOpt.unwrap())
+    : undefined
+  const member = await getMemberById(store, memberId)
+  const eventTime = new Date(event.blockTimestamp)
+
+  if (typeof metadata?.name === 'string') {
+    member.metadata.name = metadata.name || undefined
+    member.metadata.updatedAt = eventTime
+  }
+  if (typeof metadata?.about === 'string') {
+    member.metadata.about = metadata.about || undefined
+    member.metadata.updatedAt = eventTime
+  }
+  // TODO: avatar
+  if (handle.isSome) {
+    member.handle = bytesToString(handle.unwrap())
+    member.updatedAt = eventTime
+  }
+
+  await store.save<MemberMetadata>(member.metadata)
+  await store.save<Membership>(member)
+
+  const memberProfileUpdatedEvent = new MemberProfileUpdatedEvent({
+    ...genericEventFields(event),
+    member: member,
+    newHandle: member.handle,
+    newMetadata: new MemberMetadata({
+      ...member.metadata,
+      id: undefined,
+    }),
+  })
+
+  await store.save<MemberMetadata>(memberProfileUpdatedEvent.newMetadata)
+  await store.save<MemberProfileUpdatedEvent>(memberProfileUpdatedEvent)
+}
+
+export async function members_MemberAccountsUpdated({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [memberId] = new Members.MemberAccountsUpdatedEvent(event).params
+  const { newRootAccount, newControllerAccount } = new Members.UpdateAccountsCall(event).args
+  const member = await getMemberById(store, memberId)
+  const eventTime = new Date(event.blockTimestamp)
+
+  if (newControllerAccount.isSome) {
+    member.controllerAccount = newControllerAccount.unwrap().toString()
+  }
+  if (newRootAccount.isSome) {
+    member.rootAccount = newRootAccount.unwrap().toString()
+  }
+  member.updatedAt = eventTime
+
+  await store.save<Membership>(member)
+
+  const memberAccountsUpdatedEvent = new MemberAccountsUpdatedEvent({
+    ...genericEventFields(event),
+    member: member,
+    newRootAccount: member.rootAccount,
+    newControllerAccount: member.controllerAccount,
+  })
+
+  await store.save<MemberAccountsUpdatedEvent>(memberAccountsUpdatedEvent)
+}
+
+export async function members_MemberVerificationStatusUpdated(
+  store: DatabaseManager,
+  event: SubstrateEvent
+): Promise<void> {
+  const [memberId, verificationStatus] = new Members.MemberVerificationStatusUpdatedEvent(event).params
+  const member = await getMemberById(store, memberId)
+  const eventTime = new Date(event.blockTimestamp)
+
+  member.isVerified = verificationStatus.valueOf()
+  member.updatedAt = eventTime
+
+  await store.save<Membership>(member)
+
+  const memberVerificationStatusUpdatedEvent = new MemberVerificationStatusUpdatedEvent({
+    ...genericEventFields(event),
+    member: member,
+    isVerified: member.isVerified,
+  })
+
+  await store.save<MemberVerificationStatusUpdatedEvent>(memberVerificationStatusUpdatedEvent)
+}
+
+export async function members_InvitesTransferred({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [sourceMemberId, targetMemberId, numberOfInvites] = new Members.InvitesTransferredEvent(event).params
+  const sourceMember = await getMemberById(store, sourceMemberId)
+  const targetMember = await getMemberById(store, targetMemberId)
+  const eventTime = new Date(event.blockTimestamp)
+
+  sourceMember.inviteCount -= numberOfInvites.toNumber()
+  sourceMember.updatedAt = eventTime
+  targetMember.inviteCount += numberOfInvites.toNumber()
+  targetMember.updatedAt = eventTime
+
+  await store.save<Membership>(sourceMember)
+  await store.save<Membership>(targetMember)
+
+  const invitesTransferredEvent = new InvitesTransferredEvent({
+    ...genericEventFields(event),
+    sourceMember,
+    targetMember,
+    numberOfInvites: numberOfInvites.toNumber(),
+  })
+
+  await store.save<InvitesTransferredEvent>(invitesTransferredEvent)
+}
+
+export async function members_MemberInvited({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [memberId, inviteMembershipParameters] = new Members.MemberInvitedEvent(event).params
+  const eventTime = new Date(event.blockTimestamp)
+  const entryMethod = new MembershipEntryInvited()
+  const invitedMember = await createNewMemberFromParams(store, event, memberId, entryMethod, inviteMembershipParameters)
+
+  // Decrease invite count of inviting member
+  const invitingMember = await getMemberById(store, inviteMembershipParameters.inviting_member_id)
+  invitingMember.inviteCount -= 1
+  invitingMember.updatedAt = eventTime
+  await store.save<Membership>(invitingMember)
+
+  const memberInvitedEvent = new MemberInvitedEvent({
+    ...genericEventFields(event),
+    invitingMember,
+    newMember: invitedMember,
+    handle: invitedMember.handle,
+    rootAccount: invitedMember.rootAccount,
+    controllerAccount: invitedMember.controllerAccount,
+    metadata: new MemberMetadata({
+      ...invitedMember.metadata,
+      id: undefined,
+    }),
+  })
+
+  await store.save<MemberMetadata>(memberInvitedEvent.metadata)
+  await store.save<MemberInvitedEvent>(memberInvitedEvent)
+  // Update the other side of event<->member relationship
+  entryMethod.memberInvitedEventId = memberInvitedEvent.id
+  await store.save<Membership>(invitedMember)
+}
+
+export async function members_StakingAccountAdded({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [accountId, memberId] = new Members.StakingAccountAddedEvent(event).params
+
+  const stakingAccountAddedEvent = new StakingAccountAddedEvent({
+    ...genericEventFields(event),
+    member: new Membership({ id: memberId.toString() }),
+    account: accountId.toString(),
+  })
+
+  await store.save<StakingAccountAddedEvent>(stakingAccountAddedEvent)
+}
+
+export async function members_StakingAccountConfirmed({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [accountId, memberId] = new Members.StakingAccountConfirmedEvent(event).params
+  const member = await getMemberById(store, memberId)
+  const eventTime = new Date(event.blockTimestamp)
+
+  member.boundAccounts.push(accountId.toString())
+  member.updatedAt = eventTime
+
+  await store.save<Membership>(member)
+
+  const stakingAccountConfirmedEvent = new StakingAccountConfirmedEvent({
+    ...genericEventFields(event),
+    member,
+    account: accountId.toString(),
+  })
+
+  await store.save<StakingAccountConfirmedEvent>(stakingAccountConfirmedEvent)
+}
+
+export async function members_StakingAccountRemoved({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [accountId, memberId] = new Members.StakingAccountRemovedEvent(event).params
+  const eventTime = new Date(event.blockTimestamp)
+  const member = await getMemberById(store, memberId)
+
+  member.boundAccounts.splice(
+    member.boundAccounts.findIndex((a) => a === accountId.toString()),
+    1
+  )
+  member.updatedAt = eventTime
+
+  await store.save<Membership>(member)
+
+  const stakingAccountRemovedEvent = new StakingAccountRemovedEvent({
+    ...genericEventFields(event),
+    member,
+    account: accountId.toString(),
+  })
+
+  await store.save<StakingAccountRemovedEvent>(stakingAccountRemovedEvent)
+}
+
+export async function members_InitialInvitationCountUpdated(ctx: EventContext & StoreContext): Promise<void> {
+  const { event, store } = ctx
+  const [newDefaultInviteCount] = new Members.InitialInvitationCountUpdatedEvent(event).params
+  const membershipSystemSnapshot = await getOrCreateMembershipSnapshot(ctx)
+
+  membershipSystemSnapshot.defaultInviteCount = newDefaultInviteCount.toNumber()
+
+  await store.save<MembershipSystemSnapshot>(membershipSystemSnapshot)
+
+  const initialInvitationCountUpdatedEvent = new InitialInvitationCountUpdatedEvent({
+    ...genericEventFields(event),
+    newInitialInvitationCount: newDefaultInviteCount.toNumber(),
+  })
+
+  await store.save<InitialInvitationCountUpdatedEvent>(initialInvitationCountUpdatedEvent)
+}
+
+export async function members_MembershipPriceUpdated(ctx: EventContext & StoreContext): Promise<void> {
+  const { event, store } = ctx
+  const [newMembershipPrice] = new Members.MembershipPriceUpdatedEvent(event).params
+  const membershipSystemSnapshot = await getOrCreateMembershipSnapshot(ctx)
+
+  membershipSystemSnapshot.membershipPrice = newMembershipPrice
+
+  await store.save<MembershipSystemSnapshot>(membershipSystemSnapshot)
+
+  const membershipPriceUpdatedEvent = new MembershipPriceUpdatedEvent({
+    ...genericEventFields(event),
+    newPrice: newMembershipPrice,
+  })
+
+  await store.save<MembershipPriceUpdatedEvent>(membershipPriceUpdatedEvent)
+}
+
+export async function members_ReferralCutUpdated(ctx: EventContext & StoreContext): Promise<void> {
+  const { event, store } = ctx
+  const [newReferralCut] = new Members.ReferralCutUpdatedEvent(event).params
+  const membershipSystemSnapshot = await getOrCreateMembershipSnapshot(ctx)
+
+  membershipSystemSnapshot.referralCut = newReferralCut.toNumber()
+
+  await store.save<MembershipSystemSnapshot>(membershipSystemSnapshot)
+
+  const referralCutUpdatedEvent = new ReferralCutUpdatedEvent({
+    ...genericEventFields(event),
+    newValue: newReferralCut.toNumber(),
+  })
+
+  await store.save<ReferralCutUpdatedEvent>(referralCutUpdatedEvent)
+}
+
+export async function members_InitialInvitationBalanceUpdated(ctx: EventContext & StoreContext): Promise<void> {
+  const { event, store } = ctx
+  const [newInvitedInitialBalance] = new Members.InitialInvitationBalanceUpdatedEvent(event).params
+  const membershipSystemSnapshot = await getOrCreateMembershipSnapshot(ctx)
+
+  membershipSystemSnapshot.invitedInitialBalance = newInvitedInitialBalance
+
+  await store.save<MembershipSystemSnapshot>(membershipSystemSnapshot)
+
+  const initialInvitationBalanceUpdatedEvent = new InitialInvitationBalanceUpdatedEvent({
+    ...genericEventFields(event),
+    newInitialBalance: newInvitedInitialBalance,
+  })
+
+  await store.save<InitialInvitationBalanceUpdatedEvent>(initialInvitationBalanceUpdatedEvent)
+}
+
+export async function members_LeaderInvitationQuotaUpdated({
+  store,
+  event,
+}: EventContext & StoreContext): Promise<void> {
+  const [newQuota] = new Members.LeaderInvitationQuotaUpdatedEvent(event).params
+
+  const leaderInvitationQuotaUpdatedEvent = new LeaderInvitationQuotaUpdatedEvent({
+    ...genericEventFields(event),
+    newInvitationQuota: newQuota.toNumber(),
+  })
+
+  await store.save<LeaderInvitationQuotaUpdatedEvent>(leaderInvitationQuotaUpdatedEvent)
+}

+ 3 - 3
query-node/mappings/package.json

@@ -10,10 +10,10 @@
     "clean": "rm -rf lib"
   },
   "dependencies": {
-    "@dzlzv/hydra-common": "2.0.1-beta.15",
-    "@dzlzv/hydra-db-utils": "2.0.1-beta.15",
+    "@dzlzv/hydra-common": "3.0.0-beta.6",
+    "@dzlzv/hydra-db-utils": "3.0.0-beta.6",
     "@joystream/types": "^0.15.0",
-    "warthog": "https://github.com/metmirr/warthog/releases/download/v2.23.0/warthog-v2.23.0.tgz"
+    "warthog": "https://github.com/metmirr/warthog/releases/download/v2.30.0/warthog-v2.30.0.tgz"
   },
   "devDependencies": {
     "ts-node": "^9.0.0",

+ 965 - 0
query-node/mappings/workingGroups.ts

@@ -0,0 +1,965 @@
+/*
+eslint-disable @typescript-eslint/naming-convention
+*/
+import { EventContext, StoreContext, DatabaseManager, SubstrateEvent } from '@dzlzv/hydra-common'
+
+import { StorageWorkingGroup as WorkingGroups } from './generated/types'
+import {
+  ApplicationMetadata,
+  IAddUpcomingOpening,
+  IOpeningMetadata,
+  IRemoveUpcomingOpening,
+  ISetGroupMetadata,
+  IWorkingGroupMetadata,
+  IWorkingGroupMetadataAction,
+  OpeningMetadata,
+  WorkingGroupMetadataAction,
+} from '@joystream/metadata-protobuf'
+import { Bytes } from '@polkadot/types'
+import { deserializeMetadata, bytesToString, genericEventFields } from './common'
+import BN from 'bn.js'
+import {
+  WorkingGroupOpening,
+  OpeningAddedEvent,
+  WorkingGroup,
+  WorkingGroupOpeningMetadata,
+  ApplicationFormQuestion,
+  ApplicationFormQuestionType,
+  OpeningStatusOpen,
+  WorkingGroupOpeningType,
+  WorkingGroupApplication,
+  ApplicationFormQuestionAnswer,
+  AppliedOnOpeningEvent,
+  Membership,
+  ApplicationStatusPending,
+  ApplicationStatusAccepted,
+  ApplicationStatusRejected,
+  Worker,
+  WorkerStatusActive,
+  OpeningFilledEvent,
+  OpeningStatusFilled,
+  // LeaderSetEvent,
+  OpeningCanceledEvent,
+  OpeningStatusCancelled,
+  ApplicationStatusCancelled,
+  ApplicationWithdrawnEvent,
+  ApplicationStatusWithdrawn,
+  UpcomingWorkingGroupOpening,
+  StatusTextChangedEvent,
+  WorkingGroupMetadata,
+  WorkingGroupMetadataSet,
+  UpcomingOpeningRemoved,
+  InvalidActionMetadata,
+  WorkingGroupMetadataActionResult,
+  UpcomingOpeningAdded,
+  WorkerRoleAccountUpdatedEvent,
+  WorkerRewardAccountUpdatedEvent,
+  StakeIncreasedEvent,
+  RewardPaidEvent,
+  RewardPaymentType,
+  NewMissedRewardLevelReachedEvent,
+  WorkerExitedEvent,
+  WorkerStatusLeft,
+  WorkerStatusTerminated,
+  TerminatedWorkerEvent,
+  LeaderUnsetEvent,
+  TerminatedLeaderEvent,
+  WorkerRewardAmountUpdatedEvent,
+  StakeSlashedEvent,
+  StakeDecreasedEvent,
+  WorkerStartedLeavingEvent,
+  BudgetSetEvent,
+  BudgetSpendingEvent,
+  LeaderSetEvent,
+} from 'query-node/dist/model'
+import { createType } from '@joystream/types'
+
+// Reusable functions
+async function getWorkingGroup(
+  store: DatabaseManager,
+  event: SubstrateEvent,
+  relations: string[] = []
+): Promise<WorkingGroup> {
+  const [groupName] = event.name.split('.')
+  const group = await store.get(WorkingGroup, { where: { name: groupName }, relations })
+  if (!group) {
+    throw new Error(`Working group ${groupName} not found!`)
+  }
+
+  return group
+}
+
+async function getOpening(
+  store: DatabaseManager,
+  openingstoreId: string,
+  relations: string[] = []
+): Promise<WorkingGroupOpening> {
+  const opening = await store.get(WorkingGroupOpening, { where: { id: openingstoreId }, relations })
+  if (!opening) {
+    throw new Error(`Opening not found by id ${openingstoreId}`)
+  }
+
+  return opening
+}
+
+async function getApplication(store: DatabaseManager, applicationstoreId: string): Promise<WorkingGroupApplication> {
+  const application = await store.get(WorkingGroupApplication, { where: { id: applicationstoreId } })
+  if (!application) {
+    throw new Error(`Application not found by id ${applicationstoreId}`)
+  }
+
+  return application
+}
+
+async function getWorker(store: DatabaseManager, workerstoreId: string): Promise<Worker> {
+  const worker = await store.get(Worker, { where: { id: workerstoreId } })
+  if (!worker) {
+    throw new Error(`Worker not found by id ${workerstoreId}`)
+  }
+
+  return worker
+}
+
+async function getApplicationFormQuestions(
+  store: DatabaseManager,
+  openingstoreId: string
+): Promise<ApplicationFormQuestion[]> {
+  const openingWithQuestions = await getOpening(store, openingstoreId, [
+    'metadata',
+    'metadata.applicationFormQuestions',
+  ])
+
+  if (!openingWithQuestions) {
+    throw new Error(`Opening not found by id: ${openingstoreId}`)
+  }
+  if (!openingWithQuestions.metadata.applicationFormQuestions) {
+    throw new Error(`Application form questions not found for opening: ${openingstoreId}`)
+  }
+  return openingWithQuestions.metadata.applicationFormQuestions
+}
+
+const InputTypeToApplicationFormQuestionType = {
+  [OpeningMetadata.ApplicationFormQuestion.InputType.TEXT]: ApplicationFormQuestionType.TEXT,
+  [OpeningMetadata.ApplicationFormQuestion.InputType.TEXTAREA]: ApplicationFormQuestionType.TEXTAREA,
+}
+
+function parseQuestionInputType(
+  type?: OpeningMetadata.ApplicationFormQuestion.InputType | null
+): ApplicationFormQuestionType {
+  const validType: OpeningMetadata.ApplicationFormQuestion.InputType = type || 0
+  return InputTypeToApplicationFormQuestionType[validType]
+}
+
+async function createOpeningMeta(
+  store: DatabaseManager,
+  event: SubstrateEvent,
+  originalMeta: Bytes | IOpeningMetadata
+): Promise<WorkingGroupOpeningMetadata> {
+  let originallyValid: boolean
+  let metadata: IOpeningMetadata
+  if (originalMeta instanceof Bytes) {
+    const deserializedMetadata = await deserializeMetadata(OpeningMetadata, originalMeta)
+    metadata = deserializedMetadata || {}
+    originallyValid = !!deserializedMetadata
+  } else {
+    metadata = originalMeta
+    originallyValid = true
+  }
+  const eventTime = new Date(event.blockTimestamp)
+
+  const {
+    applicationFormQuestions,
+    applicationDetails,
+    description,
+    expectedEndingTimestamp,
+    hiringLimit,
+    shortDescription,
+  } = metadata
+
+  const openingMetadata = new WorkingGroupOpeningMetadata({
+    createdAt: eventTime,
+    updatedAt: eventTime,
+    originallyValid,
+    applicationDetails: applicationDetails || undefined,
+    description: description || undefined,
+    shortDescription: shortDescription || undefined,
+    hiringLimit: hiringLimit || undefined,
+    expectedEnding: expectedEndingTimestamp ? new Date(expectedEndingTimestamp) : undefined,
+    applicationFormQuestions: [],
+  })
+
+  await store.save<WorkingGroupOpeningMetadata>(openingMetadata)
+
+  await Promise.all(
+    (applicationFormQuestions || []).map(async ({ question, type }, index) => {
+      const applicationFormQuestion = new ApplicationFormQuestion({
+        createdAt: eventTime,
+        updatedAt: eventTime,
+        question: question || undefined,
+        type: parseQuestionInputType(type),
+        index,
+        openingMetadata,
+      })
+      await store.save<ApplicationFormQuestion>(applicationFormQuestion)
+      return applicationFormQuestion
+    })
+  )
+
+  return openingMetadata
+}
+
+async function createApplicationQuestionAnswers(
+  store: DatabaseManager,
+  application: WorkingGroupApplication,
+  metadataBytes: Bytes
+) {
+  const metadata = deserializeMetadata(ApplicationMetadata, metadataBytes)
+  if (!metadata) {
+    return
+  }
+  const questions = await getApplicationFormQuestions(store, application.opening.id)
+  const { answers } = metadata
+  await Promise.all(
+    (answers || []).slice(0, questions.length).map(async (answer, index) => {
+      const applicationFormQuestionAnswer = new ApplicationFormQuestionAnswer({
+        createdAt: application.createdAt,
+        updatedAt: application.updatedAt,
+        application,
+        question: questions[index],
+        answer,
+      })
+
+      await store.save<ApplicationFormQuestionAnswer>(applicationFormQuestionAnswer)
+      return applicationFormQuestionAnswer
+    })
+  )
+}
+
+async function handleAddUpcomingOpeningAction(
+  store: DatabaseManager,
+  event: SubstrateEvent,
+  statusChangedEvent: StatusTextChangedEvent,
+  action: IAddUpcomingOpening
+): Promise<UpcomingOpeningAdded | InvalidActionMetadata> {
+  const upcomingOpeningMeta = action.metadata || {}
+  const group = await getWorkingGroup(store, event)
+  const eventTime = new Date(event.blockTimestamp)
+  const openingMeta = await createOpeningMeta(store, event, upcomingOpeningMeta.metadata || {})
+  const { rewardPerBlock, expectedStart, minApplicationStake } = upcomingOpeningMeta
+  const upcomingOpening = new UpcomingWorkingGroupOpening({
+    createdAt: eventTime,
+    updatedAt: eventTime,
+    metadata: openingMeta,
+    group,
+    rewardPerBlock: rewardPerBlock?.toNumber() ? new BN(rewardPerBlock.toString()) : undefined,
+    expectedStart: expectedStart ? new Date(expectedStart) : undefined,
+    stakeAmount: minApplicationStake?.toNumber() ? new BN(minApplicationStake.toString()) : undefined,
+    createdInEvent: statusChangedEvent,
+  })
+  await store.save<UpcomingWorkingGroupOpening>(upcomingOpening)
+
+  const result = new UpcomingOpeningAdded()
+  result.upcomingOpeningId = upcomingOpening.id
+
+  return result
+}
+
+async function handleRemoveUpcomingOpeningAction(
+  store: DatabaseManager,
+  action: IRemoveUpcomingOpening
+): Promise<UpcomingOpeningRemoved | InvalidActionMetadata> {
+  const { id } = action
+  const upcomingOpening = await store.get(UpcomingWorkingGroupOpening, { where: { id } })
+  let result: UpcomingOpeningRemoved | InvalidActionMetadata
+  if (upcomingOpening) {
+    result = new UpcomingOpeningRemoved()
+    result.upcomingOpeningId = upcomingOpening.id
+    await store.remove<UpcomingWorkingGroupOpening>(upcomingOpening)
+  } else {
+    const error = `Cannot remove upcoming opening: Entity by id ${id} not found!`
+    console.error(error)
+    result = new InvalidActionMetadata()
+    result.reason = error
+  }
+  return result
+}
+
+async function handleSetWorkingGroupMetadataAction(
+  store: DatabaseManager,
+  event: SubstrateEvent,
+  statusChangedEvent: StatusTextChangedEvent,
+  action: ISetGroupMetadata
+): Promise<WorkingGroupMetadataSet> {
+  const { newMetadata } = action
+  const group = await getWorkingGroup(store, event, ['metadata'])
+  const oldMetadata = group.metadata
+  const eventTime = new Date(event.blockTimestamp)
+  const setNewOptionalString = (field: keyof IWorkingGroupMetadata) =>
+    typeof newMetadata?.[field] === 'string' ? newMetadata[field] || undefined : oldMetadata?.[field]
+
+  const newGroupMetadata = new WorkingGroupMetadata({
+    createdAt: eventTime,
+    updatedAt: eventTime,
+    setInEvent: statusChangedEvent,
+    group,
+    status: setNewOptionalString('status'),
+    statusMessage: setNewOptionalString('statusMessage'),
+    about: setNewOptionalString('about'),
+    description: setNewOptionalString('description'),
+  })
+  await store.save<WorkingGroupMetadata>(newGroupMetadata)
+
+  group.metadata = newGroupMetadata
+  group.updatedAt = eventTime
+  await store.save<WorkingGroup>(group)
+
+  const result = new WorkingGroupMetadataSet()
+  result.metadataId = newGroupMetadata.id
+
+  return result
+}
+
+async function handleWorkingGroupMetadataAction(
+  store: DatabaseManager,
+  event: SubstrateEvent,
+  statusChangedEvent: StatusTextChangedEvent,
+  action: IWorkingGroupMetadataAction
+): Promise<typeof WorkingGroupMetadataActionResult> {
+  if (action.addUpcomingOpening) {
+    return handleAddUpcomingOpeningAction(store, event, statusChangedEvent, action.addUpcomingOpening)
+  } else if (action.removeUpcomingOpening) {
+    return handleRemoveUpcomingOpeningAction(store, action.removeUpcomingOpening)
+  } else if (action.setGroupMetadata) {
+    return handleSetWorkingGroupMetadataAction(store, event, statusChangedEvent, action.setGroupMetadata)
+  } else {
+    const result = new InvalidActionMetadata()
+    result.reason = 'No known action was provided'
+    return result
+  }
+}
+
+async function handleTerminatedWorker({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [workerId, optPenalty, optRationale] = new WorkingGroups.TerminatedWorkerEvent(event).params
+  const group = await getWorkingGroup(store, event)
+  const worker = await getWorker(store, `${group.name}-${workerId.toString()}`)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const EventConstructor = worker.isLead ? TerminatedLeaderEvent : TerminatedWorkerEvent
+
+  const terminatedEvent = new EventConstructor({
+    ...genericEventFields(event),
+    group,
+    worker,
+    penalty: optPenalty.unwrapOr(undefined),
+    rationale: optRationale.isSome ? bytesToString(optRationale.unwrap()) : undefined,
+  })
+
+  await store.save(terminatedEvent)
+
+  const status = new WorkerStatusTerminated()
+  status.terminatedWorkerEventId = terminatedEvent.id
+  worker.status = status
+  worker.stake = new BN(0)
+  worker.rewardPerBlock = new BN(0)
+  worker.updatedAt = eventTime
+
+  await store.save<Worker>(worker)
+}
+
+export async function findLeaderSetEventByTxHash(store: DatabaseManager, txHash?: string): Promise<LeaderSetEvent> {
+  const leaderSetEvent = await store.get(LeaderSetEvent, { where: { inExtrinsic: txHash } })
+
+  if (!leaderSetEvent) {
+    throw new Error(`LeaderSet event not found by tx hash: ${txHash}`)
+  }
+
+  return leaderSetEvent
+}
+
+// Mapping functions
+export async function workingGroups_OpeningAdded({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [
+    openingRuntimeId,
+    metadataBytes,
+    openingType,
+    stakePolicy,
+    optRewardPerBlock,
+  ] = new WorkingGroups.OpeningAddedEvent(event).params
+  const group = await getWorkingGroup(store, event)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const opening = new WorkingGroupOpening({
+    createdAt: eventTime,
+    updatedAt: eventTime,
+    id: `${group.name}-${openingRuntimeId.toString()}`,
+    runtimeId: openingRuntimeId.toNumber(),
+    applications: [],
+    group,
+    rewardPerBlock: optRewardPerBlock.unwrapOr(new BN(0)),
+    stakeAmount: stakePolicy.stake_amount,
+    unstakingPeriod: stakePolicy.leaving_unstaking_period.toNumber(),
+    status: new OpeningStatusOpen(),
+    type: openingType.isLeader ? WorkingGroupOpeningType.LEADER : WorkingGroupOpeningType.REGULAR,
+  })
+
+  const metadata = await createOpeningMeta(store, event, metadataBytes)
+  opening.metadata = metadata
+
+  await store.save<WorkingGroupOpening>(opening)
+
+  const openingAddedEvent = new OpeningAddedEvent({
+    ...genericEventFields(event),
+    group,
+    opening,
+  })
+
+  await store.save<OpeningAddedEvent>(openingAddedEvent)
+}
+
+export async function workingGroups_AppliedOnOpening({ store, event }: EventContext & StoreContext): Promise<void> {
+  const eventTime = new Date(event.blockTimestamp)
+
+  const [
+    {
+      opening_id: openingRuntimeId,
+      description: metadataBytes,
+      member_id: memberId,
+      reward_account_id: rewardAccount,
+      role_account_id: roleAccout,
+      stake_parameters: { stake, staking_account_id: stakingAccount },
+    },
+    applicationRuntimeId,
+  ] = new WorkingGroups.AppliedOnOpeningEvent(event).params
+
+  const group = await getWorkingGroup(store, event)
+  const openingstoreId = `${group.name}-${openingRuntimeId.toString()}`
+
+  const application = new WorkingGroupApplication({
+    createdAt: eventTime,
+    updatedAt: eventTime,
+    id: `${group.name}-${applicationRuntimeId.toString()}`,
+    runtimeId: applicationRuntimeId.toNumber(),
+    opening: new WorkingGroupOpening({ id: openingstoreId }),
+    applicant: new Membership({ id: memberId.toString() }),
+    rewardAccount: rewardAccount.toString(),
+    roleAccount: roleAccout.toString(),
+    stakingAccount: stakingAccount.toString(),
+    status: new ApplicationStatusPending(),
+    answers: [],
+    stake,
+  })
+
+  await store.save<WorkingGroupApplication>(application)
+  await createApplicationQuestionAnswers(store, application, metadataBytes)
+
+  const appliedOnOpeningEvent = new AppliedOnOpeningEvent({
+    ...genericEventFields(event),
+    group,
+    opening: new WorkingGroupOpening({ id: openingstoreId }),
+    application,
+  })
+
+  await store.save<AppliedOnOpeningEvent>(appliedOnOpeningEvent)
+}
+
+export async function workingGroups_LeaderSet({ store, event }: EventContext & StoreContext): Promise<void> {
+  const group = await getWorkingGroup(store, event)
+
+  const leaderSetEvent = new LeaderSetEvent({
+    ...genericEventFields(event),
+    group,
+  })
+
+  await store.save<LeaderSetEvent>(leaderSetEvent)
+}
+
+export async function workingGroups_OpeningFilled({ store, event }: EventContext & StoreContext): Promise<void> {
+  const eventTime = new Date(event.blockTimestamp)
+
+  const [openingRuntimeId, applicationIdToWorkerIdMap, applicationIdsSet] = new WorkingGroups.OpeningFilledEvent(
+    event
+  ).params
+
+  const group = await getWorkingGroup(store, event)
+  const opening = await getOpening(store, `${group.name}-${openingRuntimeId.toString()}`, [
+    'applications',
+    'applications.applicant',
+  ])
+  const acceptedApplicationIds = createType('Vec<ApplicationId>', applicationIdsSet.toHex() as any)
+
+  // Save the event
+  const openingFilledEvent = new OpeningFilledEvent({
+    ...genericEventFields(event),
+    group,
+    opening,
+  })
+
+  await store.save<OpeningFilledEvent>(openingFilledEvent)
+
+  // Update applications and create new workers
+  const hiredWorkers = (
+    await Promise.all(
+      (opening.applications || [])
+        // Skip withdrawn applications
+        .filter((application) => application.status.isTypeOf !== 'ApplicationStatusWithdrawn')
+        .map(async (application) => {
+          const isAccepted = acceptedApplicationIds.some((runtimeId) => runtimeId.toNumber() === application.runtimeId)
+          const applicationStatus = isAccepted ? new ApplicationStatusAccepted() : new ApplicationStatusRejected()
+          applicationStatus.openingFilledEventId = openingFilledEvent.id
+          application.status = applicationStatus
+          application.updatedAt = eventTime
+          await store.save<WorkingGroupApplication>(application)
+          if (isAccepted) {
+            // Cannot use "applicationIdToWorkerIdMap.get" here,
+            // it only works if the passed instance is identical to BTreeMap key instance (=== instead of .eq)
+            const [, workerRuntimeId] =
+              Array.from(applicationIdToWorkerIdMap.entries()).find(
+                ([applicationRuntimeId]) => applicationRuntimeId.toNumber() === application.runtimeId
+              ) || []
+            if (!workerRuntimeId) {
+              throw new Error(
+                `Fatal: No worker id found by accepted application id ${application.id} when handling OpeningFilled event!`
+              )
+            }
+            const worker = new Worker({
+              createdAt: eventTime,
+              updatedAt: eventTime,
+              id: `${group.name}-${workerRuntimeId.toString()}`,
+              runtimeId: workerRuntimeId.toNumber(),
+              application,
+              group,
+              isLead: opening.type === WorkingGroupOpeningType.LEADER,
+              membership: application.applicant,
+              stake: application.stake,
+              roleAccount: application.roleAccount,
+              rewardAccount: application.rewardAccount,
+              stakeAccount: application.stakingAccount,
+              payouts: [],
+              status: new WorkerStatusActive(),
+              entry: openingFilledEvent,
+              rewardPerBlock: opening.rewardPerBlock,
+            })
+            await store.save<Worker>(worker)
+            return worker
+          }
+        })
+    )
+  ).filter((w) => w !== undefined) as Worker[]
+
+  // Set opening status
+  const openingFilled = new OpeningStatusFilled()
+  openingFilled.openingFilledEventId = openingFilledEvent.id
+  opening.status = openingFilled
+  opening.updatedAt = eventTime
+  await store.save<WorkingGroupOpening>(opening)
+
+  // Update working group and LeaderSetEvent if necessary
+  if (opening.type === WorkingGroupOpeningType.LEADER && hiredWorkers.length) {
+    group.leader = hiredWorkers[0]
+    group.updatedAt = eventTime
+    await store.save<WorkingGroup>(group)
+
+    const leaderSetEvent = await findLeaderSetEventByTxHash(store, openingFilledEvent.inExtrinsic)
+    leaderSetEvent.worker = hiredWorkers[0]
+    leaderSetEvent.updatedAt = eventTime
+    await store.save<LeaderSetEvent>(leaderSetEvent)
+  }
+}
+
+export async function workingGroups_OpeningCanceled({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [openingRuntimeId] = new WorkingGroups.OpeningCanceledEvent(event).params
+
+  const group = await getWorkingGroup(store, event)
+  const opening = await getOpening(store, `${group.name}-${openingRuntimeId.toString()}`, ['applications'])
+  const eventTime = new Date(event.blockTimestamp)
+
+  // Create and save event
+  const openingCanceledEvent = new OpeningCanceledEvent({
+    ...genericEventFields(event),
+    group,
+    opening,
+  })
+
+  await store.save<OpeningCanceledEvent>(openingCanceledEvent)
+
+  // Set opening status
+  const openingCancelled = new OpeningStatusCancelled()
+  openingCancelled.openingCanceledEventId = openingCanceledEvent.id
+  opening.status = openingCancelled
+  opening.updatedAt = eventTime
+
+  await store.save<WorkingGroupOpening>(opening)
+
+  // Set applications status
+  const applicationCancelled = new ApplicationStatusCancelled()
+  applicationCancelled.openingCanceledEventId = openingCanceledEvent.id
+  await Promise.all(
+    (opening.applications || [])
+      // Skip withdrawn applications
+      .filter((application) => application.status.isTypeOf !== 'ApplicationStatusWithdrawn')
+      .map(async (application) => {
+        application.status = applicationCancelled
+        application.updatedAt = eventTime
+        await store.save<WorkingGroupApplication>(application)
+      })
+  )
+}
+
+export async function workingGroups_ApplicationWithdrawn({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [applicationRuntimeId] = new WorkingGroups.ApplicationWithdrawnEvent(event).params
+
+  const group = await getWorkingGroup(store, event)
+  const application = await getApplication(store, `${group.name}-${applicationRuntimeId.toString()}`)
+  const eventTime = new Date(event.blockTimestamp)
+
+  // Create and save event
+  const applicationWithdrawnEvent = new ApplicationWithdrawnEvent({
+    ...genericEventFields(event),
+    group,
+    application,
+  })
+
+  await store.save<ApplicationWithdrawnEvent>(applicationWithdrawnEvent)
+
+  // Set application status
+  const statusWithdrawn = new ApplicationStatusWithdrawn()
+  statusWithdrawn.applicationWithdrawnEventId = applicationWithdrawnEvent.id
+  application.status = statusWithdrawn
+  application.updatedAt = eventTime
+
+  await store.save<WorkingGroupApplication>(application)
+}
+
+export async function workingGroups_StatusTextChanged({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [, optBytes] = new WorkingGroups.StatusTextChangedEvent(event).params
+  const group = await getWorkingGroup(store, event)
+
+  // Since result cannot be empty at this point, but we already need to have an existing StatusTextChangedEvent
+  // in order to be able to create UpcomingOpening.createdInEvent relation, we use a temporary "mock" result
+  const mockResult = new InvalidActionMetadata()
+  mockResult.reason = 'Metadata not yet processed'
+  const statusTextChangedEvent = new StatusTextChangedEvent({
+    ...genericEventFields(event),
+    group,
+    metadata: optBytes.isSome ? optBytes.unwrap().toString() : undefined,
+    result: mockResult,
+  })
+
+  await store.save<StatusTextChangedEvent>(statusTextChangedEvent)
+
+  let result: typeof WorkingGroupMetadataActionResult
+
+  if (optBytes.isSome) {
+    const metadata = deserializeMetadata(WorkingGroupMetadataAction, optBytes.unwrap())
+    if (metadata) {
+      result = await handleWorkingGroupMetadataAction(store, event, statusTextChangedEvent, metadata)
+    } else {
+      result = new InvalidActionMetadata()
+      result.reason = 'Invalid metadata: Cannot deserialize metadata binary'
+    }
+  } else {
+    const error = 'No encoded metadata was provided'
+    console.error(`StatusTextChanged event: ${error}`)
+    result = new InvalidActionMetadata()
+    result.reason = error
+  }
+
+  // Now we can set the "real" result
+  statusTextChangedEvent.result = result
+  await store.save<StatusTextChangedEvent>(statusTextChangedEvent)
+}
+
+export async function workingGroups_WorkerRoleAccountUpdated({
+  store,
+  event,
+}: EventContext & StoreContext): Promise<void> {
+  const [workerId, accountId] = new WorkingGroups.WorkerRoleAccountUpdatedEvent(event).params
+  const group = await getWorkingGroup(store, event)
+  const worker = await getWorker(store, `${group.name}-${workerId.toString()}`)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const workerRoleAccountUpdatedEvent = new WorkerRoleAccountUpdatedEvent({
+    ...genericEventFields(event),
+    group,
+    worker,
+    newRoleAccount: accountId.toString(),
+  })
+
+  await store.save<WorkerRoleAccountUpdatedEvent>(workerRoleAccountUpdatedEvent)
+
+  worker.roleAccount = accountId.toString()
+  worker.updatedAt = eventTime
+
+  await store.save<Worker>(worker)
+}
+
+export async function workingGroups_WorkerRewardAccountUpdated({
+  store,
+  event,
+}: EventContext & StoreContext): Promise<void> {
+  const [workerId, accountId] = new WorkingGroups.WorkerRewardAccountUpdatedEvent(event).params
+  const group = await getWorkingGroup(store, event)
+  const worker = await getWorker(store, `${group.name}-${workerId.toString()}`)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const workerRewardAccountUpdatedEvent = new WorkerRewardAccountUpdatedEvent({
+    ...genericEventFields(event),
+    group,
+    worker,
+    newRewardAccount: accountId.toString(),
+  })
+
+  await store.save<WorkerRoleAccountUpdatedEvent>(workerRewardAccountUpdatedEvent)
+
+  worker.rewardAccount = accountId.toString()
+  worker.updatedAt = eventTime
+
+  await store.save<Worker>(worker)
+}
+
+export async function workingGroups_StakeIncreased({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [workerId, increaseAmount] = new WorkingGroups.StakeIncreasedEvent(event).params
+  const group = await getWorkingGroup(store, event)
+  const worker = await getWorker(store, `${group.name}-${workerId.toString()}`)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const stakeIncreasedEvent = new StakeIncreasedEvent({
+    ...genericEventFields(event),
+    group,
+    worker,
+    amount: increaseAmount,
+  })
+
+  await store.save<StakeIncreasedEvent>(stakeIncreasedEvent)
+
+  worker.stake = worker.stake.add(increaseAmount)
+  worker.updatedAt = eventTime
+
+  await store.save<Worker>(worker)
+}
+
+export async function workingGroups_RewardPaid({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [workerId, rewardAccountId, amount, rewardPaymentType] = new WorkingGroups.RewardPaidEvent(event).params
+  const group = await getWorkingGroup(store, event)
+  const worker = await getWorker(store, `${group.name}-${workerId.toString()}`)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const rewardPaidEvent = new RewardPaidEvent({
+    ...genericEventFields(event),
+    group,
+    worker,
+    amount,
+    rewardAccount: rewardAccountId.toString(),
+    type: rewardPaymentType.isRegularReward ? RewardPaymentType.REGULAR : RewardPaymentType.MISSED,
+  })
+
+  await store.save<RewardPaidEvent>(rewardPaidEvent)
+
+  // Update group budget
+  group.budget = group.budget.sub(amount)
+  group.updatedAt = eventTime
+
+  await store.save<WorkingGroup>(group)
+}
+
+export async function workingGroups_NewMissedRewardLevelReached({
+  store,
+  event,
+}: EventContext & StoreContext): Promise<void> {
+  const [workerId, newMissedRewardAmountOpt] = new WorkingGroups.NewMissedRewardLevelReachedEvent(event).params
+  const group = await getWorkingGroup(store, event)
+  const worker = await getWorker(store, `${group.name}-${workerId.toString()}`)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const newMissedRewardLevelReachedEvent = new NewMissedRewardLevelReachedEvent({
+    ...genericEventFields(event),
+    group,
+    worker,
+    newMissedRewardAmount: newMissedRewardAmountOpt.unwrapOr(new BN(0)),
+  })
+
+  await store.save<NewMissedRewardLevelReachedEvent>(newMissedRewardLevelReachedEvent)
+
+  // Update worker
+  worker.missingRewardAmount = newMissedRewardAmountOpt.unwrapOr(undefined)
+  worker.updatedAt = eventTime
+
+  await store.save<Worker>(worker)
+}
+
+export async function workingGroups_WorkerExited({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [workerId] = new WorkingGroups.WorkerExitedEvent(event).params
+  const group = await getWorkingGroup(store, event)
+  const worker = await getWorker(store, `${group.name}-${workerId.toString()}`)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const workerExitedEvent = new WorkerExitedEvent({
+    ...genericEventFields(event),
+    group,
+    worker,
+  })
+
+  await store.save<WorkerExitedEvent>(workerExitedEvent)
+  ;(worker.status as WorkerStatusLeft).workerExitedEventId = workerExitedEvent.id
+  worker.stake = new BN(0)
+  worker.rewardPerBlock = new BN(0)
+  worker.updatedAt = eventTime
+
+  await store.save<Worker>(worker)
+}
+
+export async function workingGroups_LeaderUnset({ store, event }: EventContext & StoreContext): Promise<void> {
+  const group = await getWorkingGroup(store, event)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const leaderUnsetEvent = new LeaderUnsetEvent({
+    ...genericEventFields(event),
+    group,
+    leader: group.leader,
+  })
+
+  await store.save<LeaderUnsetEvent>(leaderUnsetEvent)
+
+  group.leader = undefined
+  group.updatedAt = eventTime
+
+  await store.save<WorkingGroup>(group)
+}
+
+export async function workingGroups_TerminatedWorker(ctx: EventContext & StoreContext): Promise<void> {
+  await handleTerminatedWorker(ctx)
+}
+export async function workingGroups_TerminatedLeader(ctx: EventContext & StoreContext): Promise<void> {
+  await handleTerminatedWorker(ctx)
+}
+
+export async function workingGroups_WorkerRewardAmountUpdated({
+  store,
+  event,
+}: EventContext & StoreContext): Promise<void> {
+  const [workerId, newRewardPerBlockOpt] = new WorkingGroups.WorkerRewardAmountUpdatedEvent(event).params
+  const group = await getWorkingGroup(store, event)
+  const worker = await getWorker(store, `${group.name}-${workerId.toString()}`)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const workerRewardAmountUpdatedEvent = new WorkerRewardAmountUpdatedEvent({
+    ...genericEventFields(event),
+    group,
+    worker,
+    newRewardPerBlock: newRewardPerBlockOpt.unwrapOr(new BN(0)),
+  })
+
+  await store.save<WorkerRewardAmountUpdatedEvent>(workerRewardAmountUpdatedEvent)
+
+  worker.rewardPerBlock = newRewardPerBlockOpt.unwrapOr(new BN(0))
+  worker.updatedAt = eventTime
+
+  await store.save<Worker>(worker)
+}
+
+export async function workingGroups_StakeSlashed({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [workerId, slashedAmount, requestedAmount, optRationale] = new WorkingGroups.StakeSlashedEvent(event).params
+  const group = await getWorkingGroup(store, event)
+  const worker = await getWorker(store, `${group.name}-${workerId.toString()}`)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const workerStakeSlashedEvent = new StakeSlashedEvent({
+    ...genericEventFields(event),
+    group,
+    worker,
+    requestedAmount,
+    slashedAmount,
+    rationale: optRationale.isSome ? bytesToString(optRationale.unwrap()) : undefined,
+  })
+
+  await store.save<StakeSlashedEvent>(workerStakeSlashedEvent)
+
+  worker.stake = worker.stake.sub(slashedAmount)
+  worker.updatedAt = eventTime
+
+  await store.save<Worker>(worker)
+}
+
+export async function workingGroups_StakeDecreased({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [workerId, amount] = new WorkingGroups.StakeDecreasedEvent(event).params
+  const group = await getWorkingGroup(store, event)
+  const worker = await getWorker(store, `${group.name}-${workerId.toString()}`)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const workerStakeDecreasedEvent = new StakeDecreasedEvent({
+    ...genericEventFields(event),
+    group,
+    worker,
+    amount,
+  })
+
+  await store.save<StakeDecreasedEvent>(workerStakeDecreasedEvent)
+
+  worker.stake = worker.stake.sub(amount)
+  worker.updatedAt = eventTime
+
+  await store.save<Worker>(worker)
+}
+
+export async function workingGroups_WorkerStartedLeaving({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [workerId, optRationale] = new WorkingGroups.WorkerStartedLeavingEvent(event).params
+  const group = await getWorkingGroup(store, event)
+  const worker = await getWorker(store, `${group.name}-${workerId.toString()}`)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const workerStartedLeavingEvent = new WorkerStartedLeavingEvent({
+    ...genericEventFields(event),
+    group,
+    worker,
+    rationale: optRationale.isSome ? bytesToString(optRationale.unwrap()) : undefined,
+  })
+
+  await store.save<WorkerStartedLeavingEvent>(workerStartedLeavingEvent)
+
+  const status = new WorkerStatusLeft()
+  status.workerStartedLeavingEventId = workerStartedLeavingEvent.id
+  worker.status = status
+  worker.updatedAt = eventTime
+
+  await store.save<Worker>(worker)
+}
+
+export async function workingGroups_BudgetSet({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [newBudget] = new WorkingGroups.BudgetSetEvent(event).params
+  const group = await getWorkingGroup(store, event)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const budgetSetEvent = new BudgetSetEvent({
+    ...genericEventFields(event),
+    group,
+    newBudget,
+  })
+
+  await store.save<BudgetSetEvent>(budgetSetEvent)
+
+  group.budget = newBudget
+  group.updatedAt = eventTime
+
+  await store.save<WorkingGroup>(group)
+}
+
+export async function workingGroups_BudgetSpending({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [reciever, amount, optRationale] = new WorkingGroups.BudgetSpendingEvent(event).params
+  const group = await getWorkingGroup(store, event)
+  const eventTime = new Date(event.blockTimestamp)
+
+  const budgetSpendingEvent = new BudgetSpendingEvent({
+    ...genericEventFields(event),
+    group,
+    amount,
+    reciever: reciever.toString(),
+    rationale: optRationale.isSome ? bytesToString(optRationale.unwrap()) : undefined,
+  })
+
+  await store.save<BudgetSpendingEvent>(budgetSpendingEvent)
+
+  group.budget = group.budget.sub(amount)
+  group.updatedAt = eventTime
+
+  await store.save<WorkingGroup>(group)
+}

+ 3 - 3
query-node/package.json

@@ -24,8 +24,8 @@
     "bootstrap": "yarn codegen && yarn db:drop && yarn db:bootstrap",
     "hydra-cli": "./codegen/node_modules/.bin/hydra-cli",
     "hydra-typegen": "./codegen/node_modules/.bin/hydra-typegen",
-    "codegen": "yarn hydra-cli codegen",
-    "codegen:noinstall": "yarn hydra-cli codegen --no-install",
+    "codegen": "yarn hydra-cli codegen --schema ../../schemas/",
+    "codegen:noinstall": "yarn codegen --no-install",
     "typegen:configure": "TYPEGEN_WS_URI=${TYPEGEN_WS_URI:-ws://localhost:9944} yarn envsub manifest.yml typegen.yml",
     "typegen": "rm -rf ./mappings/generated && yarn hydra-typegen typegen typegen.yml --debug",
     "mappings:build": "yarn workspace query-node-mappings build",
@@ -42,7 +42,7 @@
     "tslib": "^2.0.0",
     "@types/bn.js": "^4.11.6",
     "bn.js": "^5.1.2",
-    "@dzlzv/hydra-processor": "2.0.1-beta.15",
+    "@dzlzv/hydra-processor": "3.0.0-beta.6",
     "envsub": "4.0.7"
   },
   "volta": {

+ 6 - 1
query-node/run-tests.sh

@@ -25,4 +25,9 @@ docker-compose down -v
 
 ./start.sh
 
-time yarn workspace integration-tests run-test-scenario olympia
+# pass the scenario name without .ts extension
+SCENARIO=$1
+# fallback if scenario if not specified
+SCENARIO=${SCENARIO:=full}
+
+time yarn workspace integration-tests run-test-scenario ${SCENARIO}

+ 24 - 0
query-node/schemas/common.graphql

@@ -0,0 +1,24 @@
+enum Network {
+  BABYLON
+  ALEXANDRIA
+  ROME
+  OLYMPIA
+}
+
+# FIXME: https://github.com/Joystream/hydra/issues/359
+interface Event @entity {
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+}

+ 37 - 32
query-node/schema.graphql → query-node/schemas/membership.graphql

@@ -1,24 +1,32 @@
-enum Network {
-  BABYLON
-  ALEXANDRIA
-  ROME
-  OLYMPIA
+type MemberMetadata @entity {
+  "Member's name"
+  name: String
+
+  "Avatar data object"
+  avatar: DataObject
+
+  "Short text chosen by member to share information about themselves"
+  about: String
 }
 
-type Block @entity {
-  "Block number as a string"
-  id: ID!
-  block: Int!
-  executedAt: DateTime!
-  network: Network!
+type MembershipEntryPaid @variant {
+  "The event the membership was bought in"
+  # Must be optional because of member.entry <=> membershipBoughtEvent.newMember cross relationship
+  membershipBoughtEvent: MembershipBoughtEvent
+}
+
+type MembershipEntryInvited @variant {
+  "The event the member was invited in"
+  # Must be optional because of member.entry <=> memberInvitedEvent.newMember cross relationship
+  memberInvitedEvent: MemberInvitedEvent
 }
 
-enum MembershipEntryMethod {
-  PAID
-  INVITED
-  GENESIS
+type MembershipEntryGenesis @variant {
+  phantom: Int
 }
 
+union MembershipEntryMethod = MembershipEntryPaid | MembershipEntryInvited | MembershipEntryGenesis
+
 "Stored information about a registered user"
 type Membership @entity {
   "MemberId: runtime identifier for a user"
@@ -27,14 +35,8 @@ type Membership @entity {
   "The unique handle chosen by member"
   handle: String! @unique @fulltext(query: "membersByHandle")
 
-  "Member's name"
-  name: String
-
-  "A Url to member's Avatar image"
-  avatarUri: String
-
-  "Short text chosen by member to share information about themselves"
-  about: String
+  "Member's metadata"
+  metadata: MemberMetadata!
 
   "Member's controller account id"
   controllerAccount: String!
@@ -42,12 +44,6 @@ type Membership @entity {
   "Member's root account id"
   rootAccount: String!
 
-  "Blocknumber when member was registered"
-  registeredAtBlock: Block!
-
-  "Timestamp when member was registered"
-  registeredAtTime: DateTime!
-
   "How the member was registered"
   entry: MembershipEntryMethod!
 
@@ -71,17 +67,26 @@ type Membership @entity {
 
   "A member that referred this member (if any)"
   referredBy: Membership
+
+  "Whether member is founding member."
+  isFoundingMember: Boolean!
+
+  "Member's working group roles (current and past)"
+  roles: [Worker!] @derivedFrom(field: "membership")
 }
 
-type MembershipSystem @entity {
+type MembershipSystemSnapshot @entity {
+  "The snapshot block number"
+  snapshotBlock: Int!
+
   "Initial invitation count of a new member."
   defaultInviteCount: Int!
 
   "Current price to buy a membership."
   membershipPrice: BigInt!
 
-  "Amount of tokens diverted to invitor."
-  referralCut: BigInt!
+  "Percentage of tokens diverted to invitor."
+  referralCut: Int!
 
   "The initial, locked, balance credited to controller account of invitee."
   invitedInitialBalance: BigInt!

+ 398 - 0
query-node/schemas/membershipEvents.graphql

@@ -0,0 +1,398 @@
+type MembershipBoughtEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "New membership created."
+  newMember: Membership!
+
+  "New member root account in SS58 encoding."
+  rootAccount: String!
+
+  "New member controller in SS58 encoding."
+  controllerAccount: String!
+
+  "New member handle."
+  handle: String!
+
+  "New member metadata"
+  metadata: MemberMetadata!
+
+  "Referrer member."
+  referrer: Membership
+}
+
+type MemberInvitedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Inviting member."
+  invitingMember: Membership!
+
+  "New membership created."
+  newMember: Membership!
+
+  "New member root account in SS58 encoding."
+  rootAccount: String!
+
+  "New member controller in SS58 encoding."
+  controllerAccount: String!
+
+  "New member handle."
+  handle: String!
+
+  "New member metadata"
+  metadata: MemberMetadata!
+}
+
+type MemberProfileUpdatedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Membership being updated."
+  member: Membership!
+
+  "New member handle. Null means no new value was provided."
+  newHandle: String
+
+  "New member metadata. (empty values inside metadata mean no new value was provided)"
+  newMetadata: MemberMetadata!
+}
+
+type MemberAccountsUpdatedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Membership in question."
+  member: Membership!
+
+  "New member root account in SS58 encoding. Null means no new value was provided."
+  newRootAccount: String
+
+  "New member controller in SS58 encoding. Null means no new value was provided."
+  newControllerAccount: String
+}
+
+type MemberVerificationStatusUpdatedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Membership in question."
+  member: Membership!
+
+  "Worker updating status"
+  worker: Worker!
+
+  "New status."
+  isVerified: Boolean!
+}
+
+type ReferralCutUpdatedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "New cut value."
+  newValue: Int!
+}
+
+type InvitesTransferredEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Membership sending invites."
+  sourceMember: Membership!
+
+  "Membership receiving invites."
+  targetMember: Membership!
+
+  "Number of invites transferred."
+  numberOfInvites: Int!
+}
+
+type MembershipPriceUpdatedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "The new membership price."
+  newPrice: BigInt!
+}
+
+type InitialInvitationBalanceUpdatedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "New initial invitation balance."
+  newInitialBalance: BigInt!
+}
+
+type LeaderInvitationQuotaUpdatedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "New quota."
+  newInvitationQuota: Int!
+}
+
+type InitialInvitationCountUpdatedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "New initial invitation count for members."
+  newInitialInvitationCount: Int!
+}
+
+type StakingAccountAddedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Membership in question."
+  member: Membership!
+
+  "New staking account in SS58 encoding."
+  account: String!
+}
+
+type StakingAccountConfirmedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Membership in question."
+  member: Membership!
+
+  "New staking account in SS58 encoding."
+  account: String!
+}
+
+type StakingAccountRemovedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Membership in question."
+  member: Membership!
+
+  "New staking account in SS58 encoding."
+  account: String!
+}

+ 91 - 0
query-node/schemas/storage.graphql

@@ -0,0 +1,91 @@
+"The decision of the storage provider when it acts as liaison"
+enum LiaisonJudgement {
+  "Content awaits for a judgment"
+  PENDING
+
+  "Content accepted"
+  ACCEPTED
+
+  "Content rejected"
+  REJECTED
+}
+
+"Manages content ids, type and storage provider decision about it"
+type DataObject @entity {
+  "Content owner"
+  owner: DataObjectOwner!
+
+  "Content added at"
+  addedAt: Int!
+
+  "Content type id"
+  typeId: Int!
+
+  "Content size in bytes"
+  size: BigInt!
+
+  "Storage provider id of the liaison"
+  liaisonId: BigInt!
+
+  "Storage provider as liaison judgment"
+  liaisonJudgement: LiaisonJudgement!
+
+  "IPFS content id"
+  ipfsContentId: String!
+
+  "Joystream runtime content"
+  joystreamContentId: String!
+}
+
+"Owner type for storage object"
+union DataObjectOwner =
+    DataObjectOwnerMember
+  | DataObjectOwnerChannel
+  | DataObjectOwnerDao
+  | DataObjectOwnerCouncil
+  | DataObjectOwnerWorkingGroup
+
+"Asset owned by a member"
+type DataObjectOwnerMember @variant {
+  # use `BigInt` instead of `Membership` before variant relations are featured in Hydra
+  #"Member identifier"
+  #memberId: Membership!
+  "Member identifier"
+  member: BigInt!
+
+  "Variant needs to have at least one property. This value is not used."
+  dummy: Int
+}
+
+"Asset owned by a channel"
+type DataObjectOwnerChannel @variant {
+  # use `BigInt` instead of `Channel` before variant relations are featured in Hydra
+  #"Channel identifier"
+  #channel: Channel!
+  "Channel identifier"
+  channel: BigInt!
+
+  "Variant needs to have at least one property. This value is not used."
+  dummy: Int
+}
+
+"Asset owned by a DAO"
+type DataObjectOwnerDao @variant {
+  "DAO identifier"
+  dao: BigInt!
+}
+
+"Asset owned by the Council"
+type DataObjectOwnerCouncil @variant {
+  "Variant needs to have at least one property. This value is not used."
+  dummy: Int
+}
+
+"Asset owned by a WorkingGroup"
+type DataObjectOwnerWorkingGroup @variant {
+  #"Working group identifier"
+  #workingGroup: BigInt!
+
+  "Variant needs to have at least one property. This value is not used."
+  dummy: Int
+}

+ 316 - 0
query-node/schemas/workingGroups.graphql

@@ -0,0 +1,316 @@
+type WorkerStatusActive @variant {
+  # No additional information needed
+  _phantom: Int
+}
+
+type WorkerStatusLeft @variant {
+  "Related event emitted on leaving initialization"
+  workerStartedLeavingEvent: WorkerStartedLeavingEvent!
+
+  "Related event emitted (and set) when the unstaking period is finished"
+  workerExitedEvent: WorkerExitedEvent
+}
+
+type WorkerStatusTerminated @variant {
+  "Related event emitted on worker termination"
+  terminatedWorkerEvent: TerminatedWorkerEvent!
+}
+
+union WorkerStatus = WorkerStatusActive | WorkerStatusLeft | WorkerStatusTerminated
+
+# Working Groups
+type Worker @entity {
+  "Worker id ({workingGroupName}-{workerId})"
+  id: ID!
+
+  "WorkerId in specific working group module"
+  runtimeId: Int!
+
+  "The group that the worker belongs to"
+  group: WorkingGroup!
+
+  "Worker membership"
+  membership: Membership!
+
+  "Worker's role account"
+  roleAccount: String!
+
+  "Worker's reward account"
+  rewardAccount: String!
+
+  "Worker's staking account"
+  stakeAccount: String!
+
+  "Current worker status"
+  status: WorkerStatus!
+
+  "Whether the worker is also the working group lead"
+  isLead: Boolean!
+
+  "Current role stake (in JOY)"
+  stake: BigInt!
+
+  "Current reward per block"
+  rewardPerBlock: BigInt!
+
+  "The reward amount the worker is currently missing (due to empty working group budget)"
+  missingRewardAmount: BigInt
+
+  "All related reward payouts"
+  payouts: [RewardPaidEvent!] @derivedFrom(field: "worker")
+
+  "All related stake slashes"
+  slashes: [StakeSlashedEvent!] @derivedFrom(field: "worker")
+
+  "The event that caused the worker to be hired"
+  entry: OpeningFilledEvent!
+
+  "Related worker entry application"
+  application: WorkingGroupApplication!
+
+  "Worker's storage data"
+  storage: String
+}
+
+type WorkingGroupMetadata @entity {
+  "Working group status"
+  status: String
+
+  "Working group status message"
+  statusMessage: String
+
+  "Working group about text"
+  about: String
+
+  "Working group description text"
+  description: String
+
+  "Event the working group metadata was set in"
+  setInEvent: StatusTextChangedEvent!
+
+  "Related group"
+  group: WorkingGroup!
+}
+
+type WorkingGroup @entity {
+  "Working group id (currently === name)"
+  id: ID!
+
+  "Working group name"
+  name: String! @unique
+
+  "Working group current metadata"
+  metadata: WorkingGroupMetadata
+
+  "Current working group leader"
+  leader: Worker
+
+  "Workers that currently belong to the group or belonged to the group in the past"
+  workers: [Worker!] @derivedFrom(field: "group")
+
+  "All openings related to this group"
+  openings: [WorkingGroupOpening!] @derivedFrom(field: "group")
+
+  "Current working group budget (JOY)"
+  budget: BigInt!
+}
+
+type OpeningStatusCancelled @variant {
+  "Related event emitted on opening cancellation"
+  openingCanceledEvent: OpeningCanceledEvent!
+}
+
+type OpeningStatusOpen @variant {
+  # No additional information needed
+  _phantom: Int
+}
+
+type OpeningStatusFilled @variant {
+  "Related event emitted after filling the opening"
+  openingFilledEvent: OpeningFilledEvent!
+}
+
+union WorkingGroupOpeningStatus = OpeningStatusOpen | OpeningStatusFilled | OpeningStatusCancelled
+
+enum WorkingGroupOpeningType {
+  REGULAR
+  LEADER
+}
+
+type WorkingGroupOpeningMetadata @entity {
+  "Whether the originally provided metadata was valid"
+  originallyValid: Boolean!
+
+  "Opening short description"
+  shortDescription: String
+
+  "Opening description (md-formatted)"
+  description: String
+
+  "Expected max. number of applicants that will be hired"
+  hiringLimit: Int
+
+  "Expected time when the opening will close"
+  expectedEnding: DateTime
+
+  "Md-formatted text explaining the application process"
+  applicationDetails: String
+
+  "List of questions that should be answered during application"
+  applicationFormQuestions: [ApplicationFormQuestion!] @derivedFrom(field: "openingMetadata")
+}
+
+type WorkingGroupOpening @entity {
+  "Opening id ({workingGroupName}-{openingId})"
+  id: ID!
+
+  "OpeningId in specific working group module"
+  runtimeId: Int!
+
+  "Related working group"
+  group: WorkingGroup!
+
+  "List of opening applications"
+  applications: [WorkingGroupApplication!] @derivedFrom(field: "opening")
+
+  "Type of the opening (Leader/Regular)"
+  type: WorkingGroupOpeningType!
+
+  "Current opening status"
+  status: WorkingGroupOpeningStatus!
+
+  "Opening metadata"
+  metadata: WorkingGroupOpeningMetadata!
+
+  "Min. application/role stake amount"
+  stakeAmount: BigInt!
+
+  "Role stake unstaking period in blocks"
+  unstakingPeriod: Int!
+
+  "Initial workers' reward per block"
+  rewardPerBlock: BigInt!
+
+  "Event the opening was created in"
+  createdInEvent: OpeningAddedEvent! @derivedFrom(field: "opening")
+
+  "Time of opening creation"
+  createdAt: DateTime!
+}
+
+type UpcomingWorkingGroupOpening @entity {
+  "Event the upcoming opening was created in"
+  createdInEvent: StatusTextChangedEvent!
+
+  "Related working group"
+  group: WorkingGroup!
+
+  "Expected opening start time"
+  expectedStart: DateTime
+
+  "Expected min. application/role stake amount"
+  stakeAmount: BigInt
+
+  "Expected reward per block"
+  rewardPerBlock: BigInt
+
+  "Opening metadata"
+  metadata: WorkingGroupOpeningMetadata!
+}
+
+type ApplicationStatusPending @variant {
+  # No additional information needed
+  _phantom: Int
+}
+
+type ApplicationStatusAccepted @variant {
+  "Related OpeningFilled event"
+  openingFilledEvent: OpeningFilledEvent!
+}
+
+type ApplicationStatusRejected @variant {
+  "Related OpeningFilled event"
+  openingFilledEvent: OpeningFilledEvent!
+}
+
+type ApplicationStatusCancelled @variant {
+  "Related OpeningCanceled event"
+  openingCanceledEvent: OpeningCanceledEvent!
+}
+
+type ApplicationStatusWithdrawn @variant {
+  "Related ApplicationWithdrawn event"
+  applicationWithdrawnEvent: ApplicationWithdrawnEvent!
+}
+
+union WorkingGroupApplicationStatus =
+    ApplicationStatusPending
+  | ApplicationStatusAccepted
+  | ApplicationStatusRejected
+  | ApplicationStatusWithdrawn
+  | ApplicationStatusCancelled
+
+type WorkingGroupApplication @entity {
+  "Application id ({workingGroupName}-{applicationId})"
+  id: ID!
+
+  "ApplicationId in specific working group module"
+  runtimeId: Int!
+
+  "Related working group opening"
+  opening: WorkingGroupOpening!
+
+  "Applicant's membership"
+  applicant: Membership!
+
+  "Application stake"
+  stake: BigInt!
+
+  "Applicant's initial role account"
+  roleAccount: String!
+
+  "Applicant's initial reward account"
+  rewardAccount: String!
+
+  "Applicant's initial staking account"
+  stakingAccount: String!
+
+  "Answers to application form questions"
+  answers: [ApplicationFormQuestionAnswer!] @derivedFrom(field: "application")
+
+  "Current application status"
+  status: WorkingGroupApplicationStatus!
+
+  "Event the application was created in"
+  createdInEvent: AppliedOnOpeningEvent! @derivedFrom(field: "application")
+}
+
+type ApplicationFormQuestionAnswer @entity {
+  "Related application"
+  application: WorkingGroupApplication!
+
+  "The question beeing answered"
+  question: ApplicationFormQuestion!
+
+  "Applicant's answer"
+  answer: String!
+}
+
+enum ApplicationFormQuestionType {
+  TEXT
+  TEXTAREA
+}
+
+type ApplicationFormQuestion @entity {
+  "Related opening metadata"
+  openingMetadata: WorkingGroupOpeningMetadata!
+
+  "The question itself"
+  question: String
+
+  "Type of the question (UI answer input type)"
+  type: ApplicationFormQuestionType!
+
+  "Index of the question"
+  index: Int!
+}

+ 695 - 0
query-node/schemas/workingGroupsEvents.graphql

@@ -0,0 +1,695 @@
+type OpeningAddedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related opening"
+  opening: WorkingGroupOpening!
+
+  # Other opening data like: metadata, type, staking policy, reward etc. is immutable, so can be read directly from Opening entity
+}
+
+type AppliedOnOpeningEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related opening"
+  opening: WorkingGroupOpening!
+
+  "The application that was created"
+  application: WorkingGroupApplication!
+
+  # Same as with opening - application parameters are immutable and can be fetched from Application entity
+}
+
+type OpeningFilledEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related opening"
+  opening: WorkingGroupOpening!
+
+  "Workers that have been hired as a result of filling the opening"
+  workersHired: [Worker!] @derivedFrom(field: "entry")
+}
+
+type LeaderSetEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  # The field must be optional, because at the time the event is emitted the worker does not yet exist
+  "Related Lead worker"
+  worker: Worker
+}
+
+type WorkerRoleAccountUpdatedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related worker"
+  worker: Worker!
+
+  "New role account"
+  newRoleAccount: String!
+}
+
+type LeaderUnsetEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "A leader that was unset"
+  leader: Worker!
+}
+
+type WorkerExitedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related worker"
+  worker: Worker!
+}
+
+type TerminatedWorkerEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related worker"
+  worker: Worker!
+
+  "Slash amount (if any)"
+  penalty: BigInt
+
+  "Optional rationale"
+  rationale: String
+}
+
+type TerminatedLeaderEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related worker"
+  worker: Worker!
+
+  "Slash amount (if any)"
+  penalty: BigInt
+
+  "Optional rationale"
+  rationale: String
+}
+
+type WorkerStartedLeavingEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related worker"
+  worker: Worker!
+
+  "Optional rationale"
+  rationale: String
+}
+
+type StakeSlashedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related worker"
+  worker: Worker!
+
+  "Balance that was requested to be slashed"
+  requestedAmount: BigInt!
+
+  "Balance that was actually slashed"
+  slashedAmount: BigInt!
+
+  "Optional rationale"
+  rationale: String
+}
+
+type StakeDecreasedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related worker"
+  worker: Worker!
+
+  "The amount of JOY the stake was decreased by"
+  amount: BigInt!
+}
+
+type StakeIncreasedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related worker"
+  worker: Worker!
+
+  "The amount of JOY the stake was increased by"
+  amount: BigInt!
+}
+
+type ApplicationWithdrawnEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related application"
+  application: WorkingGroupApplication!
+}
+
+type OpeningCanceledEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related opening"
+  opening: WorkingGroupOpening!
+}
+
+type BudgetSetEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "New working group budget"
+  newBudget: BigInt!
+}
+
+type WorkerRewardAccountUpdatedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related worker"
+  worker: Worker!
+
+  "New reward account"
+  newRewardAccount: String!
+}
+
+type WorkerRewardAmountUpdatedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related worker"
+  worker: Worker!
+
+  "New worker reward per block"
+  newRewardPerBlock: BigInt!
+}
+
+type UpcomingOpeningAdded @variant {
+  upcomingOpeningId: ID!
+}
+
+type UpcomingOpeningRemoved @variant {
+  upcomingOpeningId: ID!
+}
+
+type WorkingGroupMetadataSet @variant {
+  "The new metadata snapshot resulting from the update"
+  metadata: WorkingGroupMetadata!
+}
+
+type InvalidActionMetadata @variant {
+  "Reason why the action metadata was considered invalid"
+  reason: String!
+}
+
+union WorkingGroupMetadataActionResult =
+    UpcomingOpeningAdded
+  | UpcomingOpeningRemoved
+  | WorkingGroupMetadataSet
+  | InvalidActionMetadata
+
+type StatusTextChangedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Original action metadata as hex string"
+  metadata: String
+
+  "Event result depeding on the metadata action type"
+  result: WorkingGroupMetadataActionResult!
+}
+
+type BudgetSpendingEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Reciever account address"
+  reciever: String!
+
+  "Amount beeing spent"
+  amount: BigInt!
+
+  "Optional rationale"
+  rationale: String
+}
+
+enum RewardPaymentType {
+  "Regular reward payout"
+  REGULAR
+  "Payout of previously missed reward"
+  MISSED
+}
+
+type RewardPaidEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related worker"
+  worker: Worker!
+
+  "The account that recieved the reward"
+  rewardAccount: String!
+
+  "Amount recieved"
+  amount: BigInt!
+
+  "Type of the payment (REGULAR/MISSED)"
+  type: RewardPaymentType!
+}
+
+type NewMissedRewardLevelReachedEvent @entity {
+  ### GENERIC DATA ###
+
+  "(network}-{blockNumber}-{indexInBlock}"
+  id: ID!
+
+  "Hash of the extrinsic which caused the event to be emitted"
+  inExtrinsic: String
+
+  "Blocknumber of the block in which the event was emitted."
+  inBlock: Int!
+
+  "Network the block was produced in"
+  network: Network!
+
+  "Index of event in block from which it was emitted."
+  indexInBlock: Int!
+
+  ### SPECIFIC DATA ###
+
+  "Related group"
+  group: WorkingGroup!
+
+  "Related worker"
+  worker: Worker!
+
+  "New missed reward amount"
+  newMissedRewardAmount: BigInt!
+}

+ 6 - 0
query-node/start.sh

@@ -1,3 +1,9 @@
+#!/usr/bin/env bash
+set -e
+
+SCRIPT_PATH="$(dirname "${BASH_SOURCE[0]}")"
+cd $SCRIPT_PATH
+
 set -a
 . ../.env
 set +a

+ 11 - 0
tests/integration-tests/.env

@@ -12,6 +12,17 @@ MEMBERSHIP_CREATION_N = 2
 MEMBERS_INVITE_N = 2
 # Amount of staking accounts to add during "add staking accounts" test
 STAKING_ACCOUNTS_ADD_N = 3
+# Amount of applications to create in openingAndApplicationsStatus test
+APPLICATION_STATUS_CREATE_N = 6
+# Amount of applications to withdraw in openingAndApplicationsStatus test
+APPLICATION_STATUS_WITHDRAW_N = 3
+# Amount of workers to test in workerActions flow
+WORKER_ACTIONS_WORKERS_N = 6
+# Amount of workers to terminate in workerActions flow
+WORKER_ACTIONS_TERMINATE_N = 3
+
+
+
 # ID of the membership paid terms used in membership creation test.
 MEMBERSHIP_PAID_TERMS = 0
 # Council stake amount for first K accounts in council election test.

+ 21 - 1
tests/integration-tests/codegen.yml

@@ -2,11 +2,31 @@ overwrite: true
 
 schema: '../../query-node/generated/graphql-server/generated/schema.graphql'
 
+documents:
+  - './src/graphql/queries/*.graphql'
+
+config:
+  scalars:
+    Date: Date
+  preResolveTypes: true # avoid using Pick
+  skipTypename: true # skip __typename field in typings unless it's part of the query
+
 generates:
-  src/QueryNodeApiSchema.generated.ts:
+  src/graphql/generated/schema.ts:
     hooks:
       afterOneFileWrite:
         - prettier --write
         - eslint --fix
     plugins:
       - typescript
+  src/graphql/generated/queries.ts:
+    preset: import-types
+    presetConfig:
+      typesPath: ./schema
+    hooks:
+      afterOneFileWrite:
+        - prettier --write
+        - eslint --fix
+    plugins:
+      - typescript-operations
+      - typescript-document-nodes

+ 6 - 3
tests/integration-tests/package.json

@@ -10,7 +10,7 @@
     "lint": "eslint . --quiet --ext .ts",
     "checks": "tsc --noEmit --pretty && prettier ./ --check && yarn lint",
     "format": "prettier ./ --write",
-    "generate:query-node-types": "graphql-codegen"
+    "generate:graphql-types": "graphql-codegen"
   },
   "dependencies": {
     "@apollo/client": "^3.2.5",
@@ -35,8 +35,11 @@
     "prettier": "2.0.2",
     "ts-node": "^8.8.1",
     "typescript": "^3.8.3",
-    "@graphql-codegen/cli": "^1.21.3",
-    "@graphql-codegen/typescript": "^1.21.1"
+    "@graphql-codegen/cli": "^1.21.4",
+    "@graphql-codegen/typescript": "^1.22.0",
+    "@graphql-codegen/import-types-preset": "^1.18.1",
+    "@graphql-codegen/typescript-operations": "^1.17.16",
+    "@graphql-codegen/typescript-document-nodes": "^1.17.11"
   },
   "volta": {
     "extends": "../../package.json"

+ 1 - 1
tests/integration-tests/run-test-scenario.sh

@@ -7,7 +7,7 @@ cd $SCRIPT_PATH
 # pass the scenario name without .ts extension
 SCENARIO=$1
 # fallback if scenario if not specified
-SCENARIO=${SCENARIO:=olympia}
+SCENARIO=${SCENARIO:=full}
 
 # Execute the tests
 time DEBUG=* yarn workspace integration-tests node-ts-strict src/scenarios/${SCENARIO}.ts

+ 207 - 13
tests/integration-tests/src/Api.ts

@@ -1,10 +1,10 @@
 import { ApiPromise, WsProvider, Keyring } from '@polkadot/api'
-import { u32 } from '@polkadot/types'
+import { u32, BTreeMap } from '@polkadot/types'
 import { ISubmittableResult } from '@polkadot/types/types'
 import { KeyringPair } from '@polkadot/keyring/types'
 import { AccountId, MemberId } from '@joystream/types/common'
 
-import { AccountInfo, Balance, EventRecord } from '@polkadot/types/interfaces'
+import { AccountInfo, Balance, EventRecord, BlockNumber, BlockHash } from '@polkadot/types/interfaces'
 import BN from 'bn.js'
 import { QueryableConsts, QueryableStorage, SubmittableExtrinsic, SubmittableExtrinsics } from '@polkadot/api/types'
 import { Sender, LogLevel } from './sender'
@@ -14,6 +14,27 @@ import { types } from '@joystream/types'
 import { v4 as uuid } from 'uuid'
 import Debugger from 'debug'
 import { DispatchError } from '@polkadot/types/interfaces/system'
+import {
+  EventDetails,
+  MemberInvitedEventDetails,
+  MembershipBoughtEventDetails,
+  MembershipEventName,
+  OpeningAddedEventDetails,
+  WorkingGroupsEventName,
+  WorkingGroupModuleName,
+  AppliedOnOpeningEventDetails,
+  OpeningFilledEventDetails,
+} from './types'
+import {
+  ApplicationId,
+  Opening,
+  OpeningId,
+  WorkerId,
+  ApplyOnOpeningParameters,
+  Worker,
+} from '@joystream/types/working-group'
+import { DeriveAllSections } from '@polkadot/api/util/decorate'
+import { ExactDerive } from '@polkadot/api-derive'
 
 export enum WorkingGroups {
   StorageWorkingGroup = 'storageWorkingGroup',
@@ -100,7 +121,7 @@ export class Api {
     return this.api.consts
   }
 
-  public get derive() {
+  public get derive(): DeriveAllSections<'promise', ExactDerive> {
     return this.api.derive
   }
 
@@ -111,6 +132,26 @@ export class Api {
     return this.sender.signAndSend(tx, sender)
   }
 
+  public async sendExtrinsicsAndGetResults(
+    txs: SubmittableExtrinsic<'promise'>[],
+    sender: AccountId | string | AccountId[] | string[],
+    preserveOrder = false
+  ): Promise<ISubmittableResult[]> {
+    let results: ISubmittableResult[] = []
+    if (preserveOrder) {
+      for (const i in txs) {
+        const tx = txs[i]
+        const result = await this.sender.signAndSend(tx, Array.isArray(sender) ? sender[i] : sender)
+        results.push(result)
+      }
+    } else {
+      results = await Promise.all(
+        txs.map((tx, i) => this.sender.signAndSend(tx, Array.isArray(sender) ? sender[i] : sender))
+      )
+    }
+    return results
+  }
+
   public async makeSudoCall(tx: SubmittableExtrinsic<'promise'>): Promise<ISubmittableResult> {
     const sudo = await this.api.query.sudo.key()
     return this.signAndSend(this.api.tx.sudo.sudo(tx), sudo)
@@ -125,13 +166,18 @@ export class Api {
   }
 
   // Create new keys and store them in the shared keyring
-  public createKeyPairs(n: number): KeyringPair[] {
+  public async createKeyPairs(n: number, withExistentialDeposit = true): Promise<KeyringPair[]> {
     const nKeyPairs: KeyringPair[] = []
     for (let i = 0; i < n; i++) {
       // What are risks of generating duplicate keys this way?
       // Why not use a deterministic /TestKeys/N and increment N
       nKeyPairs.push(this.keyring.addFromUri(i + uuid().substring(0, 8)))
     }
+    if (withExistentialDeposit) {
+      await Promise.all(
+        nKeyPairs.map(({ address }) => this.treasuryTransferBalance(address, this.existentialDeposit()))
+      )
+    }
     return nKeyPairs
   }
 
@@ -167,6 +213,10 @@ export class Api {
     return this.api.derive.chain.bestNumber()
   }
 
+  public async getBlockHash(blockNumber: number | BlockNumber): Promise<BlockHash> {
+    return this.api.rpc.chain.getBlockHash(blockNumber)
+  }
+
   public async getControllerAccountOfMember(id: MemberId): Promise<string> {
     return (await this.api.query.members.membershipById(id)).controller_account.toString()
   }
@@ -176,6 +226,15 @@ export class Api {
     return accountData.data.free
   }
 
+  public async getStakedBalance(address: string | AccountId, lockId?: string): Promise<BN> {
+    const locks = await this.api.query.balances.locks(address)
+    if (lockId) {
+      const foundLock = locks.find((l) => l.id.eq(lockId))
+      return foundLock ? foundLock.amount : new BN(0)
+    }
+    return locks.reduce((sum, lock) => sum.add(lock.amount), new BN(0))
+  }
+
   public async transferBalance({
     from,
     to,
@@ -198,31 +257,142 @@ export class Api {
     )
   }
 
+  public async prepareAccountsForFeeExpenses(
+    accountOrAccounts: string | string[],
+    extrinsics: SubmittableExtrinsic<'promise'>[]
+  ): Promise<void> {
+    const fees = await Promise.all(
+      extrinsics.map((tx, i) =>
+        this.estimateTxFee(tx, Array.isArray(accountOrAccounts) ? accountOrAccounts[i] : accountOrAccounts)
+      )
+    )
+
+    if (Array.isArray(accountOrAccounts)) {
+      await Promise.all(fees.map((fee, i) => this.treasuryTransferBalance(accountOrAccounts[i], fee)))
+    } else {
+      await this.treasuryTransferBalance(
+        accountOrAccounts,
+        fees.reduce((a, b) => a.add(b), new BN(0))
+      )
+    }
+  }
+
   public async getMembershipFee(): Promise<BN> {
     return this.api.query.members.membershipPrice()
   }
 
   // This method does not take into account weights and the runtime weight to fees computation!
-  public async estimateTxFee(tx: SubmittableExtrinsic<'promise'>, account: string): Promise<BN> {
+  public async estimateTxFee(tx: SubmittableExtrinsic<'promise'>, account: string): Promise<Balance> {
     const paymentInfo = await tx.paymentInfo(account)
     return paymentInfo.partialFee
   }
 
+  public existentialDeposit(): Balance {
+    return this.api.consts.balances.existentialDeposit
+  }
+
+  // TODO: Augmentations comming with new @polkadot/typegen!
+
   public findEventRecord(events: EventRecord[], section: string, method: string): EventRecord | undefined {
     return events.find((record) => record.event.section === section && record.event.method === method)
   }
 
-  public findMemberBoughtEvent(events: EventRecord[]): MemberId | undefined {
-    const record = this.findEventRecord(events, 'members', 'MembershipBought')
-    if (record) {
-      return record.event.data[0] as MemberId
+  public async retrieveEventDetails(
+    result: ISubmittableResult,
+    section: string,
+    method: string
+  ): Promise<EventDetails | undefined> {
+    const { status, events } = result
+    const record = this.findEventRecord(events, section, method)
+    if (!record) {
+      return
+    }
+
+    const blockHash = status.asInBlock.toString()
+    const blockNumber = (await this.api.rpc.chain.getHeader(blockHash)).number.toNumber()
+    const blockTimestamp = (await this.api.query.timestamp.now.at(blockHash)).toNumber()
+    const blockEvents = await this.api.query.system.events.at(blockHash)
+    const indexInBlock = blockEvents.findIndex(({ event: blockEvent }) => blockEvent.hash.eq(record.event.hash))
+
+    return {
+      event: record.event,
+      blockNumber,
+      blockHash,
+      blockTimestamp,
+      indexInBlock,
+    }
+  }
+
+  public async retrieveMembershipEventDetails(
+    result: ISubmittableResult,
+    eventName: MembershipEventName
+  ): Promise<EventDetails> {
+    const details = await this.retrieveEventDetails(result, 'members', eventName)
+    if (!details) {
+      throw new Error(`${eventName} event details not found in result: ${JSON.stringify(result.toHuman())}`)
     }
+    return details
   }
 
-  public findMemberInvitedEvent(events: EventRecord[]): MemberId | undefined {
-    const record = this.findEventRecord(events, 'members', 'MemberInvited')
-    if (record) {
-      return record.event.data[0] as MemberId
+  public async retrieveWorkingGroupsEventDetails(
+    result: ISubmittableResult,
+    moduleName: WorkingGroupModuleName,
+    eventName: WorkingGroupsEventName
+  ): Promise<EventDetails> {
+    const details = await this.retrieveEventDetails(result, moduleName, eventName)
+    if (!details) {
+      throw new Error(`${eventName} event details not found in result: ${JSON.stringify(result.toHuman())}`)
+    }
+    return details
+  }
+
+  public async retrieveMembershipBoughtEventDetails(result: ISubmittableResult): Promise<MembershipBoughtEventDetails> {
+    const details = await this.retrieveMembershipEventDetails(result, 'MembershipBought')
+    return {
+      ...details,
+      memberId: details.event.data[0] as MemberId,
+    }
+  }
+
+  public async retrieveMemberInvitedEventDetails(result: ISubmittableResult): Promise<MemberInvitedEventDetails> {
+    const details = await this.retrieveMembershipEventDetails(result, 'MemberInvited')
+    return {
+      ...details,
+      newMemberId: details.event.data[0] as MemberId,
+    }
+  }
+
+  public async retrieveOpeningAddedEventDetails(
+    result: ISubmittableResult,
+    moduleName: WorkingGroupModuleName
+  ): Promise<OpeningAddedEventDetails> {
+    const details = await this.retrieveWorkingGroupsEventDetails(result, moduleName, 'OpeningAdded')
+    return {
+      ...details,
+      openingId: details.event.data[0] as OpeningId,
+    }
+  }
+
+  public async retrieveAppliedOnOpeningEventDetails(
+    result: ISubmittableResult,
+    moduleName: WorkingGroupModuleName
+  ): Promise<AppliedOnOpeningEventDetails> {
+    const details = await this.retrieveWorkingGroupsEventDetails(result, moduleName, 'AppliedOnOpening')
+    return {
+      ...details,
+      params: details.event.data[0] as ApplyOnOpeningParameters,
+      applicationId: details.event.data[1] as ApplicationId,
+    }
+  }
+
+  public async retrieveOpeningFilledEventDetails(
+    result: ISubmittableResult,
+    moduleName: WorkingGroupModuleName
+  ): Promise<OpeningFilledEventDetails> {
+    const details = await this.retrieveWorkingGroupsEventDetails(result, moduleName, 'OpeningFilled')
+    return {
+      ...details,
+      applicationIdToWorkerIdMap: details.event.data[1] as BTreeMap<ApplicationId, WorkerId>,
     }
   }
 
@@ -245,4 +415,28 @@ export class Api {
       }
     }
   }
+
+  public async getOpening(group: WorkingGroupModuleName, id: OpeningId): Promise<Opening> {
+    const opening = await this.api.query[group].openingById(id)
+    if (opening.isEmpty) {
+      throw new Error(`Opening by id ${id} not found!`)
+    }
+    return opening
+  }
+
+  public async getLeader(group: WorkingGroupModuleName): Promise<Worker> {
+    const leadId = await this.api.query[group].currentLead()
+    if (leadId.isNone) {
+      throw new Error('Cannot get lead role key: Lead not yet hired!')
+    }
+    return await this.api.query[group].workerById(leadId.unwrap())
+  }
+
+  public async getLeadRoleKey(group: WorkingGroupModuleName): Promise<string> {
+    return (await this.getLeader(group)).role_account_id.toString()
+  }
+
+  public async getLeaderStakingKey(group: WorkingGroupModuleName): Promise<string> {
+    return (await this.getLeader(group)).staking_account_id.toString()
+  }
 }

+ 88 - 2
tests/integration-tests/src/Fixture.ts

@@ -2,6 +2,10 @@ import { Api } from './Api'
 import { assert } from 'chai'
 import { ISubmittableResult } from '@polkadot/types/types/'
 import { DispatchResult } from '@polkadot/types/interfaces/system'
+import { QueryNodeApi } from './QueryNodeApi'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import Debugger from 'debug'
+import { AnyQueryNodeEvent, EventDetails } from './types'
 
 export abstract class BaseFixture {
   protected readonly api: Api
@@ -15,8 +19,8 @@ export abstract class BaseFixture {
 
   // Derviced classes must not override this
   public async runner(): Promise<void> {
+    await this.execute()
     this._executed = true
-    return this.execute()
   }
 
   abstract execute(): Promise<void>
@@ -31,7 +35,7 @@ export abstract class BaseFixture {
   }
 
   public didFail(): boolean {
-    if (!this.execute) {
+    if (!this.executed) {
       throw new Error('Trying to check execution result before running fixture')
     }
     return this._err !== undefined
@@ -83,11 +87,75 @@ export abstract class BaseFixture {
   }
 }
 
+export abstract class BaseQueryNodeFixture extends BaseFixture {
+  protected readonly query: QueryNodeApi
+  protected debug: Debugger.Debugger
+
+  constructor(api: Api, query: QueryNodeApi) {
+    super(api)
+    this.query = query
+    this.debug = Debugger(`fixture:${this.constructor.name}`)
+  }
+
+  public async runQueryNodeChecks(): Promise<void> {
+    if (!this.executed) {
+      throw new Error('Cannot run query node checks before Fixture is executed')
+    }
+    // Implement in child class!
+  }
+
+  protected findMatchingQueryNodeEvent<T extends AnyQueryNodeEvent>(
+    eventToFind: EventDetails,
+    queryNodeEvents: T[]
+  ): T {
+    const { blockNumber, indexInBlock } = eventToFind
+    const qEvent = queryNodeEvents.find((e) => e.inBlock === blockNumber && e.indexInBlock === indexInBlock)
+    if (!qEvent) {
+      throw new Error(`Could not find matching query-node event (expected ${blockNumber}:${indexInBlock})!`)
+    }
+    return qEvent
+  }
+}
+
+export abstract class StandardizedFixture extends BaseQueryNodeFixture {
+  protected extrinsics: SubmittableExtrinsic<'promise'>[] = []
+  protected results: ISubmittableResult[] = []
+  protected events: EventDetails[] = []
+  protected areExtrinsicsOrderSensitive = false
+
+  protected abstract getSignerAccountOrAccounts(): Promise<string | string[]>
+  protected abstract getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]>
+  protected abstract getEventFromResult(result: ISubmittableResult): Promise<EventDetails>
+  protected abstract assertQueryNodeEventIsValid(qEvent: AnyQueryNodeEvent, i: number): void
+
+  protected assertQueryNodeEventsAreValid(qEvents: AnyQueryNodeEvent[]): void {
+    this.events.forEach((e, i) => {
+      const qEvent = this.findMatchingQueryNodeEvent(e, qEvents)
+      assert.equal(qEvent.inExtrinsic, this.extrinsics[i].hash.toString())
+      assert.equal(new Date(qEvent.createdAt).getTime(), e.blockTimestamp)
+      this.assertQueryNodeEventIsValid(qEvent, i)
+    })
+  }
+
+  public async execute(): Promise<void> {
+    const accountOrAccounts = await this.getSignerAccountOrAccounts()
+    this.extrinsics = await this.getExtrinsics()
+    await this.api.prepareAccountsForFeeExpenses(accountOrAccounts, this.extrinsics)
+    this.results = await this.api.sendExtrinsicsAndGetResults(
+      this.extrinsics,
+      accountOrAccounts,
+      this.areExtrinsicsOrderSensitive
+    )
+    this.events = await Promise.all(this.results.map((r) => this.getEventFromResult(r)))
+  }
+}
+
 // Runs a fixture and measures how long it took to run
 // Ensures fixture only runs once, and asserts that it doesn't fail
 export class FixtureRunner {
   private fixture: BaseFixture
   private ran = false
+  private queryNodeChecksRan = false
 
   constructor(fixture: BaseFixture) {
     this.fixture = fixture
@@ -107,4 +175,22 @@ export class FixtureRunner {
     const err = this.fixture.executionError()
     assert.equal(err, undefined)
   }
+
+  public async runQueryNodeChecks(): Promise<void> {
+    if (!(this.fixture instanceof BaseQueryNodeFixture)) {
+      throw new Error('Tried to run query node checks for non-query-node fixture!')
+    }
+    if (this.queryNodeChecksRan) {
+      throw new Error('Fixture query node checks already ran')
+    }
+
+    this.queryNodeChecksRan = true
+
+    await this.fixture.runQueryNodeChecks()
+  }
+
+  public async runWithQueryNodeChecks(): Promise<void> {
+    await this.run()
+    await this.runQueryNodeChecks()
+  }
 }

+ 634 - 43
tests/integration-tests/src/QueryNodeApi.ts

@@ -1,31 +1,211 @@
-import { gql, ApolloClient, ApolloQueryResult, NormalizedCacheObject } from '@apollo/client'
+import { ApolloClient, DocumentNode, NormalizedCacheObject } from '@apollo/client'
 import { MemberId } from '@joystream/types/common'
-import { Query } from './QueryNodeApiSchema.generated'
 import Debugger from 'debug'
-
+import { ApplicationId, OpeningId, WorkerId } from '@joystream/types/working-group'
+import { EventDetails, WorkingGroupModuleName } from './types'
+import {
+  GetMemberByIdQuery,
+  GetMemberByIdQueryVariables,
+  GetMemberById,
+  GetMemberProfileUpdatedEventsByMemberIdQuery,
+  GetMemberProfileUpdatedEventsByMemberIdQueryVariables,
+  GetMemberProfileUpdatedEventsByMemberId,
+  GetMemberAccountsUpdatedEventsByMemberIdQuery,
+  GetMemberAccountsUpdatedEventsByMemberIdQueryVariables,
+  GetMemberAccountsUpdatedEventsByMemberId,
+  GetInvitesTransferredEventsBySourceMemberIdQuery,
+  GetInvitesTransferredEventsBySourceMemberIdQueryVariables,
+  GetInvitesTransferredEventsBySourceMemberId,
+  GetStakingAccountAddedEventsByMemberIdQuery,
+  GetStakingAccountAddedEventsByMemberIdQueryVariables,
+  GetStakingAccountAddedEventsByMemberId,
+  GetStakingAccountConfirmedEventsByMemberIdQuery,
+  GetStakingAccountConfirmedEventsByMemberIdQueryVariables,
+  GetStakingAccountConfirmedEventsByMemberId,
+  GetStakingAccountRemovedEventsByMemberIdQuery,
+  GetStakingAccountRemovedEventsByMemberIdQueryVariables,
+  GetStakingAccountRemovedEventsByMemberId,
+  GetMembershipSystemSnapshotAtQuery,
+  GetMembershipSystemSnapshotAtQueryVariables,
+  GetMembershipSystemSnapshotAt,
+  GetMembershipSystemSnapshotBeforeQuery,
+  GetMembershipSystemSnapshotBeforeQueryVariables,
+  GetMembershipSystemSnapshotBefore,
+  GetReferralCutUpdatedEventsByEventIdQuery,
+  GetReferralCutUpdatedEventsByEventIdQueryVariables,
+  GetReferralCutUpdatedEventsByEventId,
+  GetMembershipPriceUpdatedEventsByEventIdQuery,
+  GetMembershipPriceUpdatedEventsByEventIdQueryVariables,
+  GetMembershipPriceUpdatedEventsByEventId,
+  GetInitialInvitationBalanceUpdatedEventsByEventIdQuery,
+  GetInitialInvitationBalanceUpdatedEventsByEventIdQueryVariables,
+  GetInitialInvitationBalanceUpdatedEventsByEventId,
+  GetInitialInvitationCountUpdatedEventsByEventIdQuery,
+  GetInitialInvitationCountUpdatedEventsByEventIdQueryVariables,
+  GetInitialInvitationCountUpdatedEventsByEventId,
+  GetOpeningByIdQuery,
+  GetOpeningByIdQueryVariables,
+  GetOpeningById,
+  GetApplicationByIdQuery,
+  GetApplicationByIdQueryVariables,
+  GetApplicationById,
+  GetAppliedOnOpeningEventsByEventIdsQuery,
+  GetAppliedOnOpeningEventsByEventIdsQueryVariables,
+  GetAppliedOnOpeningEventsByEventIds,
+  GetOpeningAddedEventsByEventIdsQuery,
+  GetOpeningAddedEventsByEventIdsQueryVariables,
+  GetOpeningAddedEventsByEventIds,
+  GetOpeningFilledEventsByEventIdsQuery,
+  GetOpeningFilledEventsByEventIdsQueryVariables,
+  GetOpeningFilledEventsByEventIds,
+  GetApplicationWithdrawnEventsByEventIdsQuery,
+  GetApplicationWithdrawnEventsByEventIdsQueryVariables,
+  GetApplicationWithdrawnEventsByEventIds,
+  GetOpeningCancelledEventsByEventIdsQuery,
+  GetOpeningCancelledEventsByEventIdsQueryVariables,
+  GetOpeningCancelledEventsByEventIds,
+  GetStatusTextChangedEventsByEventIdsQuery,
+  GetStatusTextChangedEventsByEventIdsQueryVariables,
+  GetStatusTextChangedEventsByEventIds,
+  GetUpcomingOpeningsByCreatedInEventIdsQuery,
+  GetUpcomingOpeningsByCreatedInEventIdsQueryVariables,
+  GetUpcomingOpeningsByCreatedInEventIds,
+  GetWorkingGroupByNameQuery,
+  GetWorkingGroupByNameQueryVariables,
+  GetWorkingGroupByName,
+  GetWorkingGroupMetadataSnapshotsByTimeAsc,
+  GetWorkingGroupMetadataSnapshotsByTimeAscQuery,
+  GetWorkingGroupMetadataSnapshotsByTimeAscQueryVariables,
+  MembershipFieldsFragment,
+  MembershipBoughtEventFieldsFragment,
+  MemberProfileUpdatedEventFieldsFragment,
+  MemberAccountsUpdatedEventFieldsFragment,
+  MemberInvitedEventFieldsFragment,
+  InvitesTransferredEventFieldsFragment,
+  StakingAccountAddedEventFieldsFragment,
+  StakingAccountConfirmedEventFieldsFragment,
+  StakingAccountRemovedEventFieldsFragment,
+  MembershipSystemSnapshotFieldsFragment,
+  ReferralCutUpdatedEventFieldsFragment,
+  MembershipPriceUpdatedEventFieldsFragment,
+  InitialInvitationBalanceUpdatedEventFieldsFragment,
+  InitialInvitationCountUpdatedEventFieldsFragment,
+  OpeningFieldsFragment,
+  ApplicationFieldsFragment,
+  AppliedOnOpeningEventFieldsFragment,
+  OpeningAddedEventFieldsFragment,
+  OpeningFilledEventFieldsFragment,
+  ApplicationWithdrawnEventFieldsFragment,
+  OpeningCanceledEventFieldsFragment,
+  StatusTextChangedEventFieldsFragment,
+  UpcomingOpeningFieldsFragment,
+  WorkingGroupFieldsFragment,
+  WorkingGroupMetadataFieldsFragment,
+  GetUpcomingOpeningByIdQuery,
+  GetUpcomingOpeningByIdQueryVariables,
+  GetUpcomingOpeningById,
+  GetOpeningsByIdsQuery,
+  GetOpeningsByIdsQueryVariables,
+  GetOpeningsByIds,
+  GetApplicationsByIdsQuery,
+  GetApplicationsByIdsQueryVariables,
+  GetApplicationsByIds,
+  GetWorkerRoleAccountUpdatedEventsByEventIdsQuery,
+  GetWorkerRoleAccountUpdatedEventsByEventIdsQueryVariables,
+  WorkerRoleAccountUpdatedEventFieldsFragment,
+  GetWorkerRoleAccountUpdatedEventsByEventIds,
+  GetWorkerRewardAccountUpdatedEventsByEventIdsQuery,
+  GetWorkerRewardAccountUpdatedEventsByEventIdsQueryVariables,
+  WorkerRewardAccountUpdatedEventFieldsFragment,
+  GetWorkerRewardAccountUpdatedEventsByEventIds,
+  StakeIncreasedEventFieldsFragment,
+  GetStakeIncreasedEventsByEventIdsQuery,
+  GetStakeIncreasedEventsByEventIdsQueryVariables,
+  GetStakeIncreasedEventsByEventIds,
+  WorkerFieldsFragment,
+  GetWorkersByRuntimeIdsQuery,
+  GetWorkersByRuntimeIdsQueryVariables,
+  GetWorkersByRuntimeIds,
+  GetWorkerStartedLeavingEventsByEventIdsQuery,
+  GetWorkerStartedLeavingEventsByEventIdsQueryVariables,
+  GetWorkerStartedLeavingEventsByEventIds,
+  WorkerStartedLeavingEventFieldsFragment,
+  TerminatedWorkerEventFieldsFragment,
+  GetTerminatedWorkerEventsByEventIdsQuery,
+  GetTerminatedWorkerEventsByEventIdsQueryVariables,
+  GetTerminatedWorkerEventsByEventIds,
+  TerminatedLeaderEventFieldsFragment,
+  GetTerminatedLeaderEventsByEventIdsQuery,
+  GetTerminatedLeaderEventsByEventIdsQueryVariables,
+  GetTerminatedLeaderEventsByEventIds,
+  WorkerRewardAmountUpdatedEventFieldsFragment,
+  GetWorkerRewardAmountUpdatedEventsByEventIdsQuery,
+  GetWorkerRewardAmountUpdatedEventsByEventIdsQueryVariables,
+  GetWorkerRewardAmountUpdatedEventsByEventIds,
+  StakeSlashedEventFieldsFragment,
+  GetStakeSlashedEventsByEventIdsQuery,
+  GetStakeSlashedEventsByEventIdsQueryVariables,
+  GetStakeSlashedEventsByEventIds,
+  StakeDecreasedEventFieldsFragment,
+  GetStakeDecreasedEventsByEventIdsQuery,
+  GetStakeDecreasedEventsByEventIdsQueryVariables,
+  GetStakeDecreasedEventsByEventIds,
+  BudgetSetEventFieldsFragment,
+  GetBudgetSetEventsByEventIdsQuery,
+  GetBudgetSetEventsByEventIdsQueryVariables,
+  GetBudgetSetEventsByEventIds,
+  BudgetSpendingEventFieldsFragment,
+  GetBudgetSpendingEventsByEventIdsQuery,
+  GetBudgetSpendingEventsByEventIdsQueryVariables,
+  GetBudgetSpendingEventsByEventIds,
+  LeaderUnsetEventFieldsFragment,
+  GetLeaderUnsetEventsByEventIdsQuery,
+  GetLeaderUnsetEventsByEventIdsQueryVariables,
+  GetLeaderUnsetEventsByEventIds,
+  LeaderSetEventFieldsFragment,
+  GetLeaderSetEventsByEventIdsQuery,
+  GetLeaderSetEventsByEventIdsQueryVariables,
+  GetLeaderSetEventsByEventIds,
+  GetMembershipBoughtEventsByEventIdsQuery,
+  GetMembershipBoughtEventsByEventIdsQueryVariables,
+  GetMembershipBoughtEventsByEventIds,
+  GetMembersByIdsQuery,
+  GetMembersByIdsQueryVariables,
+  GetMembersByIds,
+  GetMemberInvitedEventsByEventIdsQuery,
+  GetMemberInvitedEventsByEventIdsQueryVariables,
+  GetMemberInvitedEventsByEventIds,
+} from './graphql/generated/queries'
+import { Maybe } from './graphql/generated/schema'
+import { OperationDefinitionNode } from 'graphql'
 export class QueryNodeApi {
   private readonly queryNodeProvider: ApolloClient<NormalizedCacheObject>
+  private readonly debug: Debugger.Debugger
   private readonly queryDebug: Debugger.Debugger
+  private readonly tryDebug: Debugger.Debugger
 
   constructor(queryNodeProvider: ApolloClient<NormalizedCacheObject>) {
     this.queryNodeProvider = queryNodeProvider
-    this.queryDebug = Debugger('query-node-api:query')
+    this.debug = Debugger('query-node-api')
+    this.queryDebug = this.debug.extend('query')
+    this.tryDebug = this.debug.extend('try')
   }
 
-  public tryQueryWithTimeout<QueryResultT extends ApolloQueryResult<unknown>>(
+  public tryQueryWithTimeout<QueryResultT>(
     query: () => Promise<QueryResultT>,
     assertResultIsValid: (res: QueryResultT) => void,
-    timeoutMs = 120000,
-    retryTimeMs = 5000
+    timeoutMs = 60000,
+    retryTimeMs = 15000
   ): Promise<QueryResultT> {
-    const retryDebug = Debugger('query-node-api:retry')
+    const label = query.toString().replace(/^.*\.([A-za-z0-9]+\(.*\))$/g, '$1')
+    const retryDebug = this.tryDebug.extend(label).extend('retry')
+    const failDebug = this.tryDebug.extend(label).extend('failed')
     return new Promise((resolve, reject) => {
       let lastError: any
       const timeout = setTimeout(() => {
-        console.error(`Query node query is still failing after timeout was reached (${timeoutMs}ms)!`)
+        failDebug(`Query node query is still failing after timeout was reached (${timeoutMs}ms)!`)
         reject(lastError)
       }, timeoutMs)
-
       const tryQuery = () => {
         query()
           .then((result) => {
@@ -34,7 +214,11 @@ export class QueryNodeApi {
               clearTimeout(timeout)
               resolve(result)
             } catch (e) {
-              retryDebug(`Unexpected query result, retyring query in ${retryTimeMs}ms...`)
+              retryDebug(
+                `Unexpected query result${
+                  e && e.message ? ` (${e.message})` : ''
+                }, retyring query in ${retryTimeMs}ms...`
+              )
               lastError = e
               setTimeout(tryQuery, retryTimeMs)
             }
@@ -50,39 +234,446 @@ export class QueryNodeApi {
     })
   }
 
-  public async getMemberById(id: MemberId): Promise<ApolloQueryResult<Pick<Query, 'membership'>>> {
-    const MEMBER_BY_ID_QUERY = gql`
-      query($id: ID!) {
-        membership(where: { id: $id }) {
-          id
-          handle
-          name
-          avatarUri
-          about
-          controllerAccount
-          rootAccount
-          registeredAtBlock {
-            block
-            executedAt
-            network
-          }
-          registeredAtTime
-          entry
-          isVerified
-          inviteCount
-          invitedBy {
-            id
-          }
-          invitees {
-            id
-          }
-          boundAccounts
-        }
-      }
-    `
+  private debugQuery(query: DocumentNode, args: Record<string, unknown>): void {
+    const queryDef = query.definitions.find((d) => d.kind === 'OperationDefinition') as OperationDefinitionNode
+    this.queryDebug(`${queryDef.name!.value}(${JSON.stringify(args)})`)
+  }
 
-    this.queryDebug(`Executing getMemberById(${id.toString()}) query`)
+  // Query entity by unique input
+  private async uniqueEntityQuery<
+    QueryT extends { [k: string]: Maybe<Record<string, unknown>> | undefined },
+    VariablesT extends Record<string, unknown>
+  >(
+    query: DocumentNode,
+    variables: VariablesT,
+    resultKey: keyof QueryT
+  ): Promise<Required<QueryT>[keyof QueryT] | null> {
+    this.debugQuery(query, variables)
+    return (await this.queryNodeProvider.query<QueryT, VariablesT>({ query, variables })).data[resultKey] || null
+  }
+
+  // Query entities by "non-unique" input and return first result
+  private async firstEntityQuery<QueryT extends { [k: string]: unknown[] }, VariablesT extends Record<string, unknown>>(
+    query: DocumentNode,
+    variables: VariablesT,
+    resultKey: keyof QueryT
+  ): Promise<QueryT[keyof QueryT][number] | null> {
+    this.debugQuery(query, variables)
+    return (await this.queryNodeProvider.query<QueryT, VariablesT>({ query, variables })).data[resultKey][0] || null
+  }
+
+  // Query multiple entities
+  private async multipleEntitiesQuery<
+    QueryT extends { [k: string]: unknown[] },
+    VariablesT extends Record<string, unknown>
+  >(query: DocumentNode, variables: VariablesT, resultKey: keyof QueryT): Promise<QueryT[keyof QueryT]> {
+    this.debugQuery(query, variables)
+    return (await this.queryNodeProvider.query<QueryT, VariablesT>({ query, variables })).data[resultKey]
+  }
+
+  public getQueryNodeEventId(blockNumber: number, indexInBlock: number): string {
+    return `OLYMPIA-${blockNumber}-${indexInBlock}`
+  }
+
+  public async getMemberById(id: MemberId): Promise<MembershipFieldsFragment | null> {
+    return this.uniqueEntityQuery<GetMemberByIdQuery, GetMemberByIdQueryVariables>(
+      GetMemberById,
+      { id: id.toString() },
+      'membershipByUniqueInput'
+    )
+  }
+
+  public async getMembersByIds(ids: MemberId[]): Promise<MembershipFieldsFragment[]> {
+    return this.multipleEntitiesQuery<GetMembersByIdsQuery, GetMembersByIdsQueryVariables>(
+      GetMembersByIds,
+      { ids: ids.map((id) => id.toString()) },
+      'memberships'
+    )
+  }
+
+  public async getMembershipBoughtEvents(events: EventDetails[]): Promise<MembershipBoughtEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetMembershipBoughtEventsByEventIdsQuery,
+      GetMembershipBoughtEventsByEventIdsQueryVariables
+    >(GetMembershipBoughtEventsByEventIds, { eventIds }, 'membershipBoughtEvents')
+  }
+
+  public async getMemberProfileUpdatedEvents(memberId: MemberId): Promise<MemberProfileUpdatedEventFieldsFragment[]> {
+    return this.multipleEntitiesQuery<
+      GetMemberProfileUpdatedEventsByMemberIdQuery,
+      GetMemberProfileUpdatedEventsByMemberIdQueryVariables
+    >(GetMemberProfileUpdatedEventsByMemberId, { memberId: memberId.toString() }, 'memberProfileUpdatedEvents')
+  }
+
+  public async getMemberAccountsUpdatedEvents(memberId: MemberId): Promise<MemberAccountsUpdatedEventFieldsFragment[]> {
+    return this.multipleEntitiesQuery<
+      GetMemberAccountsUpdatedEventsByMemberIdQuery,
+      GetMemberAccountsUpdatedEventsByMemberIdQueryVariables
+    >(GetMemberAccountsUpdatedEventsByMemberId, { memberId: memberId.toString() }, 'memberAccountsUpdatedEvents')
+  }
+
+  public async getMemberInvitedEvents(events: EventDetails[]): Promise<MemberInvitedEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetMemberInvitedEventsByEventIdsQuery,
+      GetMemberInvitedEventsByEventIdsQueryVariables
+    >(GetMemberInvitedEventsByEventIds, { eventIds }, 'memberInvitedEvents')
+  }
+
+  // TODO: Use event id
+  public async getInvitesTransferredEvent(
+    sourceMemberId: MemberId
+  ): Promise<InvitesTransferredEventFieldsFragment | null> {
+    return this.firstEntityQuery<
+      GetInvitesTransferredEventsBySourceMemberIdQuery,
+      GetInvitesTransferredEventsBySourceMemberIdQueryVariables
+    >(
+      GetInvitesTransferredEventsBySourceMemberId,
+      { sourceMemberId: sourceMemberId.toString() },
+      'invitesTransferredEvents'
+    )
+  }
+
+  public async getStakingAccountAddedEvents(memberId: MemberId): Promise<StakingAccountAddedEventFieldsFragment[]> {
+    return this.multipleEntitiesQuery<
+      GetStakingAccountAddedEventsByMemberIdQuery,
+      GetStakingAccountAddedEventsByMemberIdQueryVariables
+    >(GetStakingAccountAddedEventsByMemberId, { memberId: memberId.toString() }, 'stakingAccountAddedEvents')
+  }
+
+  public async getStakingAccountConfirmedEvents(
+    memberId: MemberId
+  ): Promise<StakingAccountConfirmedEventFieldsFragment[]> {
+    return this.multipleEntitiesQuery<
+      GetStakingAccountConfirmedEventsByMemberIdQuery,
+      GetStakingAccountConfirmedEventsByMemberIdQueryVariables
+    >(GetStakingAccountConfirmedEventsByMemberId, { memberId: memberId.toString() }, 'stakingAccountConfirmedEvents')
+  }
+
+  public async getStakingAccountRemovedEvents(memberId: MemberId): Promise<StakingAccountRemovedEventFieldsFragment[]> {
+    return this.multipleEntitiesQuery<
+      GetStakingAccountRemovedEventsByMemberIdQuery,
+      GetStakingAccountRemovedEventsByMemberIdQueryVariables
+    >(GetStakingAccountRemovedEventsByMemberId, { memberId: memberId.toString() }, 'stakingAccountRemovedEvents')
+  }
+
+  // FIXME: Cross-filtering is not enabled yet, so we have to use timestamp workaround
+  public async getMembershipSystemSnapshotAt(
+    timestamp: number
+  ): Promise<MembershipSystemSnapshotFieldsFragment | null> {
+    return this.firstEntityQuery<GetMembershipSystemSnapshotAtQuery, GetMembershipSystemSnapshotAtQueryVariables>(
+      GetMembershipSystemSnapshotAt,
+      { time: new Date(timestamp) },
+      'membershipSystemSnapshots'
+    )
+  }
+
+  public async getMembershipSystemSnapshotBefore(
+    timestamp: number
+  ): Promise<MembershipSystemSnapshotFieldsFragment | null> {
+    return this.firstEntityQuery<
+      GetMembershipSystemSnapshotBeforeQuery,
+      GetMembershipSystemSnapshotBeforeQueryVariables
+    >(GetMembershipSystemSnapshotBefore, { time: new Date(timestamp) }, 'membershipSystemSnapshots')
+  }
+
+  public async getReferralCutUpdatedEvent(
+    blockNumber: number,
+    indexInBlock: number
+  ): Promise<ReferralCutUpdatedEventFieldsFragment | null> {
+    return this.firstEntityQuery<
+      GetReferralCutUpdatedEventsByEventIdQuery,
+      GetReferralCutUpdatedEventsByEventIdQueryVariables
+    >(
+      GetReferralCutUpdatedEventsByEventId,
+      { eventId: this.getQueryNodeEventId(blockNumber, indexInBlock) },
+      'referralCutUpdatedEvents'
+    )
+  }
+
+  public async getMembershipPriceUpdatedEvent(
+    blockNumber: number,
+    indexInBlock: number
+  ): Promise<MembershipPriceUpdatedEventFieldsFragment | null> {
+    return this.firstEntityQuery<
+      GetMembershipPriceUpdatedEventsByEventIdQuery,
+      GetMembershipPriceUpdatedEventsByEventIdQueryVariables
+    >(
+      GetMembershipPriceUpdatedEventsByEventId,
+      { eventId: this.getQueryNodeEventId(blockNumber, indexInBlock) },
+      'membershipPriceUpdatedEvents'
+    )
+  }
+
+  public async getInitialInvitationBalanceUpdatedEvent(
+    blockNumber: number,
+    indexInBlock: number
+  ): Promise<InitialInvitationBalanceUpdatedEventFieldsFragment | null> {
+    return this.firstEntityQuery<
+      GetInitialInvitationBalanceUpdatedEventsByEventIdQuery,
+      GetInitialInvitationBalanceUpdatedEventsByEventIdQueryVariables
+    >(
+      GetInitialInvitationBalanceUpdatedEventsByEventId,
+      { eventId: this.getQueryNodeEventId(blockNumber, indexInBlock) },
+      'initialInvitationBalanceUpdatedEvents'
+    )
+  }
+
+  public async getInitialInvitationCountUpdatedEvent(
+    blockNumber: number,
+    indexInBlock: number
+  ): Promise<InitialInvitationCountUpdatedEventFieldsFragment | null> {
+    return this.firstEntityQuery<
+      GetInitialInvitationCountUpdatedEventsByEventIdQuery,
+      GetInitialInvitationCountUpdatedEventsByEventIdQueryVariables
+    >(
+      GetInitialInvitationCountUpdatedEventsByEventId,
+      { eventId: this.getQueryNodeEventId(blockNumber, indexInBlock) },
+      'initialInvitationCountUpdatedEvents'
+    )
+  }
+
+  public async getOpeningById(id: OpeningId, group: WorkingGroupModuleName): Promise<OpeningFieldsFragment | null> {
+    return this.uniqueEntityQuery<GetOpeningByIdQuery, GetOpeningByIdQueryVariables>(
+      GetOpeningById,
+      { openingId: `${group}-${id.toString()}` },
+      'workingGroupOpeningByUniqueInput'
+    )
+  }
+
+  public async getOpeningsByIds(ids: OpeningId[], group: WorkingGroupModuleName): Promise<OpeningFieldsFragment[]> {
+    const openingIds = ids.map((id) => `${group}-${id.toString()}`)
+    return this.multipleEntitiesQuery<GetOpeningsByIdsQuery, GetOpeningsByIdsQueryVariables>(
+      GetOpeningsByIds,
+      { openingIds },
+      'workingGroupOpenings'
+    )
+  }
+
+  public async getApplicationById(
+    id: ApplicationId,
+    group: WorkingGroupModuleName
+  ): Promise<ApplicationFieldsFragment | null> {
+    return this.uniqueEntityQuery<GetApplicationByIdQuery, GetApplicationByIdQueryVariables>(
+      GetApplicationById,
+      { applicationId: `${group}-${id.toString()}` },
+      'workingGroupApplicationByUniqueInput'
+    )
+  }
+
+  public async getApplicationsByIds(
+    ids: ApplicationId[],
+    group: WorkingGroupModuleName
+  ): Promise<ApplicationFieldsFragment[]> {
+    const applicationIds = ids.map((id) => `${group}-${id.toString()}`)
+    return this.multipleEntitiesQuery<GetApplicationsByIdsQuery, GetApplicationsByIdsQueryVariables>(
+      GetApplicationsByIds,
+      { applicationIds },
+      'workingGroupApplications'
+    )
+  }
+
+  public async getAppliedOnOpeningEvents(events: EventDetails[]): Promise<AppliedOnOpeningEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetAppliedOnOpeningEventsByEventIdsQuery,
+      GetAppliedOnOpeningEventsByEventIdsQueryVariables
+    >(GetAppliedOnOpeningEventsByEventIds, { eventIds }, 'appliedOnOpeningEvents')
+  }
+
+  public async getOpeningAddedEvents(events: EventDetails[]): Promise<OpeningAddedEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetOpeningAddedEventsByEventIdsQuery,
+      GetOpeningAddedEventsByEventIdsQueryVariables
+    >(GetOpeningAddedEventsByEventIds, { eventIds }, 'openingAddedEvents')
+  }
+
+  public async getOpeningFilledEvents(events: EventDetails[]): Promise<OpeningFilledEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetOpeningFilledEventsByEventIdsQuery,
+      GetOpeningFilledEventsByEventIdsQueryVariables
+    >(GetOpeningFilledEventsByEventIds, { eventIds }, 'openingFilledEvents')
+  }
+
+  public async getApplicationWithdrawnEvents(
+    events: EventDetails[]
+  ): Promise<ApplicationWithdrawnEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetApplicationWithdrawnEventsByEventIdsQuery,
+      GetApplicationWithdrawnEventsByEventIdsQueryVariables
+    >(GetApplicationWithdrawnEventsByEventIds, { eventIds }, 'applicationWithdrawnEvents')
+  }
+
+  public async getOpeningCancelledEvents(events: EventDetails[]): Promise<OpeningCanceledEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetOpeningCancelledEventsByEventIdsQuery,
+      GetOpeningCancelledEventsByEventIdsQueryVariables
+    >(GetOpeningCancelledEventsByEventIds, { eventIds }, 'openingCanceledEvents')
+  }
+
+  public async getStatusTextChangedEvents(events: EventDetails[]): Promise<StatusTextChangedEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetStatusTextChangedEventsByEventIdsQuery,
+      GetStatusTextChangedEventsByEventIdsQueryVariables
+    >(GetStatusTextChangedEventsByEventIds, { eventIds }, 'statusTextChangedEvents')
+  }
+
+  public async getUpcomingOpeningById(id: string): Promise<UpcomingOpeningFieldsFragment | null> {
+    return this.uniqueEntityQuery<GetUpcomingOpeningByIdQuery, GetUpcomingOpeningByIdQueryVariables>(
+      GetUpcomingOpeningById,
+      { id },
+      'upcomingWorkingGroupOpeningByUniqueInput'
+    )
+  }
+
+  public async getUpcomingOpeningsByCreatedInEventIds(eventIds: string[]): Promise<UpcomingOpeningFieldsFragment[]> {
+    return this.multipleEntitiesQuery<
+      GetUpcomingOpeningsByCreatedInEventIdsQuery,
+      GetUpcomingOpeningsByCreatedInEventIdsQueryVariables
+    >(GetUpcomingOpeningsByCreatedInEventIds, { createdInEventIds: eventIds }, 'upcomingWorkingGroupOpenings')
+  }
+
+  public async getWorkingGroup(name: WorkingGroupModuleName): Promise<WorkingGroupFieldsFragment | null> {
+    return this.uniqueEntityQuery<GetWorkingGroupByNameQuery, GetWorkingGroupByNameQueryVariables>(
+      GetWorkingGroupByName,
+      { name },
+      'workingGroupByUniqueInput'
+    )
+  }
+
+  public async getGroupMetaSnapshotsByTimeAsc(groupId: string): Promise<WorkingGroupMetadataFieldsFragment[]> {
+    return this.multipleEntitiesQuery<
+      GetWorkingGroupMetadataSnapshotsByTimeAscQuery,
+      GetWorkingGroupMetadataSnapshotsByTimeAscQueryVariables
+    >(GetWorkingGroupMetadataSnapshotsByTimeAsc, { groupId }, 'workingGroupMetadata')
+  }
+
+  public async getWorkerRoleAccountUpdatedEvents(
+    events: EventDetails[]
+  ): Promise<WorkerRoleAccountUpdatedEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetWorkerRoleAccountUpdatedEventsByEventIdsQuery,
+      GetWorkerRoleAccountUpdatedEventsByEventIdsQueryVariables
+    >(GetWorkerRoleAccountUpdatedEventsByEventIds, { eventIds }, 'workerRoleAccountUpdatedEvents')
+  }
+
+  public async getWorkerRewardAccountUpdatedEvents(
+    events: EventDetails[]
+  ): Promise<WorkerRewardAccountUpdatedEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetWorkerRewardAccountUpdatedEventsByEventIdsQuery,
+      GetWorkerRewardAccountUpdatedEventsByEventIdsQueryVariables
+    >(GetWorkerRewardAccountUpdatedEventsByEventIds, { eventIds }, 'workerRewardAccountUpdatedEvents')
+  }
+
+  public async getStakeIncreasedEvents(events: EventDetails[]): Promise<StakeIncreasedEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetStakeIncreasedEventsByEventIdsQuery,
+      GetStakeIncreasedEventsByEventIdsQueryVariables
+    >(GetStakeIncreasedEventsByEventIds, { eventIds }, 'stakeIncreasedEvents')
+  }
+
+  public async getWorkersByIds(ids: WorkerId[], group: WorkingGroupModuleName): Promise<WorkerFieldsFragment[]> {
+    return this.multipleEntitiesQuery<GetWorkersByRuntimeIdsQuery, GetWorkersByRuntimeIdsQueryVariables>(
+      GetWorkersByRuntimeIds,
+      { workerIds: ids.map((id) => id.toNumber()), groupId: group },
+      'workers'
+    )
+  }
+
+  public async getWorkerStartedLeavingEvents(
+    events: EventDetails[]
+  ): Promise<WorkerStartedLeavingEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetWorkerStartedLeavingEventsByEventIdsQuery,
+      GetWorkerStartedLeavingEventsByEventIdsQueryVariables
+    >(GetWorkerStartedLeavingEventsByEventIds, { eventIds }, 'workerStartedLeavingEvents')
+  }
+
+  public async getTerminatedWorkerEvents(events: EventDetails[]): Promise<TerminatedWorkerEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetTerminatedWorkerEventsByEventIdsQuery,
+      GetTerminatedWorkerEventsByEventIdsQueryVariables
+    >(GetTerminatedWorkerEventsByEventIds, { eventIds }, 'terminatedWorkerEvents')
+  }
+
+  public async getTerminatedLeaderEvents(events: EventDetails[]): Promise<TerminatedLeaderEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetTerminatedLeaderEventsByEventIdsQuery,
+      GetTerminatedLeaderEventsByEventIdsQueryVariables
+    >(GetTerminatedLeaderEventsByEventIds, { eventIds }, 'terminatedLeaderEvents')
+  }
+
+  public async getWorkerRewardAmountUpdatedEvents(
+    events: EventDetails[]
+  ): Promise<WorkerRewardAmountUpdatedEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetWorkerRewardAmountUpdatedEventsByEventIdsQuery,
+      GetWorkerRewardAmountUpdatedEventsByEventIdsQueryVariables
+    >(GetWorkerRewardAmountUpdatedEventsByEventIds, { eventIds }, 'workerRewardAmountUpdatedEvents')
+  }
+
+  public async getStakeSlashedEvents(events: EventDetails[]): Promise<StakeSlashedEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetStakeSlashedEventsByEventIdsQuery,
+      GetStakeSlashedEventsByEventIdsQueryVariables
+    >(GetStakeSlashedEventsByEventIds, { eventIds }, 'stakeSlashedEvents')
+  }
+
+  public async getStakeDecreasedEvents(events: EventDetails[]): Promise<StakeDecreasedEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetStakeDecreasedEventsByEventIdsQuery,
+      GetStakeDecreasedEventsByEventIdsQueryVariables
+    >(GetStakeDecreasedEventsByEventIds, { eventIds }, 'stakeDecreasedEvents')
+  }
+
+  public async getBudgetSetEvents(events: EventDetails[]): Promise<BudgetSetEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<GetBudgetSetEventsByEventIdsQuery, GetBudgetSetEventsByEventIdsQueryVariables>(
+      GetBudgetSetEventsByEventIds,
+      { eventIds },
+      'budgetSetEvents'
+    )
+  }
+
+  public async getBudgetSpendingEvents(events: EventDetails[]): Promise<BudgetSpendingEventFieldsFragment[]> {
+    const eventIds = events.map((e) => this.getQueryNodeEventId(e.blockNumber, e.indexInBlock))
+    return this.multipleEntitiesQuery<
+      GetBudgetSpendingEventsByEventIdsQuery,
+      GetBudgetSpendingEventsByEventIdsQueryVariables
+    >(GetBudgetSpendingEventsByEventIds, { eventIds }, 'budgetSpendingEvents')
+  }
+
+  public async getLeaderSetEvent(event: EventDetails): Promise<LeaderSetEventFieldsFragment | null> {
+    const eventId = this.getQueryNodeEventId(event.blockNumber, event.indexInBlock)
+    return this.firstEntityQuery<GetLeaderSetEventsByEventIdsQuery, GetLeaderSetEventsByEventIdsQueryVariables>(
+      GetLeaderSetEventsByEventIds,
+      { eventIds: [eventId] },
+      'leaderSetEvents'
+    )
+  }
 
-    return this.queryNodeProvider.query({ query: MEMBER_BY_ID_QUERY, variables: { id: id.toNumber() } })
+  public async getLeaderUnsetEvent(event: EventDetails): Promise<LeaderUnsetEventFieldsFragment | null> {
+    const eventId = this.getQueryNodeEventId(event.blockNumber, event.indexInBlock)
+    return this.firstEntityQuery<GetLeaderUnsetEventsByEventIdsQuery, GetLeaderUnsetEventsByEventIdsQueryVariables>(
+      GetLeaderUnsetEventsByEventIds,
+      { eventIds: [eventId] },
+      'leaderUnsetEvents'
+    )
   }
 }

+ 21 - 0
tests/integration-tests/src/consts.ts

@@ -0,0 +1,21 @@
+import BN from 'bn.js'
+import { WorkingGroupModuleName } from './types'
+
+export const MINIMUM_STAKING_ACCOUNT_BALANCE = 200
+export const MIN_APPLICATION_STAKE = new BN(2000)
+export const MIN_UNSTANKING_PERIOD = 43201
+export const LEADER_OPENING_STAKE = new BN(2000)
+
+export const lockIdByWorkingGroup: { [K in WorkingGroupModuleName]: string } = {
+  storageWorkingGroup: '0x0606060606060606',
+  contentDirectoryWorkingGroup: '0x0707070707070707',
+  forumWorkingGroup: '0x0808080808080808',
+  membershipWorkingGroup: '0x0909090909090909',
+}
+
+export const workingGroups: WorkingGroupModuleName[] = [
+  'storageWorkingGroup',
+  'contentDirectoryWorkingGroup',
+  'forumWorkingGroup',
+  'membershipWorkingGroup',
+]

+ 103 - 0
tests/integration-tests/src/fixtures/membership/AddStakingAccountsHappyCaseFixture.ts

@@ -0,0 +1,103 @@
+import { Api } from '../../Api'
+import { assert } from 'chai'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { BaseQueryNodeFixture } from '../../Fixture'
+import { MemberContext, EventDetails } from '../../types'
+import {
+  StakingAccountAddedEventFieldsFragment,
+  StakingAccountConfirmedEventFieldsFragment,
+} from '../../graphql/generated/queries'
+import { MINIMUM_STAKING_ACCOUNT_BALANCE } from '../../consts'
+
+export class AddStakingAccountsHappyCaseFixture extends BaseQueryNodeFixture {
+  private memberContext: MemberContext
+  private accounts: string[]
+
+  private addExtrinsics: SubmittableExtrinsic<'promise'>[] = []
+  private confirmExtrinsics: SubmittableExtrinsic<'promise'>[] = []
+  private addEvents: EventDetails[] = []
+  private confirmEvents: EventDetails[] = []
+
+  public constructor(api: Api, query: QueryNodeApi, memberContext: MemberContext, accounts: string[]) {
+    super(api, query)
+    this.memberContext = memberContext
+    this.accounts = accounts
+  }
+
+  private assertQueryNodeAddAccountEventIsValid(
+    eventDetails: EventDetails,
+    account: string,
+    txHash: string,
+    qEvents: StakingAccountAddedEventFieldsFragment[]
+  ) {
+    const qEvent = this.findMatchingQueryNodeEvent(eventDetails, qEvents)
+    assert.equal(qEvent.inExtrinsic, txHash)
+    assert.equal(qEvent.member.id, this.memberContext.memberId.toString())
+    assert.equal(qEvent.account, account)
+  }
+
+  private assertQueryNodeConfirmAccountEventIsValid(
+    eventDetails: EventDetails,
+    account: string,
+    txHash: string,
+    qEvents: StakingAccountConfirmedEventFieldsFragment[]
+  ) {
+    const qEvent = this.findMatchingQueryNodeEvent(eventDetails, qEvents)
+    assert.equal(qEvent.inExtrinsic, txHash)
+    assert.equal(qEvent.member.id, this.memberContext.memberId.toString())
+    assert.equal(qEvent.account, account)
+  }
+
+  async execute(): Promise<void> {
+    const { memberContext, accounts } = this
+    this.addExtrinsics = accounts.map(() => this.api.tx.members.addStakingAccountCandidate(memberContext.memberId))
+    this.confirmExtrinsics = accounts.map((a) => this.api.tx.members.confirmStakingAccount(memberContext.memberId, a))
+    const addStakingCandidateFee = await this.api.estimateTxFee(this.addExtrinsics[0], accounts[0])
+    const confirmStakingAccountFee = await this.api.estimateTxFee(this.confirmExtrinsics[0], memberContext.account)
+
+    await this.api.treasuryTransferBalance(memberContext.account, confirmStakingAccountFee.muln(accounts.length))
+    const stakingAccountRequiredBalance = addStakingCandidateFee.addn(MINIMUM_STAKING_ACCOUNT_BALANCE)
+    await Promise.all(accounts.map((a) => this.api.treasuryTransferBalance(a, stakingAccountRequiredBalance)))
+    // Add staking account candidates
+    const addResults = await Promise.all(accounts.map((a, i) => this.api.signAndSend(this.addExtrinsics[i], a)))
+    this.addEvents = await Promise.all(
+      addResults.map((r) => this.api.retrieveMembershipEventDetails(r, 'StakingAccountAdded'))
+    )
+    // Confirm staking accounts
+    const confirmResults = await Promise.all(
+      this.confirmExtrinsics.map((tx) => this.api.signAndSend(tx, memberContext.account))
+    )
+    this.confirmEvents = await Promise.all(
+      confirmResults.map((r) => this.api.retrieveMembershipEventDetails(r, 'StakingAccountConfirmed'))
+    )
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    const { memberContext, accounts, addEvents, confirmEvents, addExtrinsics, confirmExtrinsics } = this
+    await this.query.tryQueryWithTimeout(
+      () => this.query.getMemberById(memberContext.memberId),
+      (qMember) => {
+        if (!qMember) {
+          throw new Error('Query node: Member not found')
+        }
+        assert.isNotEmpty(qMember.boundAccounts)
+        assert.includeMembers(qMember.boundAccounts, accounts)
+      }
+    )
+
+    // Check events
+    const qAddedEvents = await this.query.getStakingAccountAddedEvents(memberContext.memberId)
+    const qConfirmedEvents = await this.query.getStakingAccountConfirmedEvents(memberContext.memberId)
+    accounts.forEach(async (account, i) => {
+      this.assertQueryNodeAddAccountEventIsValid(addEvents[i], account, addExtrinsics[i].hash.toString(), qAddedEvents)
+      this.assertQueryNodeConfirmAccountEventIsValid(
+        confirmEvents[i],
+        account,
+        confirmExtrinsics[i].hash.toString(),
+        qConfirmedEvents
+      )
+    })
+  }
+}

+ 106 - 0
tests/integration-tests/src/fixtures/membership/BuyMembershipHappyCaseFixture.ts

@@ -0,0 +1,106 @@
+import { Api } from '../../Api'
+import { assert } from 'chai'
+import { generateParamsFromAccountId } from './utils'
+import { MemberId } from '@joystream/types/common'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { Membership } from '@joystream/types/members'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { MembershipMetadata } from '@joystream/metadata-protobuf'
+import { MembershipBoughtEventDetails } from '../../types'
+import { MembershipBoughtEventFieldsFragment, MembershipFieldsFragment } from '../../graphql/generated/queries'
+import { Utils } from '../../utils'
+import { StandardizedFixture } from '../../Fixture'
+import { SubmittableResult } from '@polkadot/api'
+
+export class BuyMembershipHappyCaseFixture extends StandardizedFixture {
+  protected accounts: string[]
+  protected memberIds: MemberId[] = []
+  protected events: MembershipBoughtEventDetails[] = []
+  protected members: Membership[] = []
+
+  public constructor(api: Api, query: QueryNodeApi, accounts: string[]) {
+    super(api, query)
+    this.accounts = accounts
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string[]> {
+    return this.accounts
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    return this.accounts.map((a) => this.api.tx.members.buyMembership(generateParamsFromAccountId(a)))
+  }
+
+  protected async getEventFromResult(result: SubmittableResult): Promise<MembershipBoughtEventDetails> {
+    return this.api.retrieveMembershipBoughtEventDetails(result)
+  }
+
+  public getCreatedMembers(): MemberId[] {
+    return this.events.map((e) => e.memberId)
+  }
+
+  protected assertQueriedMembersAreValid(
+    qMembers: MembershipFieldsFragment[],
+    qEvents: MembershipBoughtEventFieldsFragment[]
+  ): void {
+    this.events.forEach((e, i) => {
+      const account = this.accounts[i]
+      const params = generateParamsFromAccountId(account)
+      const qEvent = this.findMatchingQueryNodeEvent(e, qEvents)
+      const qMember = qMembers.find((m) => m.id === e.memberId.toString())
+      Utils.assert(qMember, 'Query node: Membership not found!')
+      const {
+        handle,
+        rootAccount,
+        controllerAccount,
+        metadata: { name, about },
+        isVerified,
+        entry,
+      } = qMember
+      const metadata = Utils.metadataFromBytes(MembershipMetadata, params.metadata)
+      assert.equal(handle, params.handle)
+      assert.equal(rootAccount, params.root_account)
+      assert.equal(controllerAccount, params.controller_account)
+      assert.equal(name, metadata.name)
+      assert.equal(about, metadata.about)
+      // TODO: avatar
+      assert.equal(isVerified, false)
+      Utils.assert(entry.__typename === 'MembershipEntryPaid', 'Query node: Invalid membership entry method')
+      Utils.assert(entry.membershipBoughtEvent)
+      assert.equal(entry.membershipBoughtEvent.id, qEvent.id)
+    })
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: MembershipBoughtEventFieldsFragment, i: number): void {
+    const account = this.accounts[i]
+    const event = this.events[i]
+    const txParams = generateParamsFromAccountId(account)
+    const metadata = Utils.metadataFromBytes(MembershipMetadata, txParams.metadata)
+    assert.equal(qEvent.newMember.id, event.memberId.toString())
+    assert.equal(qEvent.handle, txParams.handle)
+    assert.equal(qEvent.rootAccount, txParams.root_account)
+    assert.equal(qEvent.controllerAccount, txParams.controller_account)
+    assert.equal(qEvent.metadata.name, metadata.name || null)
+    assert.equal(qEvent.metadata.about, metadata.about || null)
+    // TODO: avatar
+  }
+
+  async execute(): Promise<void> {
+    // Add membership-price funds to accounts
+    const membershipFee = await this.api.getMembershipFee()
+    await Promise.all(this.accounts.map((a) => this.api.treasuryTransferBalance(a, membershipFee)))
+    await super.execute()
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+
+    const qEvents = await this.query.tryQueryWithTimeout(
+      () => this.query.getMembershipBoughtEvents(this.events),
+      (r) => this.assertQueryNodeEventsAreValid(r)
+    )
+
+    const qMembers = await this.query.getMembersByIds(this.events.map((e) => e.memberId))
+    this.assertQueriedMembersAreValid(qMembers, qEvents)
+  }
+}

+ 51 - 0
tests/integration-tests/src/fixtures/membership/BuyMembershipWithInsufficienFundsFixture.ts

@@ -0,0 +1,51 @@
+import BN from 'bn.js'
+import { Api } from '../../Api'
+import { assert } from 'chai'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { generateParamsFromAccountId } from './utils'
+import { BaseFixture } from '../../Fixture'
+
+export class BuyMembershipWithInsufficienFundsFixture extends BaseFixture {
+  private account: string
+
+  public constructor(api: Api, account: string) {
+    super(api)
+    this.account = account
+  }
+
+  private generateBuyMembershipTx(accountId: string): SubmittableExtrinsic<'promise'> {
+    return this.api.tx.members.buyMembership(generateParamsFromAccountId(accountId))
+  }
+
+  async execute(): Promise<void> {
+    // It is acceptable for same account to register a new member account
+    // So no need to assert that account is not already used as a controller or root for another member
+    // const membership = await this.api.getMemberIds(this.account)
+    // assert(membership.length === 0, 'Account must not be associated with a member')
+
+    // Fee estimation and transfer
+    const membershipFee: BN = await this.api.getMembershipFee()
+    const membershipTransactionFee: BN = await this.api.estimateTxFee(
+      this.generateBuyMembershipTx(this.account),
+      this.account
+    )
+
+    // Only provide enough funds for transaction fee but not enough to cover the membership fee
+    await this.api.treasuryTransferBalance(this.account, membershipTransactionFee)
+
+    const balance = await this.api.getBalance(this.account)
+
+    assert.isBelow(
+      balance.toNumber(),
+      membershipFee.add(membershipTransactionFee).toNumber(),
+      'Account already has sufficient balance to purchase membership'
+    )
+
+    const result = await this.api.signAndSend(this.generateBuyMembershipTx(this.account), this.account)
+
+    this.expectDispatchError(result, 'Buying membership with insufficient funds should fail.')
+
+    // Assert that failure occured for expected reason
+    assert.equal(this.api.getErrorNameFromExtrinsicFailedRecord(result), 'NotEnoughBalanceToBuyMembership')
+  }
+}

+ 133 - 0
tests/integration-tests/src/fixtures/membership/InviteMembersHappyCaseFixture.ts

@@ -0,0 +1,133 @@
+import { Api } from '../../Api'
+import { assert } from 'chai'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { MemberContext, MemberInvitedEventDetails } from '../../types'
+import { MemberInvitedEventFieldsFragment, MembershipFieldsFragment } from '../../graphql/generated/queries'
+import { MemberId } from '@joystream/types/common'
+import { MembershipMetadata } from '@joystream/metadata-protobuf'
+import { Utils } from '../../utils'
+import { StandardizedFixture } from '../../Fixture'
+import { generateParamsFromAccountId } from './utils'
+import { SubmittableResult } from '@polkadot/api'
+
+export class InviteMembersHappyCaseFixture extends StandardizedFixture {
+  protected inviterContext: MemberContext
+  protected accounts: string[]
+  protected initialInvitesCount?: number
+  protected events: MemberInvitedEventDetails[] = []
+
+  public constructor(api: Api, query: QueryNodeApi, inviterContext: MemberContext, accounts: string[]) {
+    super(api, query)
+    this.inviterContext = inviterContext
+    this.accounts = accounts
+  }
+
+  generateInviteMemberTx(memberId: MemberId, inviteeAccountId: string): SubmittableExtrinsic<'promise'> {
+    return this.api.tx.members.inviteMember({
+      ...generateParamsFromAccountId(inviteeAccountId),
+      inviting_member_id: memberId,
+    })
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string> {
+    return this.inviterContext.account
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    return this.accounts.map((a) => this.generateInviteMemberTx(this.inviterContext.memberId, a))
+  }
+
+  protected async getEventFromResult(result: SubmittableResult): Promise<MemberInvitedEventDetails> {
+    return this.api.retrieveMemberInvitedEventDetails(result)
+  }
+
+  protected assertQueriedInvitedMembersAreValid(
+    qMembers: MembershipFieldsFragment[],
+    qEvents: MemberInvitedEventFieldsFragment[]
+  ): void {
+    this.events.map((e, i) => {
+      const account = this.accounts[i]
+      const txParams = generateParamsFromAccountId(account)
+      const qMember = qMembers.find((m) => m.id === e.newMemberId.toString())
+      const qEvent = this.findMatchingQueryNodeEvent(e, qEvents)
+      Utils.assert(qMember, 'Query node: Membership not found!')
+      const {
+        handle,
+        rootAccount,
+        controllerAccount,
+        metadata: { name, about },
+        isVerified,
+        entry,
+        invitedBy,
+      } = qMember
+      const metadata = Utils.metadataFromBytes(MembershipMetadata, txParams.metadata)
+      assert.equal(handle, txParams.handle)
+      assert.equal(rootAccount, txParams.root_account)
+      assert.equal(controllerAccount, txParams.controller_account)
+      assert.equal(name, metadata.name)
+      assert.equal(about, metadata.about)
+      // TODO: avatar
+      assert.equal(isVerified, false)
+      Utils.assert(entry.__typename === 'MembershipEntryInvited', 'Query node: Invalid member entry method')
+      Utils.assert(entry.memberInvitedEvent, 'Query node: Empty memberInvitedEvent reference')
+      assert.equal(entry.memberInvitedEvent.id, qEvent.id)
+      Utils.assert(invitedBy, 'invitedBy cannot be empty')
+      assert.equal(invitedBy.id, this.inviterContext.memberId.toString())
+    })
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: MemberInvitedEventFieldsFragment, i: number): void {
+    const account = this.accounts[i]
+    const event = this.events[i]
+    const txParams = generateParamsFromAccountId(account)
+    const metadata = Utils.metadataFromBytes(MembershipMetadata, txParams.metadata)
+    assert.equal(qEvent.newMember.id, event.newMemberId.toString())
+    assert.equal(qEvent.handle, txParams.handle)
+    assert.equal(qEvent.rootAccount, txParams.root_account)
+    assert.equal(qEvent.controllerAccount, txParams.controller_account)
+    assert.equal(qEvent.metadata.name, metadata.name)
+    assert.equal(qEvent.metadata.about, metadata.about)
+    // TODO: avatar
+  }
+
+  async execute(): Promise<void> {
+    const initialInvitationBalance = await this.api.query.members.initialInvitationBalance()
+    // Top up working group budget to allow funding invited members
+    await this.api.makeSudoCall(
+      this.api.tx.membershipWorkingGroup.setBudget(initialInvitationBalance.muln(this.accounts.length))
+    )
+    // Load initial invites count
+    this.initialInvitesCount = (
+      await this.api.query.members.membershipById(this.inviterContext.memberId)
+    ).invites.toNumber()
+    // Execute
+    await super.execute()
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+
+    const qEvents = await this.query.tryQueryWithTimeout(
+      () => this.query.getMemberInvitedEvents(this.events),
+      (res) => this.assertQueryNodeEventsAreValid(res)
+    )
+
+    const invitedMembersIds = this.events.map((e) => e.newMemberId)
+    const qInvitedMembers = await this.query.getMembersByIds(invitedMembersIds)
+    this.assertQueriedInvitedMembersAreValid(qInvitedMembers, qEvents)
+
+    const qInviter = await this.query.getMemberById(this.inviterContext.memberId)
+    Utils.assert(qInviter, 'Query node: Inviter member not found!')
+
+    const { inviteCount, invitees } = qInviter
+    // Assert that inviteCount was correctly updated
+    assert.equal(inviteCount, this.initialInvitesCount! - this.accounts.length)
+    // Assert that all invited members are part of "invetees" field
+    assert.isNotEmpty(invitees)
+    assert.includeMembers(
+      invitees.map(({ id }) => id),
+      invitedMembersIds.map((id) => id.toString())
+    )
+  }
+}

+ 70 - 0
tests/integration-tests/src/fixtures/membership/RemoveStakingAccountsHappyCaseFixture.ts

@@ -0,0 +1,70 @@
+import { Api } from '../../Api'
+import { assert } from 'chai'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { BaseQueryNodeFixture } from '../../Fixture'
+import { EventDetails, MemberContext } from '../../types'
+import { StakingAccountRemovedEventFieldsFragment } from '../../graphql/generated/queries'
+
+export class RemoveStakingAccountsHappyCaseFixture extends BaseQueryNodeFixture {
+  private memberContext: MemberContext
+  private accounts: string[]
+
+  private events: EventDetails[] = []
+  private extrinsics: SubmittableExtrinsic<'promise'>[] = []
+
+  public constructor(api: Api, query: QueryNodeApi, memberContext: MemberContext, accounts: string[]) {
+    super(api, query)
+    this.memberContext = memberContext
+    this.accounts = accounts
+  }
+
+  private assertQueryNodeRemoveAccountEventIsValid(
+    eventDetails: EventDetails,
+    account: string,
+    txHash: string,
+    qEvents: StakingAccountRemovedEventFieldsFragment[]
+  ) {
+    const qEvent = this.findMatchingQueryNodeEvent(eventDetails, qEvents)
+    assert.equal(qEvent.inExtrinsic, txHash)
+    assert.equal(qEvent.member.id, this.memberContext.memberId.toString())
+    assert.equal(qEvent.account, account)
+  }
+
+  async execute(): Promise<void> {
+    const { memberContext, accounts } = this
+    this.extrinsics = accounts.map(() => this.api.tx.members.removeStakingAccount(memberContext.memberId))
+
+    const removeStakingAccountFee = await this.api.estimateTxFee(this.extrinsics[0], accounts[0])
+
+    await Promise.all(accounts.map((a) => this.api.treasuryTransferBalance(a, removeStakingAccountFee)))
+    // Remove staking accounts
+    const results = await Promise.all(accounts.map((a, i) => this.api.signAndSend(this.extrinsics[i], a)))
+    this.events = await Promise.all(
+      results.map((r) => this.api.retrieveMembershipEventDetails(r, 'StakingAccountRemoved'))
+    )
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    const { memberContext, accounts, events, extrinsics } = this
+    // Check member
+    await this.query.tryQueryWithTimeout(
+      () => this.query.getMemberById(memberContext.memberId),
+      (qMember) => {
+        if (!qMember) {
+          throw new Error('Query node: Membership not found!')
+        }
+        accounts.forEach((a) => assert.notInclude(qMember.boundAccounts, a))
+      }
+    )
+
+    // Check events
+    const qEvents = await this.query.getStakingAccountRemovedEvents(memberContext.memberId)
+    await Promise.all(
+      accounts.map(async (account, i) => {
+        this.assertQueryNodeRemoveAccountEventIsValid(events[i], account, extrinsics[i].hash.toString(), qEvents)
+      })
+    )
+  }
+}

+ 162 - 0
tests/integration-tests/src/fixtures/membership/SudoUpdateMembershipSystem.ts

@@ -0,0 +1,162 @@
+import BN from 'bn.js'
+import { Api } from '../../Api'
+import { assert } from 'chai'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { BaseQueryNodeFixture } from '../../Fixture'
+import { AnyQueryNodeEvent, EventDetails, MembershipEventName } from '../../types'
+import { MembershipSystemSnapshotFieldsFragment } from '../../graphql/generated/queries'
+
+type MembershipSystemValues = {
+  referralCut: number
+  defaultInviteCount: number
+  membershipPrice: BN
+  invitedInitialBalance: BN
+}
+
+export class SudoUpdateMembershipSystem extends BaseQueryNodeFixture {
+  private newValues: Partial<MembershipSystemValues>
+
+  private events: EventDetails[] = []
+  private eventNames: MembershipEventName[] = []
+  private extrinsics: SubmittableExtrinsic<'promise'>[] = []
+
+  public constructor(api: Api, query: QueryNodeApi, newValues: Partial<MembershipSystemValues>) {
+    super(api, query)
+    this.newValues = newValues
+  }
+
+  private async getMembershipSystemValuesAt(blockNumber: number): Promise<MembershipSystemValues> {
+    const blockHash = await this.api.getBlockHash(blockNumber)
+    return {
+      referralCut: (await this.api.query.members.referralCut.at(blockHash)).toNumber(),
+      defaultInviteCount: (await this.api.query.members.initialInvitationCount.at(blockHash)).toNumber(),
+      invitedInitialBalance: await this.api.query.members.initialInvitationBalance.at(blockHash),
+      membershipPrice: await this.api.query.members.membershipPrice.at(blockHash),
+    }
+  }
+
+  private async assertBeforeSnapshotIsValid(beforeSnapshot: MembershipSystemSnapshotFieldsFragment) {
+    assert.isNumber(beforeSnapshot.snapshotBlock)
+    const chainValues = await this.getMembershipSystemValuesAt(beforeSnapshot.snapshotBlock)
+    assert.equal(beforeSnapshot.referralCut, chainValues.referralCut)
+    assert.equal(beforeSnapshot.invitedInitialBalance, chainValues.invitedInitialBalance.toString())
+    assert.equal(beforeSnapshot.membershipPrice, chainValues.membershipPrice.toString())
+    assert.equal(beforeSnapshot.defaultInviteCount, chainValues.defaultInviteCount)
+  }
+
+  private assertAfterSnapshotIsValid(
+    beforeSnapshot: MembershipSystemSnapshotFieldsFragment,
+    afterSnapshot: MembershipSystemSnapshotFieldsFragment
+  ) {
+    const { newValues } = this
+    const expectedValue = (field: keyof MembershipSystemValues) => {
+      const newValue = newValues[field]
+      return newValue === undefined ? beforeSnapshot[field] : newValue instanceof BN ? newValue.toString() : newValue
+    }
+    assert.equal(afterSnapshot.referralCut, expectedValue('referralCut'))
+    assert.equal(afterSnapshot.invitedInitialBalance, expectedValue('invitedInitialBalance'))
+    assert.equal(afterSnapshot.membershipPrice, expectedValue('membershipPrice'))
+    assert.equal(afterSnapshot.defaultInviteCount, expectedValue('defaultInviteCount'))
+  }
+
+  private checkEvent<T extends AnyQueryNodeEvent>(qEvent: T | null, txHash: string): T {
+    if (!qEvent) {
+      throw new Error('Missing query-node event')
+    }
+    assert.equal(qEvent.inExtrinsic, txHash)
+    return qEvent
+  }
+
+  async execute(): Promise<void> {
+    if (this.newValues.referralCut !== undefined) {
+      this.extrinsics.push(this.api.tx.sudo.sudo(this.api.tx.members.setReferralCut(this.newValues.referralCut)))
+      this.eventNames.push('ReferralCutUpdated')
+    }
+    if (this.newValues.defaultInviteCount !== undefined) {
+      this.extrinsics.push(
+        this.api.tx.sudo.sudo(this.api.tx.members.setInitialInvitationCount(this.newValues.defaultInviteCount))
+      )
+      this.eventNames.push('InitialInvitationCountUpdated')
+    }
+    if (this.newValues.membershipPrice !== undefined) {
+      this.extrinsics.push(
+        this.api.tx.sudo.sudo(this.api.tx.members.setMembershipPrice(this.newValues.membershipPrice))
+      )
+      this.eventNames.push('MembershipPriceUpdated')
+    }
+    if (this.newValues.invitedInitialBalance !== undefined) {
+      this.extrinsics.push(
+        this.api.tx.sudo.sudo(this.api.tx.members.setInitialInvitationBalance(this.newValues.invitedInitialBalance))
+      )
+      this.eventNames.push('InitialInvitationBalanceUpdated')
+    }
+
+    // We don't use api.makeSudoCall, since we cannot(?) then access tx hashes
+    const sudo = await this.api.query.sudo.key()
+    const results = await Promise.all(this.extrinsics.map((tx) => this.api.signAndSend(tx, sudo)))
+    this.events = await Promise.all(
+      results.map((r, i) => this.api.retrieveMembershipEventDetails(r, this.eventNames[i]))
+    )
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    const { events, extrinsics, eventNames } = this
+    const afterSnapshotBlockTimestamp = Math.max(...events.map((e) => e.blockTimestamp))
+
+    // Fetch "afterSnapshot" first to make sure query node has progressed enough
+    const afterSnapshot = (await this.query.tryQueryWithTimeout(
+      () => this.query.getMembershipSystemSnapshotAt(afterSnapshotBlockTimestamp),
+      (snapshot) => assert.isOk(snapshot)
+    )) as MembershipSystemSnapshotFieldsFragment
+
+    const beforeSnapshot = await this.query.getMembershipSystemSnapshotBefore(afterSnapshotBlockTimestamp)
+
+    if (!beforeSnapshot) {
+      throw new Error(`Query node: MembershipSystemSnapshot before timestamp ${afterSnapshotBlockTimestamp} not found!`)
+    }
+
+    // Validate snapshots
+    await this.assertBeforeSnapshotIsValid(beforeSnapshot)
+    this.assertAfterSnapshotIsValid(beforeSnapshot, afterSnapshot)
+
+    // Check events
+    await Promise.all(
+      events.map(async (event, i) => {
+        const tx = extrinsics[i]
+        const eventName = eventNames[i]
+        const txHash = tx.hash.toString()
+        const { blockNumber, indexInBlock } = event
+        if (eventName === 'ReferralCutUpdated') {
+          const { newValue } = this.checkEvent(
+            await this.query.getReferralCutUpdatedEvent(blockNumber, indexInBlock),
+            txHash
+          )
+          assert.equal(newValue, this.newValues.referralCut)
+        }
+        if (eventName === 'MembershipPriceUpdated') {
+          const { newPrice } = this.checkEvent(
+            await this.query.getMembershipPriceUpdatedEvent(blockNumber, indexInBlock),
+            txHash
+          )
+          assert.equal(newPrice, this.newValues.membershipPrice!.toString())
+        }
+        if (eventName === 'InitialInvitationBalanceUpdated') {
+          const { newInitialBalance } = this.checkEvent(
+            await this.query.getInitialInvitationBalanceUpdatedEvent(blockNumber, indexInBlock),
+            txHash
+          )
+          assert.equal(newInitialBalance, this.newValues.invitedInitialBalance!.toString())
+        }
+        if (eventName === 'InitialInvitationCountUpdated') {
+          const { newInitialInvitationCount } = this.checkEvent(
+            await this.query.getInitialInvitationCountUpdatedEvent(blockNumber, indexInBlock),
+            txHash
+          )
+          assert.equal(newInitialInvitationCount, this.newValues.defaultInviteCount)
+        }
+      })
+    )
+  }
+}

+ 93 - 0
tests/integration-tests/src/fixtures/membership/TransferInvitesHappyCaseFixture.ts

@@ -0,0 +1,93 @@
+import { Api } from '../../Api'
+import { assert } from 'chai'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { BaseQueryNodeFixture } from '../../Fixture'
+import { MemberContext, EventDetails } from '../../types'
+import { InvitesTransferredEventFieldsFragment } from '../../graphql/generated/queries'
+import { Membership } from '@joystream/types/members'
+
+export class TransferInvitesHappyCaseFixture extends BaseQueryNodeFixture {
+  private fromContext: MemberContext
+  private toContext: MemberContext
+  private invitesToTransfer: number
+
+  private fromMemberInitialInvites?: number
+  private toMemberInitialInvites?: number
+  private event?: EventDetails
+  private tx?: SubmittableExtrinsic<'promise'>
+
+  public constructor(
+    api: Api,
+    query: QueryNodeApi,
+    fromContext: MemberContext,
+    toContext: MemberContext,
+    invitesToTransfer = 2
+  ) {
+    super(api, query)
+    this.fromContext = fromContext
+    this.toContext = toContext
+    this.invitesToTransfer = invitesToTransfer
+  }
+
+  private assertQueryNodeEventIsValid(
+    eventDetails: EventDetails,
+    txHash: string,
+    qEvent: InvitesTransferredEventFieldsFragment | null
+  ) {
+    if (!qEvent) {
+      throw new Error('Query node: InvitesTransferredEvent not found!')
+    }
+    const { inExtrinsic, sourceMember, targetMember, numberOfInvites } = qEvent
+    assert.equal(inExtrinsic, txHash)
+    assert.equal(sourceMember.id, this.fromContext.memberId.toString())
+    assert.equal(targetMember.id, this.toContext.memberId.toString())
+    assert.equal(numberOfInvites, this.invitesToTransfer)
+  }
+
+  async execute(): Promise<void> {
+    const { fromContext, toContext, invitesToTransfer } = this
+    this.tx = this.api.tx.members.transferInvites(fromContext.memberId, toContext.memberId, invitesToTransfer)
+    const txFee = await this.api.estimateTxFee(this.tx, fromContext.account)
+    await this.api.treasuryTransferBalance(fromContext.account, txFee)
+
+    const [fromMember, toMember] = await this.api.query.members.membershipById.multi<Membership>([
+      fromContext.memberId,
+      toContext.memberId,
+    ])
+
+    this.fromMemberInitialInvites = fromMember.invites.toNumber()
+    this.toMemberInitialInvites = toMember.invites.toNumber()
+
+    // Send transfer invites extrinsic
+    const txRes = await this.api.signAndSend(this.tx, fromContext.account)
+    this.event = await this.api.retrieveMembershipEventDetails(txRes, 'InvitesTransferred')
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    const { fromContext, toContext, invitesToTransfer } = this
+    // Check "from" member
+    await this.query.tryQueryWithTimeout(
+      () => this.query.getMemberById(fromContext.memberId),
+      (qSourceMember) => {
+        if (!qSourceMember) {
+          throw new Error('Query node: Source member not found')
+        }
+        assert.equal(qSourceMember.inviteCount, this.fromMemberInitialInvites! - invitesToTransfer)
+      }
+    )
+
+    // Check "to" member
+    const qTargetMember = await this.query.getMemberById(toContext.memberId)
+    if (!qTargetMember) {
+      throw new Error('Query node: Target member not found')
+    }
+    assert.equal(qTargetMember.inviteCount, this.toMemberInitialInvites! + invitesToTransfer)
+
+    // Check event
+    const qEvent = await this.query.getInvitesTransferredEvent(fromContext.memberId)
+
+    this.assertQueryNodeEventIsValid(this.event!, this.tx!.hash.toString(), qEvent)
+  }
+}

+ 79 - 0
tests/integration-tests/src/fixtures/membership/UpdateAccountsHappyCaseFixture.ts

@@ -0,0 +1,79 @@
+import { Api } from '../../Api'
+import { assert } from 'chai'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { BaseQueryNodeFixture } from '../../Fixture'
+import { EventDetails, MemberContext } from '../../types'
+import { MemberAccountsUpdatedEventFieldsFragment, MembershipFieldsFragment } from '../../graphql/generated/queries'
+
+export class UpdateAccountsHappyCaseFixture extends BaseQueryNodeFixture {
+  private memberContext: MemberContext
+  // Update data
+  private newRootAccount: string
+  private newControllerAccount: string
+
+  private tx?: SubmittableExtrinsic<'promise'>
+  private event?: EventDetails
+
+  public constructor(
+    api: Api,
+    query: QueryNodeApi,
+    memberContext: MemberContext,
+    newRootAccount: string,
+    newControllerAccount: string
+  ) {
+    super(api, query)
+    this.memberContext = memberContext
+    this.newRootAccount = newRootAccount
+    this.newControllerAccount = newControllerAccount
+  }
+
+  private assertAccountsUpdateSuccesful(qMember: MembershipFieldsFragment | null) {
+    if (!qMember) {
+      throw new Error('Query node: Membership not found!')
+    }
+    const { rootAccount, controllerAccount } = qMember
+    assert.equal(rootAccount, this.newRootAccount)
+    assert.equal(controllerAccount, this.newControllerAccount)
+  }
+
+  private assertQueryNodeEventIsValid(
+    eventDetails: EventDetails,
+    txHash: string,
+    qEvents: MemberAccountsUpdatedEventFieldsFragment[]
+  ) {
+    const qEvent = this.findMatchingQueryNodeEvent(eventDetails, qEvents)
+    const {
+      inExtrinsic,
+      member: { id: memberId },
+      newControllerAccount,
+      newRootAccount,
+    } = qEvent
+    assert.equal(inExtrinsic, txHash)
+    assert.equal(memberId, this.memberContext.memberId.toString())
+    assert.equal(newControllerAccount, this.newControllerAccount)
+    assert.equal(newRootAccount, this.newRootAccount)
+  }
+
+  async execute(): Promise<void> {
+    this.tx = this.api.tx.members.updateAccounts(
+      this.memberContext.memberId,
+      this.newRootAccount,
+      this.newControllerAccount
+    )
+    const txFee = await this.api.estimateTxFee(this.tx, this.memberContext.account)
+    await this.api.treasuryTransferBalance(this.memberContext.account, txFee)
+    const txRes = await this.api.signAndSend(this.tx, this.memberContext.account)
+    this.event = await this.api.retrieveMembershipEventDetails(txRes, 'MemberAccountsUpdated')
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    await this.query.tryQueryWithTimeout(
+      () => this.query.getMemberById(this.memberContext.memberId),
+      (qMember) => this.assertAccountsUpdateSuccesful(qMember)
+    )
+    const qEvents = await this.query.getMemberAccountsUpdatedEvents(this.memberContext.memberId)
+    this.assertQueryNodeEventIsValid(this.event!, this.tx!.hash.toString(), qEvents)
+  }
+}

+ 87 - 0
tests/integration-tests/src/fixtures/membership/UpdateProfileHappyCaseFixture.ts

@@ -0,0 +1,87 @@
+import { Api } from '../../Api'
+import { assert } from 'chai'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { BaseQueryNodeFixture } from '../../Fixture'
+import { MemberContext, EventDetails } from '../../types'
+import { MembershipFieldsFragment, MemberProfileUpdatedEventFieldsFragment } from '../../graphql/generated/queries'
+import { MembershipMetadata } from '@joystream/metadata-protobuf'
+import { Utils } from '../../utils'
+
+// TODO: Add partial update to make sure it works too
+export class UpdateProfileHappyCaseFixture extends BaseQueryNodeFixture {
+  private memberContext: MemberContext
+  // Update data
+  private newName = 'New name'
+  private newHandle = 'New handle'
+  private newAbout = 'New about'
+
+  private event?: EventDetails
+  private tx?: SubmittableExtrinsic<'promise'>
+
+  public constructor(api: Api, query: QueryNodeApi, memberContext: MemberContext) {
+    super(api, query)
+    this.memberContext = memberContext
+  }
+
+  private assertProfileUpdateSuccesful(qMember: MembershipFieldsFragment | null) {
+    if (!qMember) {
+      throw new Error('Query node: Membership not found!')
+    }
+    const {
+      handle,
+      metadata: { name, about },
+    } = qMember
+    assert.equal(name, this.newName)
+    assert.equal(handle, this.newHandle)
+    // TODO: avatar
+    assert.equal(about, this.newAbout)
+  }
+
+  private assertQueryNodeEventIsValid(
+    eventDetails: EventDetails,
+    txHash: string,
+    qEvents: MemberProfileUpdatedEventFieldsFragment[]
+  ) {
+    const qEvent = this.findMatchingQueryNodeEvent(eventDetails, qEvents)
+    const {
+      inExtrinsic,
+      member: { id: memberId },
+      newHandle,
+      newMetadata,
+    } = qEvent
+    assert.equal(inExtrinsic, txHash)
+    assert.equal(memberId, this.memberContext.memberId.toString())
+    assert.equal(newHandle, this.newHandle)
+    assert.equal(newMetadata.name, this.newName)
+    assert.equal(newMetadata.about, this.newAbout)
+    // TODO: avatar
+  }
+
+  async execute(): Promise<void> {
+    const metadata = new MembershipMetadata({
+      name: this.newName,
+      about: this.newAbout,
+    })
+    // TODO: avatar
+    this.tx = this.api.tx.members.updateProfile(
+      this.memberContext.memberId,
+      this.newHandle,
+      Utils.metadataToBytes(MembershipMetadata, metadata)
+    )
+    const txFee = await this.api.estimateTxFee(this.tx, this.memberContext.account)
+    await this.api.treasuryTransferBalance(this.memberContext.account, txFee)
+    const txRes = await this.api.signAndSend(this.tx, this.memberContext.account)
+    this.event = await this.api.retrieveMembershipEventDetails(txRes, 'MemberProfileUpdated')
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    await this.query.tryQueryWithTimeout(
+      () => this.query.getMemberById(this.memberContext.memberId),
+      (qMember) => this.assertProfileUpdateSuccesful(qMember)
+    )
+    const qEvents = await this.query.getMemberProfileUpdatedEvents(this.memberContext.memberId)
+    this.assertQueryNodeEventIsValid(this.event!, this.tx!.hash.toString(), qEvents)
+  }
+}

+ 9 - 0
tests/integration-tests/src/fixtures/membership/index.ts

@@ -0,0 +1,9 @@
+export { AddStakingAccountsHappyCaseFixture } from './AddStakingAccountsHappyCaseFixture'
+export { BuyMembershipHappyCaseFixture } from './BuyMembershipHappyCaseFixture'
+export { BuyMembershipWithInsufficienFundsFixture } from './BuyMembershipWithInsufficienFundsFixture'
+export { InviteMembersHappyCaseFixture } from './InviteMembersHappyCaseFixture'
+export { RemoveStakingAccountsHappyCaseFixture } from './RemoveStakingAccountsHappyCaseFixture'
+export { SudoUpdateMembershipSystem } from './SudoUpdateMembershipSystem'
+export { TransferInvitesHappyCaseFixture } from './TransferInvitesHappyCaseFixture'
+export { UpdateAccountsHappyCaseFixture } from './UpdateAccountsHappyCaseFixture'
+export { UpdateProfileHappyCaseFixture } from './UpdateProfileHappyCaseFixture'

+ 19 - 0
tests/integration-tests/src/fixtures/membership/utils.ts

@@ -0,0 +1,19 @@
+import { MembershipMetadata } from '@joystream/metadata-protobuf'
+import { CreateInterface } from '@joystream/types'
+import { BuyMembershipParameters } from '@joystream/types/members'
+import { Utils } from '../../utils'
+
+// Common code for Membership fixtures
+export function generateParamsFromAccountId(accountId: string): CreateInterface<BuyMembershipParameters> {
+  const metadataBytes = Utils.metadataToBytes(MembershipMetadata, {
+    name: `name${accountId.substring(0, 14)}`,
+    about: `about${accountId.substring(0, 14)}`,
+  })
+
+  return {
+    root_account: accountId,
+    controller_account: accountId,
+    handle: `handle${accountId.substring(0, 14)}`,
+    metadata: metadataBytes,
+  }
+}

+ 168 - 0
tests/integration-tests/src/fixtures/workingGroups/ApplyOnOpeningsHappyCaseFixture.ts

@@ -0,0 +1,168 @@
+import { ApplicationMetadata, IOpeningMetadata } from '@joystream/metadata-protobuf'
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { ApplicationFieldsFragment, AppliedOnOpeningEventFieldsFragment } from '../../graphql/generated/queries'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { AppliedOnOpeningEventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import _ from 'lodash'
+import { MemberId } from '@joystream/types/common'
+import { ApplicationId, Opening, OpeningId } from '@joystream/types/working-group'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+
+export type ApplicantDetails = {
+  memberId: MemberId
+  roleAccount: string
+  rewardAccount: string
+  stakingAccount: string
+}
+
+export type OpeningApplications = {
+  openingId: OpeningId
+  openingMetadata: IOpeningMetadata
+  applicants: ApplicantDetails[]
+}
+
+export type OpeningApplicationsFlattened = {
+  openingId: OpeningId
+  openingMetadata: IOpeningMetadata
+  applicant: ApplicantDetails
+}[]
+
+export class ApplyOnOpeningsHappyCaseFixture extends BaseWorkingGroupFixture {
+  protected applications: OpeningApplicationsFlattened
+  protected events: AppliedOnOpeningEventDetails[] = []
+  protected createdApplicationsByOpeningId: Map<number, ApplicationId[]> = new Map<number, ApplicationId[]>()
+
+  public constructor(
+    api: Api,
+    query: QueryNodeApi,
+    group: WorkingGroupModuleName,
+    openingsApplications: OpeningApplications[]
+  ) {
+    super(api, query, group)
+    this.applications = this.flattenOpeningApplicationsData(openingsApplications)
+  }
+
+  protected flattenOpeningApplicationsData(openingsApplications: OpeningApplications[]): OpeningApplicationsFlattened {
+    return openingsApplications.reduce(
+      (curr, details) =>
+        curr.concat(
+          details.applicants.map((a) => ({
+            openingId: details.openingId,
+            openingMetadata: details.openingMetadata,
+            applicant: a,
+          }))
+        ),
+      [] as OpeningApplicationsFlattened
+    )
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string[]> {
+    return this.applications.map((a) => a.applicant.roleAccount)
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    const openingIds = _.uniq(this.applications.map((a) => a.openingId.toString()))
+    const openings = await this.api.query[this.group].openingById.multi<Opening>(openingIds)
+    return this.applications.map((a, i) => {
+      const openingIndex = openingIds.findIndex((id) => id === a.openingId.toString())
+      const opening = openings[openingIndex]
+      return this.api.tx[this.group].applyOnOpening({
+        member_id: a.applicant.memberId,
+        description: Utils.metadataToBytes(ApplicationMetadata, this.getApplicationMetadata(a.openingMetadata, i)),
+        opening_id: a.openingId,
+        reward_account_id: a.applicant.rewardAccount,
+        role_account_id: a.applicant.roleAccount,
+        stake_parameters: {
+          stake: opening.stake_policy.stake_amount,
+          staking_account_id: a.applicant.stakingAccount,
+        },
+      })
+    })
+  }
+
+  protected async getEventFromResult(result: ISubmittableResult): Promise<AppliedOnOpeningEventDetails> {
+    return this.api.retrieveAppliedOnOpeningEventDetails(result, this.group)
+  }
+
+  public async execute(): Promise<void> {
+    await super.execute()
+    this.applications.map(({ openingId }, i) => {
+      this.createdApplicationsByOpeningId.set(openingId.toNumber(), [
+        ...(this.createdApplicationsByOpeningId.get(openingId.toNumber()) || []),
+        this.events[i].applicationId,
+      ])
+    })
+  }
+
+  public getCreatedApplicationsByOpeningId(openingId: OpeningId): ApplicationId[] {
+    const applicationIds = this.createdApplicationsByOpeningId.get(openingId.toNumber())
+    if (!applicationIds) {
+      throw new Error(`No created application ids by opening id ${openingId.toString()} found!`)
+    }
+    return applicationIds
+  }
+
+  protected getApplicationMetadata(openingMetadata: IOpeningMetadata, i: number): ApplicationMetadata {
+    const metadata = new ApplicationMetadata({ answers: [] })
+    ;(openingMetadata.applicationFormQuestions || []).forEach((question, j) => {
+      metadata.answers.push(`Answer to question ${j} by applicant number ${i}`)
+    })
+    return metadata
+  }
+
+  protected assertQueriedApplicationsAreValid(
+    qApplications: ApplicationFieldsFragment[],
+    qEvents: AppliedOnOpeningEventFieldsFragment[]
+  ): void {
+    this.events.map((e, i) => {
+      const applicationDetails = this.applications[i]
+      const qApplication = qApplications.find((a) => a.runtimeId === e.applicationId.toNumber())
+      const qEvent = this.findMatchingQueryNodeEvent(e, qEvents)
+      Utils.assert(qApplication, 'Query node: Application not found!')
+      assert.equal(qApplication.runtimeId, e.applicationId.toNumber())
+      assert.equal(qApplication.createdInEvent.id, qEvent.id)
+      assert.equal(qApplication.opening.runtimeId, applicationDetails.openingId.toNumber())
+      assert.equal(qApplication.applicant.id, applicationDetails.applicant.memberId.toString())
+      assert.equal(qApplication.roleAccount, applicationDetails.applicant.roleAccount)
+      assert.equal(qApplication.rewardAccount, applicationDetails.applicant.rewardAccount)
+      assert.equal(qApplication.stakingAccount, applicationDetails.applicant.stakingAccount)
+      assert.equal(qApplication.status.__typename, 'ApplicationStatusPending')
+      assert.equal(qApplication.stake, e.params.stake_parameters.stake)
+
+      const applicationMetadata = this.getApplicationMetadata(applicationDetails.openingMetadata, i)
+      assert.deepEqual(
+        qApplication.answers.map(({ question: { question }, answer }) => ({ question, answer })),
+        (applicationDetails.openingMetadata.applicationFormQuestions || []).map(({ question }, index) => ({
+          question,
+          answer: applicationMetadata.answers[index],
+        }))
+      )
+    })
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: AppliedOnOpeningEventFieldsFragment, i: number): void {
+    const applicationDetails = this.applications[i]
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.opening.runtimeId, applicationDetails.openingId.toNumber())
+    assert.equal(qEvent.application.runtimeId, this.events[i].applicationId.toNumber())
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    // Query the events
+    const qEvents = await this.query.tryQueryWithTimeout(
+      () => this.query.getAppliedOnOpeningEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+    // Query the applications
+    const qApplications = await this.query.getApplicationsByIds(
+      this.events.map((e) => e.applicationId),
+      this.group
+    )
+    this.assertQueriedApplicationsAreValid(qApplications, qEvents)
+  }
+}

+ 40 - 0
tests/integration-tests/src/fixtures/workingGroups/BaseCreateOpeningFixture.ts

@@ -0,0 +1,40 @@
+import { IOpeningMetadata } from '@joystream/metadata-protobuf'
+import { assert } from 'chai'
+import { OpeningMetadataFieldsFragment } from '../../graphql/generated/queries'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { queryNodeQuestionTypeToMetadataQuestionType } from './utils'
+export abstract class BaseCreateOpeningFixture extends BaseWorkingGroupFixture {
+  protected assertQueriedOpeningMetadataIsValid(
+    qOpeningMeta: OpeningMetadataFieldsFragment,
+    expectedMetadata?: IOpeningMetadata | null
+  ): void {
+    const {
+      shortDescription,
+      description,
+      expectedEndingTimestamp,
+      hiringLimit,
+      applicationDetails,
+      applicationFormQuestions,
+    } = expectedMetadata || {}
+    assert.equal(qOpeningMeta.shortDescription, shortDescription || null)
+    assert.equal(qOpeningMeta.description, description || null)
+    assert.equal(
+      qOpeningMeta.expectedEnding ? new Date(qOpeningMeta.expectedEnding).getTime() : qOpeningMeta.expectedEnding,
+      expectedEndingTimestamp || null
+    )
+    assert.equal(qOpeningMeta.hiringLimit, hiringLimit || null)
+    assert.equal(qOpeningMeta.applicationDetails, applicationDetails || null)
+    assert.deepEqual(
+      qOpeningMeta.applicationFormQuestions
+        .sort((a, b) => a.index - b.index)
+        .map(({ question, type }) => ({
+          question,
+          type: queryNodeQuestionTypeToMetadataQuestionType(type),
+        })),
+      (applicationFormQuestions || []).map(({ question, type }) => ({
+        question: question || null,
+        type: type || 0,
+      }))
+    )
+  }
+}

+ 13 - 0
tests/integration-tests/src/fixtures/workingGroups/BaseWorkingGroupFixture.ts

@@ -0,0 +1,13 @@
+import { Api } from '../../Api'
+import { StandardizedFixture } from '../../Fixture'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { WorkingGroupModuleName } from '../../types'
+
+export abstract class BaseWorkingGroupFixture extends StandardizedFixture {
+  protected group: WorkingGroupModuleName
+
+  public constructor(api: Api, query: QueryNodeApi, group: WorkingGroupModuleName) {
+    super(api, query)
+    this.group = group
+  }
+}

+ 79 - 0
tests/integration-tests/src/fixtures/workingGroups/CancelOpeningsFixture.ts

@@ -0,0 +1,79 @@
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+import { OpeningId } from '@joystream/types/working-group'
+import {
+  ApplicationBasicFieldsFragment,
+  OpeningCanceledEventFieldsFragment,
+  OpeningFieldsFragment,
+} from '../../graphql/generated/queries'
+
+export class CancelOpeningsFixture extends BaseWorkingGroupFixture {
+  protected openingIds: OpeningId[]
+
+  public constructor(api: Api, query: QueryNodeApi, group: WorkingGroupModuleName, openingIds: OpeningId[]) {
+    super(api, query, group)
+    this.openingIds = openingIds
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string> {
+    return this.api.getLeadRoleKey(this.group)
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    return this.openingIds.map((id) => this.api.tx[this.group].cancelOpening(id))
+  }
+
+  protected async getEventFromResult(result: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(result, this.group, 'OpeningCanceled')
+  }
+
+  protected assertQueriedOpeningsAreValid(
+    qEvents: OpeningCanceledEventFieldsFragment[],
+    qOpenings: OpeningFieldsFragment[]
+  ): void {
+    this.events.map((e, i) => {
+      const openingId = this.openingIds[i]
+      const qEvent = this.findMatchingQueryNodeEvent(e, qEvents)
+      const qOpening = qOpenings.find((o) => o.runtimeId === openingId.toNumber())
+      Utils.assert(qOpening)
+      Utils.assert(qOpening.status.__typename === 'OpeningStatusCancelled', 'Query node: Invalid opening status')
+      Utils.assert(qOpening.status.openingCanceledEvent, 'Query node: Missing openingCanceledEvent relation')
+      assert.equal(qOpening.status.openingCanceledEvent.id, qEvent.id)
+      qOpening.applications.forEach((a) => this.assertApplicationStatusIsValid(qEvent, a))
+    })
+  }
+
+  protected assertApplicationStatusIsValid(
+    qEvent: OpeningCanceledEventFieldsFragment,
+    qApplication: ApplicationBasicFieldsFragment
+  ): void {
+    // It's possible that some of the applications have been withdrawn
+    assert.oneOf(qApplication.status.__typename, ['ApplicationStatusWithdrawn', 'ApplicationStatusCancelled'])
+    if (qApplication.status.__typename === 'ApplicationStatusCancelled') {
+      // FIXME: Missing due to Hydra bug now
+      // Utils.assert(qApplication.status.openingCanceledEvent, 'Query node: Missing openingCanceledEvent relation')
+      // assert.equal(qApplication.status.openingCanceledEvent.id, qEvent.id)
+    }
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: OpeningCanceledEventFieldsFragment, i: number): void {
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.opening.runtimeId, this.openingIds[i].toNumber())
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    const qEvents = await this.query.tryQueryWithTimeout(
+      () => this.query.getOpeningCancelledEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+    const qOpenings = await this.query.getOpeningsByIds(this.openingIds, this.group)
+    this.assertQueriedOpeningsAreValid(qEvents, qOpenings)
+  }
+}

+ 154 - 0
tests/integration-tests/src/fixtures/workingGroups/CreateOpeningsFixture.ts

@@ -0,0 +1,154 @@
+import { Api } from '../../Api'
+import { BaseCreateOpeningFixture } from './BaseCreateOpeningFixture'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { OpeningAddedEventDetails, WorkingGroupModuleName } from '../../types'
+import { OpeningId } from '@joystream/types/working-group'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { Utils } from '../../utils'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { OpeningAddedEventFieldsFragment, OpeningFieldsFragment } from '../../graphql/generated/queries'
+import { WorkingGroupOpeningType } from '../../graphql/generated/schema'
+import { assert } from 'chai'
+import { MIN_APPLICATION_STAKE, MIN_UNSTANKING_PERIOD } from '../../consts'
+import moment from 'moment'
+import BN from 'bn.js'
+import { IOpeningMetadata, OpeningMetadata } from '@joystream/metadata-protobuf'
+import { createType } from '@joystream/types'
+import { Bytes } from '@polkadot/types'
+
+export type OpeningParams = {
+  stake: BN
+  unstakingPeriod: number
+  reward: BN
+  metadata: IOpeningMetadata | string
+  expectMetadataFailure?: boolean
+}
+
+export const DEFAULT_OPENING_PARAMS: Omit<OpeningParams, 'metadata'> & { metadata: IOpeningMetadata } = {
+  stake: MIN_APPLICATION_STAKE,
+  unstakingPeriod: MIN_UNSTANKING_PERIOD,
+  reward: new BN(10),
+  metadata: {
+    shortDescription: 'Test opening',
+    description: '# Test opening',
+    expectedEndingTimestamp: moment().unix() + 60,
+    hiringLimit: 1,
+    applicationDetails: '- This is automatically created opening, do not apply!',
+    applicationFormQuestions: [
+      { question: 'Question 1?', type: OpeningMetadata.ApplicationFormQuestion.InputType.TEXT },
+      { question: 'Question 2?', type: OpeningMetadata.ApplicationFormQuestion.InputType.TEXTAREA },
+    ],
+  },
+}
+
+export class CreateOpeningsFixture extends BaseCreateOpeningFixture {
+  protected asSudo: boolean
+  protected events: OpeningAddedEventDetails[] = []
+
+  protected openingsParams: OpeningParams[]
+
+  public constructor(
+    api: Api,
+    query: QueryNodeApi,
+    group: WorkingGroupModuleName,
+    openingsParams?: OpeningParams[],
+    asSudo = false
+  ) {
+    super(api, query, group)
+    this.openingsParams = openingsParams || [DEFAULT_OPENING_PARAMS]
+    this.asSudo = asSudo
+  }
+
+  public getCreatedOpeningIds(): OpeningId[] {
+    if (!this.events.length) {
+      throw new Error('Trying to get created opening ids before they were created!')
+    }
+    return this.events.map((e) => e.openingId)
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string> {
+    return this.asSudo ? (await this.api.query.sudo.key()).toString() : await this.api.getLeadRoleKey(this.group)
+  }
+
+  protected getOpeningMetadata(params: OpeningParams): IOpeningMetadata | null {
+    if (typeof params.metadata === 'string') {
+      try {
+        return Utils.metadataFromBytes(OpeningMetadata, createType('Bytes', params.metadata))
+      } catch (e) {
+        if (!params.expectMetadataFailure) {
+          throw e
+        }
+        return null
+      }
+    }
+
+    return params.metadata
+  }
+
+  protected getOpeningMetadataBytes(params: { metadata: IOpeningMetadata | string }): Bytes {
+    const { metadata } = params
+    return typeof metadata === 'string'
+      ? createType('Bytes', metadata)
+      : Utils.metadataToBytes(OpeningMetadata, metadata)
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    const extrinsics = this.openingsParams.map((params) =>
+      this.api.tx[this.group].addOpening(
+        this.getOpeningMetadataBytes(params),
+        this.asSudo ? 'Leader' : 'Regular',
+        { stake_amount: params.stake, leaving_unstaking_period: params.unstakingPeriod },
+        params.reward
+      )
+    )
+
+    return this.asSudo ? extrinsics.map((tx) => this.api.tx.sudo.sudo(tx)) : extrinsics
+  }
+
+  protected async getEventFromResult(result: ISubmittableResult): Promise<OpeningAddedEventDetails> {
+    return this.api.retrieveOpeningAddedEventDetails(result, this.group)
+  }
+
+  protected assertQueriedOpeningsAreValid(
+    qOpenings: OpeningFieldsFragment[],
+    qEvents: OpeningAddedEventFieldsFragment[]
+  ): void {
+    this.events.map((e, i) => {
+      const qOpening = qOpenings.find((o) => o.runtimeId === e.openingId.toNumber())
+      const openingParams = this.openingsParams[i]
+      const qEvent = this.findMatchingQueryNodeEvent(e, qEvents)
+      Utils.assert(qOpening, 'Query node: Opening not found')
+      assert.equal(qOpening.runtimeId, e.openingId.toNumber())
+      assert.equal(qOpening.createdInEvent.id, qEvent.id)
+      assert.equal(qOpening.group.name, this.group)
+      assert.equal(qOpening.rewardPerBlock, openingParams.reward.toString())
+      assert.equal(qOpening.type, this.asSudo ? WorkingGroupOpeningType.Leader : WorkingGroupOpeningType.Regular)
+      assert.equal(qOpening.status.__typename, 'OpeningStatusOpen')
+      assert.equal(qOpening.stakeAmount, openingParams.stake.toString())
+      assert.equal(qOpening.unstakingPeriod, openingParams.unstakingPeriod)
+      // Metadata
+      this.assertQueriedOpeningMetadataIsValid(qOpening.metadata, this.getOpeningMetadata(openingParams))
+    })
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: OpeningAddedEventFieldsFragment, i: number): void {
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.opening.runtimeId, this.events[i].openingId.toNumber())
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    // Query the events
+    const qEvents = await this.query.tryQueryWithTimeout(
+      () => this.query.getOpeningAddedEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+
+    // Query the openings
+    const qOpenings = await this.query.getOpeningsByIds(
+      this.events.map((e) => e.openingId),
+      this.group
+    )
+    this.assertQueriedOpeningsAreValid(qOpenings, qEvents)
+  }
+}

+ 150 - 0
tests/integration-tests/src/fixtures/workingGroups/CreateUpcomingOpeningsFixture.ts

@@ -0,0 +1,150 @@
+import { Api } from '../../Api'
+import { BaseCreateOpeningFixture } from './BaseCreateOpeningFixture'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { Utils } from '../../utils'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { StatusTextChangedEventFieldsFragment, UpcomingOpeningFieldsFragment } from '../../graphql/generated/queries'
+import { assert } from 'chai'
+import {
+  IUpcomingOpeningMetadata,
+  UpcomingOpeningMetadata,
+  WorkingGroupMetadataAction,
+} from '@joystream/metadata-protobuf'
+import Long from 'long'
+import { Bytes } from '@polkadot/types'
+import moment from 'moment'
+import { DEFAULT_OPENING_PARAMS } from './CreateOpeningsFixture'
+import { createType } from '@joystream/types'
+
+export const DEFAULT_UPCOMING_OPENING_META: IUpcomingOpeningMetadata = {
+  minApplicationStake: Long.fromString(DEFAULT_OPENING_PARAMS.stake.toString()),
+  rewardPerBlock: Long.fromString(DEFAULT_OPENING_PARAMS.reward.toString()),
+  expectedStart: moment().unix() + 3600,
+  metadata: DEFAULT_OPENING_PARAMS.metadata,
+}
+
+export type UpcomingOpeningParams = {
+  meta: IUpcomingOpeningMetadata | string
+  expectMetadataFailure?: boolean
+}
+
+export class CreateUpcomingOpeningsFixture extends BaseCreateOpeningFixture {
+  protected upcomingOpeningsParams: UpcomingOpeningParams[]
+  protected createdUpcomingOpeningIds: string[] = []
+
+  public constructor(api: Api, query: QueryNodeApi, group: WorkingGroupModuleName, params?: UpcomingOpeningParams[]) {
+    super(api, query, group)
+    this.upcomingOpeningsParams = params || [{ meta: DEFAULT_UPCOMING_OPENING_META }]
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string> {
+    return this.api.getLeadRoleKey(this.group)
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    return this.upcomingOpeningsParams.map((params) =>
+      this.api.tx[this.group].setStatusText(this.getActionMetadataBytes(params))
+    )
+  }
+
+  protected async getEventFromResult(result: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(result, this.group, 'StatusTextChanged')
+  }
+
+  public getCreatedUpcomingOpeningIds(): string[] {
+    if (!this.createdUpcomingOpeningIds.length) {
+      throw new Error('Trying to get created UpcomingOpening ids before they are known')
+    }
+    return this.createdUpcomingOpeningIds
+  }
+
+  protected getUpcomingOpeningMeta(params: UpcomingOpeningParams): IUpcomingOpeningMetadata | null {
+    if (typeof params.meta === 'string') {
+      try {
+        return Utils.metadataFromBytes(UpcomingOpeningMetadata, createType('Bytes', params.meta))
+      } catch (e) {
+        if (!params.expectMetadataFailure) {
+          throw e
+        }
+        return null
+      }
+    }
+    return params.meta
+  }
+
+  protected getActionMetadataBytes(params: UpcomingOpeningParams): Bytes {
+    const upcomingOpeningMeta = this.getUpcomingOpeningMeta(params)
+    if (!upcomingOpeningMeta) {
+      return createType('Bytes', params.meta)
+    }
+    return Utils.metadataToBytes(WorkingGroupMetadataAction, {
+      addUpcomingOpening: {
+        metadata: upcomingOpeningMeta,
+      },
+    })
+  }
+
+  protected assertQueriedUpcomingOpeningsAreValid(
+    qUpcomingOpenings: UpcomingOpeningFieldsFragment[],
+    qEvents: StatusTextChangedEventFieldsFragment[]
+  ): void {
+    this.events.forEach((e, i) => {
+      const expectedMeta = this.getUpcomingOpeningMeta(this.upcomingOpeningsParams[i])
+      const qEvent = this.findMatchingQueryNodeEvent(e, qEvents)
+      const qUpcomingOpening = qUpcomingOpenings.find((o) => o.createdInEvent.id === qEvent.id)
+      if (expectedMeta) {
+        Utils.assert(qUpcomingOpening)
+        assert.equal(
+          qUpcomingOpening.expectedStart
+            ? new Date(qUpcomingOpening.expectedStart).getTime()
+            : qUpcomingOpening.expectedStart,
+          expectedMeta.expectedStart || null
+        )
+        assert.equal(qUpcomingOpening.group.name, this.group)
+        assert.equal(
+          qUpcomingOpening.rewardPerBlock,
+          expectedMeta.rewardPerBlock && expectedMeta.rewardPerBlock.toNumber()
+            ? expectedMeta.rewardPerBlock.toString()
+            : null
+        )
+        assert.equal(
+          qUpcomingOpening.stakeAmount,
+          expectedMeta.minApplicationStake && expectedMeta.minApplicationStake.toNumber()
+            ? expectedMeta.minApplicationStake.toString()
+            : null
+        )
+        Utils.assert(qEvent.result.__typename === 'UpcomingOpeningAdded')
+        assert.equal(qEvent.result.upcomingOpeningId, qUpcomingOpening.id)
+        this.assertQueriedOpeningMetadataIsValid(qUpcomingOpening.metadata, expectedMeta.metadata)
+      } else {
+        assert.isUndefined(qUpcomingOpening)
+      }
+    })
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: StatusTextChangedEventFieldsFragment, i: number): void {
+    const params = this.upcomingOpeningsParams[i]
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.metadata, this.getActionMetadataBytes(params).toString())
+    assert.equal(
+      qEvent.result.__typename,
+      params.expectMetadataFailure ? 'InvalidActionMetadata' : 'UpcomingOpeningAdded'
+    )
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    // Query the event
+    const qEvents = await this.query.tryQueryWithTimeout(
+      () => this.query.getStatusTextChangedEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+    // Query the opening
+    const qUpcomingOpenings = await this.query.getUpcomingOpeningsByCreatedInEventIds(qEvents.map((e) => e.id))
+    this.assertQueriedUpcomingOpeningsAreValid(qUpcomingOpenings, qEvents)
+
+    this.createdUpcomingOpeningIds = qUpcomingOpenings.map((o) => o.id)
+  }
+}

+ 90 - 0
tests/integration-tests/src/fixtures/workingGroups/DecreaseWorkerStakesFixture.ts

@@ -0,0 +1,90 @@
+import BN from 'bn.js'
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { Worker, WorkerId } from '@joystream/types/working-group'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+import { lockIdByWorkingGroup } from '../../consts'
+import { StakeDecreasedEventFieldsFragment, WorkerFieldsFragment } from '../../graphql/generated/queries'
+
+export class DecreaseWorkerStakesFixture extends BaseWorkingGroupFixture {
+  protected asSudo: boolean
+
+  protected workerIds: WorkerId[]
+  protected amounts: BN[]
+  protected workers: Worker[] = []
+  protected workerStakes: BN[] = []
+
+  public constructor(
+    api: Api,
+    query: QueryNodeApi,
+    group: WorkingGroupModuleName,
+    workerIds: WorkerId[],
+    amounts: BN[],
+    asSudo = false
+  ) {
+    super(api, query, group)
+    this.workerIds = workerIds
+    this.amounts = amounts
+    this.asSudo = asSudo
+  }
+
+  protected async loadWorkersData(): Promise<void> {
+    this.workers = await this.api.query[this.group].workerById.multi<Worker>(this.workerIds)
+    this.workerStakes = await Promise.all(
+      this.workers.map((w) => this.api.getStakedBalance(w.staking_account_id, lockIdByWorkingGroup[this.group]))
+    )
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string> {
+    return this.asSudo ? (await this.api.query.sudo.key()).toString() : await this.api.getLeadRoleKey(this.group)
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    const extrinsics = this.workerIds.map((workerId, i) =>
+      this.api.tx[this.group].decreaseStake(workerId, this.amounts[i])
+    )
+    return this.asSudo ? extrinsics.map((tx) => this.api.tx.sudo.sudo(tx)) : extrinsics
+  }
+
+  protected getEventFromResult(result: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(result, this.group, 'StakeDecreased')
+  }
+
+  public async execute(): Promise<void> {
+    await this.loadWorkersData()
+    await super.execute()
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: StakeDecreasedEventFieldsFragment, i: number): void {
+    assert.equal(qEvent.worker.runtimeId, this.workerIds[i].toNumber())
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.amount, this.amounts[i].toString())
+  }
+
+  protected assertQueriedWorkersAreValid(qWorkers: WorkerFieldsFragment[]): void {
+    this.workerIds.map((workerId, i) => {
+      const worker = qWorkers.find((w) => w.runtimeId === workerId.toNumber())
+      Utils.assert(worker, 'Query node: Worker not found!')
+      assert.equal(worker.stake, this.workerStakes[i].sub(this.amounts[i]).toString())
+    })
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+
+    // Query and check events
+    await this.query.tryQueryWithTimeout(
+      () => this.query.getStakeDecreasedEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+
+    // Check workers
+    const qWorkers = await this.query.getWorkersByIds(this.workerIds, this.group)
+    this.assertQueriedWorkersAreValid(qWorkers)
+  }
+}

+ 241 - 0
tests/integration-tests/src/fixtures/workingGroups/FillOpeningsFixture.ts

@@ -0,0 +1,241 @@
+import BN from 'bn.js'
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, OpeningFilledEventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { Application, ApplicationId, Opening, OpeningId, WorkerId } from '@joystream/types/working-group'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+import { JoyBTreeSet } from '@joystream/types/common'
+import { registry } from '@joystream/types'
+import { lockIdByWorkingGroup } from '../../consts'
+import {
+  LeaderSetEventFieldsFragment,
+  OpeningFieldsFragment,
+  OpeningFilledEventFieldsFragment,
+  WorkerFieldsFragment,
+} from '../../graphql/generated/queries'
+
+export class FillOpeningsFixture extends BaseWorkingGroupFixture {
+  protected events: OpeningFilledEventDetails[] = []
+  protected asSudo: boolean
+
+  protected openings: Opening[] = []
+  protected openingIds: OpeningId[]
+  protected acceptedApplicationsIdsArrays: ApplicationId[][]
+  protected acceptedApplicationsArrays: Application[][] = []
+  protected applicationStakesArrays: BN[][] = []
+  protected createdWorkerIdsByOpeningId: Map<number, WorkerId[]> = new Map<number, WorkerId[]>()
+
+  public constructor(
+    api: Api,
+    query: QueryNodeApi,
+    group: WorkingGroupModuleName,
+    openingIds: OpeningId[],
+    acceptedApplicationsIdsArrays: ApplicationId[][],
+    asSudo = false
+  ) {
+    super(api, query, group)
+    this.openingIds = openingIds
+    this.acceptedApplicationsIdsArrays = acceptedApplicationsIdsArrays
+    this.asSudo = asSudo
+  }
+
+  public getCreatedWorkerIdsByOpeningId(openingId: OpeningId): WorkerId[] {
+    const workerIds = this.createdWorkerIdsByOpeningId.get(openingId.toNumber())
+    Utils.assert(workerIds, `No created worker ids for opening id ${openingId.toString()} were found!`)
+    return workerIds
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string> {
+    return this.asSudo ? (await this.api.query.sudo.key()).toString() : await this.api.getLeadRoleKey(this.group)
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    const extrinsics = this.openingIds.map((openingId, i) => {
+      const applicationsSet = new (JoyBTreeSet(ApplicationId))(registry, this.acceptedApplicationsIdsArrays[i])
+      this.debug(
+        'Applications to accept:',
+        this.acceptedApplicationsIdsArrays[i].map((id) => id.toNumber())
+      )
+      this.debug('Encoded BTreeSet:', applicationsSet.toHex())
+      return this.api.tx[this.group].fillOpening(openingId, applicationsSet)
+    })
+    return this.asSudo ? extrinsics.map((tx) => this.api.tx.sudo.sudo(tx)) : extrinsics
+  }
+
+  protected getEventFromResult(result: ISubmittableResult): Promise<OpeningFilledEventDetails> {
+    return this.api.retrieveOpeningFilledEventDetails(result, this.group)
+  }
+
+  protected async loadApplicationsData(): Promise<void> {
+    this.acceptedApplicationsArrays = await Promise.all(
+      this.acceptedApplicationsIdsArrays.map((acceptedApplicationIds) =>
+        this.api.query[this.group].applicationById.multi<Application>(acceptedApplicationIds)
+      )
+    )
+    this.applicationStakesArrays = await Promise.all(
+      this.acceptedApplicationsArrays.map((acceptedApplications) =>
+        Promise.all(
+          acceptedApplications.map((a) =>
+            this.api.getStakedBalance(a.staking_account_id, lockIdByWorkingGroup[this.group])
+          )
+        )
+      )
+    )
+  }
+
+  protected async loadOpeningsData(): Promise<void> {
+    this.openings = await this.api.query[this.group].openingById.multi(this.openingIds)
+  }
+
+  async execute(): Promise<void> {
+    await this.loadApplicationsData()
+    await this.loadOpeningsData()
+    await super.execute()
+    this.events.forEach((e, i) => {
+      this.createdWorkerIdsByOpeningId.set(
+        this.openingIds[i].toNumber(),
+        Array.from(e.applicationIdToWorkerIdMap.values())
+      )
+    })
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: OpeningFilledEventFieldsFragment, i: number): void {
+    assert.equal(qEvent.opening.runtimeId, this.openingIds[i].toNumber())
+    assert.equal(qEvent.group.name, this.group)
+    this.acceptedApplicationsIdsArrays[i].forEach((acceptedApplId, j) => {
+      // Cannot use "applicationIdToWorkerIdMap.get" here,
+      // it only works if the passed instance is identical to BTreeMap key instance (=== instead of .eq)
+      const [, workerId] =
+        Array.from(this.events[i].applicationIdToWorkerIdMap.entries()).find(([applicationId]) =>
+          applicationId.eq(acceptedApplId)
+        ) || []
+      Utils.assert(
+        workerId,
+        `WorkerId for application id ${acceptedApplId.toString()} not found in OpeningFilled event!`
+      )
+      const qWorker = qEvent.workersHired.find((w) => w.runtimeId === workerId.toNumber())
+      Utils.assert(qWorker, `Query node: Worker not found in OpeningFilled.hiredWorkers (id: ${workerId.toString()})`)
+      this.assertHiredWorkerIsValid(
+        this.acceptedApplicationsIdsArrays[i][j],
+        this.acceptedApplicationsArrays[i][j],
+        this.applicationStakesArrays[i][j],
+        this.openings[i],
+        qWorker,
+        qEvent
+      )
+    })
+  }
+
+  protected assertHiredWorkerIsValid(
+    applicationId: ApplicationId,
+    application: Application,
+    applicationStake: BN,
+    opening: Opening,
+    qWorker: WorkerFieldsFragment,
+    qEvent: OpeningFilledEventFieldsFragment
+  ): void {
+    assert.equal(qWorker.group.name, this.group)
+    assert.equal(qWorker.membership.id, application.member_id.toString())
+    assert.equal(qWorker.roleAccount, application.role_account_id.toString())
+    assert.equal(qWorker.rewardAccount, application.reward_account_id.toString())
+    assert.equal(qWorker.stakeAccount, application.staking_account_id.toString())
+    assert.equal(qWorker.status.__typename, 'WorkerStatusActive')
+    assert.equal(qWorker.isLead, true)
+    assert.equal(qWorker.stake, applicationStake.toString())
+    assert.equal(qWorker.entry.id, qEvent.id)
+    assert.equal(qWorker.application.runtimeId, applicationId.toNumber())
+    assert.equal(qWorker.rewardPerBlock, opening.reward_per_block.toString())
+  }
+
+  protected assertOpeningsStatusesAreValid(
+    qEvents: OpeningFilledEventFieldsFragment[],
+    qOpenings: OpeningFieldsFragment[]
+  ): void {
+    this.events.map((e, i) => {
+      const openingId = this.openingIds[i]
+      const qEvent = this.findMatchingQueryNodeEvent(e, qEvents)
+      const qOpening = qOpenings.find((o) => o.runtimeId === openingId.toNumber())
+      Utils.assert(qOpening, 'Query node: Opening not found')
+      Utils.assert(qOpening.status.__typename === 'OpeningStatusFilled', 'Query node: Invalid opening status')
+      Utils.assert(qOpening.status.openingFilledEvent, 'Query node: Missing openingFilledEvent relation')
+      assert.equal(qOpening.status.openingFilledEvent.id, qEvent.id)
+    })
+  }
+
+  protected assertApplicationStatusesAreValid(
+    qEvents: OpeningFilledEventFieldsFragment[],
+    qOpenings: OpeningFieldsFragment[]
+  ): void {
+    this.events.map((e, i) => {
+      const openingId = this.openingIds[i]
+      const acceptedApplicationsIds = this.acceptedApplicationsIdsArrays[i]
+      const qEvent = this.findMatchingQueryNodeEvent(e, qEvents)
+      const qOpening = qOpenings.find((o) => o.runtimeId === openingId.toNumber())
+      Utils.assert(qOpening, 'Query node: Opening not found')
+      qOpening.applications.forEach((qApplication) => {
+        const isAccepted = acceptedApplicationsIds.some((id) => id.toNumber() === qApplication.runtimeId)
+        if (isAccepted) {
+          Utils.assert(qApplication.status.__typename === 'ApplicationStatusAccepted', 'Invalid application status')
+          console.log('qApplication.status', qApplication.status)
+          // FIXME: Missing due to Hydra bug now
+          // Utils.assert(qApplication.status.openingFilledEvent, 'Query node: Missing openingFilledEvent relation')
+          // assert.equal(qApplication.status.openingFilledEvent.id, qEvent.id)
+        } else {
+          assert.oneOf(qApplication.status.__typename, ['ApplicationStatusRejected', 'ApplicationStatusWithdrawn'])
+          if (qApplication.status.__typename === 'ApplicationStatusRejected') {
+            // FIXME: Missing due to Hydra bug now
+            // Utils.assert(qApplication.status.openingFilledEvent, 'Query node: Missing openingFilledEvent relation')
+            // assert.equal(qApplication.status.openingFilledEvent.id, qEvent.id)
+          }
+        }
+      })
+    })
+  }
+
+  protected assertQueryNodeLeaderSetEventIsValid(
+    eventDetails: EventDetails,
+    qEvent: LeaderSetEventFieldsFragment | null,
+    workerRuntimeId: number
+  ): void {
+    Utils.assert(qEvent, 'Query node: LeaderSet not found!')
+    assert.equal(new Date(qEvent.createdAt).getTime(), eventDetails.blockTimestamp)
+    assert.equal(qEvent.inExtrinsic, this.extrinsics[0].hash.toString())
+    assert.equal(qEvent.group.name, this.group)
+    Utils.assert(qEvent.worker, 'LeaderSet: Worker is empty')
+    assert.equal(qEvent.worker.runtimeId, workerRuntimeId)
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    // Query the event and check event + hiredWorkers
+    const qEvents = await this.query.tryQueryWithTimeout(
+      () => this.query.getOpeningFilledEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+
+    // Check openings statuses
+    const qOpenings = await this.query.getOpeningsByIds(this.openingIds, this.group)
+    this.assertOpeningsStatusesAreValid(qEvents, qOpenings)
+
+    // Check application statuses
+    this.assertApplicationStatusesAreValid(qEvents, qOpenings)
+
+    if (this.asSudo) {
+      const leaderId = qEvents[0].workersHired[0].runtimeId
+      assert.isNumber(leaderId)
+
+      const qGroup = await this.query.getWorkingGroup(this.group)
+      Utils.assert(qGroup, 'Query node: Working group not found!')
+      Utils.assert(qGroup.leader, 'Query node: Working group leader not set!')
+      assert.equal(qGroup.leader.runtimeId, leaderId)
+
+      const leaderSetEvent = await this.api.retrieveWorkingGroupsEventDetails(this.results[0], this.group, 'LeaderSet')
+      const qEvent = await this.query.getLeaderSetEvent(leaderSetEvent)
+      this.assertQueryNodeLeaderSetEventIsValid(leaderSetEvent, qEvent, leaderId)
+    }
+  }
+}

+ 96 - 0
tests/integration-tests/src/fixtures/workingGroups/HireWorkersFixture.ts

@@ -0,0 +1,96 @@
+import { WorkerId } from '@joystream/types/working-group'
+import { Api } from '../../Api'
+import { LEADER_OPENING_STAKE } from '../../consts'
+import { BaseQueryNodeFixture, FixtureRunner } from '../../Fixture'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { WorkingGroupModuleName } from '../../types'
+import { Utils } from '../../utils'
+import { AddStakingAccountsHappyCaseFixture, BuyMembershipHappyCaseFixture } from '../membership'
+import { ApplicantDetails, ApplyOnOpeningsHappyCaseFixture } from './ApplyOnOpeningsHappyCaseFixture'
+import { CreateOpeningsFixture, DEFAULT_OPENING_PARAMS } from './CreateOpeningsFixture'
+import { FillOpeningsFixture } from './FillOpeningsFixture'
+
+export class HireWorkersFixture extends BaseQueryNodeFixture {
+  protected group: WorkingGroupModuleName
+  protected workersN: number
+  protected createdWorkerIds: WorkerId[] = []
+
+  protected fillOpeningRunner?: FixtureRunner
+
+  constructor(api: Api, query: QueryNodeApi, group: WorkingGroupModuleName, workersN: number) {
+    super(api, query)
+    this.group = group
+    this.workersN = workersN
+  }
+
+  public getCreatedWorkerIds(): WorkerId[] {
+    Utils.assert(this.createdWorkerIds.length, 'Trying to get created workers before they were created!')
+    return this.createdWorkerIds
+  }
+
+  public async execute(): Promise<void> {
+    // Transfer funds to leader staking account to cover opening stake
+    const leaderStakingAcc = await this.api.getLeaderStakingKey(this.group)
+    await this.api.treasuryTransferBalance(leaderStakingAcc, LEADER_OPENING_STAKE)
+
+    // Create an opening
+    const createOpeningFixture = new CreateOpeningsFixture(this.api, this.query, this.group)
+    const openingRunner = new FixtureRunner(createOpeningFixture)
+    await openingRunner.run()
+    const [openingId] = createOpeningFixture.getCreatedOpeningIds()
+    const { stake: openingStake, metadata: openingMetadata } = DEFAULT_OPENING_PARAMS
+
+    // Create the applications
+    const roleAccounts = (await this.api.createKeyPairs(this.workersN)).map((kp) => kp.address)
+    const stakingAccounts = (await this.api.createKeyPairs(this.workersN)).map((kp) => kp.address)
+    const rewardAccounts = (await this.api.createKeyPairs(this.workersN)).map((kp) => kp.address)
+
+    const buyMembershipFixture = new BuyMembershipHappyCaseFixture(this.api, this.query, roleAccounts)
+    await new FixtureRunner(buyMembershipFixture).run()
+    const memberIds = buyMembershipFixture.getCreatedMembers()
+
+    const applicantContexts = roleAccounts.map((account, i) => ({
+      account,
+      memberId: memberIds[i],
+    }))
+
+    await Promise.all(
+      applicantContexts.map((applicantContext, i) => {
+        const addStakingAccFixture = new AddStakingAccountsHappyCaseFixture(this.api, this.query, applicantContext, [
+          stakingAccounts[i],
+        ])
+        return new FixtureRunner(addStakingAccFixture).run()
+      })
+    )
+    await Promise.all(stakingAccounts.map((a) => this.api.treasuryTransferBalance(a, openingStake)))
+
+    const applicants: ApplicantDetails[] = memberIds.map((memberId, i) => ({
+      memberId,
+      roleAccount: roleAccounts[i],
+      stakingAccount: stakingAccounts[i],
+      rewardAccount: rewardAccounts[i],
+    }))
+    const applyOnOpeningFixture = new ApplyOnOpeningsHappyCaseFixture(this.api, this.query, this.group, [
+      {
+        openingId,
+        openingMetadata,
+        applicants,
+      },
+    ])
+    const applyRunner = new FixtureRunner(applyOnOpeningFixture)
+    await applyRunner.run()
+    const applicationIds = await applyOnOpeningFixture.getCreatedApplicationsByOpeningId(openingId)
+
+    // Fill the opening
+    const fillOpeningFixture = new FillOpeningsFixture(this.api, this.query, this.group, [openingId], [applicationIds])
+    const fillOpeningRunner = new FixtureRunner(fillOpeningFixture)
+    await fillOpeningRunner.run()
+
+    this.createdWorkerIds = fillOpeningFixture.getCreatedWorkerIdsByOpeningId(openingId)
+  }
+
+  public async runQueryNodeChecks(): Promise<void> {
+    Utils.assert(this.fillOpeningRunner)
+    await this.fillOpeningRunner.runQueryNodeChecks()
+  }
+}

+ 79 - 0
tests/integration-tests/src/fixtures/workingGroups/IncreaseWorkerStakesFixture.ts

@@ -0,0 +1,79 @@
+import BN from 'bn.js'
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { WorkerId, Worker } from '@joystream/types/working-group'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+import { lockIdByWorkingGroup } from '../../consts'
+import { StakeIncreasedEventFieldsFragment, WorkerFieldsFragment } from '../../graphql/generated/queries'
+
+export class IncreaseWorkerStakesFixture extends BaseWorkingGroupFixture {
+  protected workerIds: WorkerId[]
+  protected stakeIncreases: BN[]
+
+  protected workers: Worker[] = []
+  protected workerStakes: BN[] = []
+
+  public constructor(
+    api: Api,
+    query: QueryNodeApi,
+    group: WorkingGroupModuleName,
+    workerIds: WorkerId[],
+    stakeIncreases: BN[]
+  ) {
+    super(api, query, group)
+    this.workerIds = workerIds
+    this.stakeIncreases = stakeIncreases
+  }
+
+  protected async loadWorkersData(): Promise<void> {
+    this.workers = await this.api.query[this.group].workerById.multi<Worker>(this.workerIds)
+    this.workerStakes = await Promise.all(
+      this.workers.map((w) => this.api.getStakedBalance(w.staking_account_id, lockIdByWorkingGroup[this.group]))
+    )
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string[]> {
+    await this.loadWorkersData()
+    return this.workers.map((w) => w.role_account_id.toString())
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    return this.workerIds.map((workerId, i) => this.api.tx[this.group].increaseStake(workerId, this.stakeIncreases[i]))
+  }
+
+  protected getEventFromResult(result: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(result, this.group, 'StakeIncreased')
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: StakeIncreasedEventFieldsFragment, i: number): void {
+    assert.equal(qEvent.worker.runtimeId, this.workerIds[i].toNumber())
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.amount, this.stakeIncreases[i].toString())
+  }
+
+  protected assertQueriedWorkersAreValid(qWorkers: WorkerFieldsFragment[]): void {
+    this.workerIds.map((workerId, i) => {
+      const worker = qWorkers.find((w) => w.runtimeId === workerId.toNumber())
+      Utils.assert(worker, 'Query node: Worker not found!')
+      assert.equal(worker.stake, this.workerStakes[i].add(this.stakeIncreases[i]).toString())
+    })
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    // Query and check the events
+    await this.query.tryQueryWithTimeout(
+      () => this.query.getStakeIncreasedEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+
+    // Check the workers
+    const qWorkers = await this.query.getWorkersByIds(this.workerIds, this.group)
+    this.assertQueriedWorkersAreValid(qWorkers)
+  }
+}

+ 79 - 0
tests/integration-tests/src/fixtures/workingGroups/LeaveRoleFixture.ts

@@ -0,0 +1,79 @@
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { WorkerId, Worker } from '@joystream/types/working-group'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+import { WorkerFieldsFragment, WorkerStartedLeavingEventFieldsFragment } from '../../graphql/generated/queries'
+
+export class LeaveRoleFixture extends BaseWorkingGroupFixture {
+  protected workerIds: WorkerId[] = []
+
+  protected workers: Worker[] = []
+
+  public constructor(api: Api, query: QueryNodeApi, group: WorkingGroupModuleName, workerIds: WorkerId[]) {
+    super(api, query, group)
+    this.workerIds = workerIds
+  }
+
+  protected async loadWorkersData(): Promise<void> {
+    this.workers = await this.api.query[this.group].workerById.multi<Worker>(this.workerIds)
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string[]> {
+    await this.loadWorkersData()
+    return this.workers.map((w) => w.role_account_id.toString())
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    return this.workerIds.map((workerId) => this.api.tx[this.group].leaveRole(workerId, this.getRationale(workerId)))
+  }
+
+  protected getEventFromResult(result: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(result, this.group, 'WorkerStartedLeaving')
+  }
+
+  protected getRationale(workerId: WorkerId): string {
+    return `Worker ${workerId.toString()} leaving rationale`
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: WorkerStartedLeavingEventFieldsFragment, i: number): void {
+    assert.equal(qEvent.worker.runtimeId, this.workerIds[i].toNumber())
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.rationale, this.getRationale(this.workerIds[i]))
+  }
+
+  protected assertQueriedWorkersAreValid(
+    qEvents: WorkerStartedLeavingEventFieldsFragment[],
+    qWorkers: WorkerFieldsFragment[]
+  ): void {
+    this.events.map((e, i) => {
+      const qEvent = this.findMatchingQueryNodeEvent(e, qEvents)
+      const workerId = this.workerIds[i]
+      const worker = qWorkers.find((w) => w.runtimeId === workerId.toNumber())
+      Utils.assert(worker, 'Query node: Worker not found!')
+      Utils.assert(
+        worker.status.__typename === 'WorkerStatusLeft',
+        `Invalid worker status: ${worker.status.__typename}`
+      )
+      Utils.assert(worker.status.workerStartedLeavingEvent, 'Query node: Missing workerStartedLeavingEvent relation')
+      assert.equal(worker.status.workerStartedLeavingEvent.id, qEvent.id)
+    })
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    // Query and check the events
+    const qEvents = await this.query.tryQueryWithTimeout(
+      () => this.query.getWorkerStartedLeavingEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+
+    // Check the worker
+    const qWorkers = await this.query.getWorkersByIds(this.workerIds, this.group)
+    this.assertQueriedWorkersAreValid(qEvents, qWorkers)
+  }
+}

+ 65 - 0
tests/integration-tests/src/fixtures/workingGroups/RemoveUpcomingOpeningsFixture.ts

@@ -0,0 +1,65 @@
+import { Api } from '../../Api'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { Utils } from '../../utils'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { StatusTextChangedEventFieldsFragment } from '../../graphql/generated/queries'
+import { assert } from 'chai'
+import { WorkingGroupMetadataAction } from '@joystream/metadata-protobuf'
+import { Bytes } from '@polkadot/types'
+
+export class RemoveUpcomingOpeningsFixture extends BaseWorkingGroupFixture {
+  protected upcomingOpeningIds: string[]
+
+  public constructor(api: Api, query: QueryNodeApi, group: WorkingGroupModuleName, upcomingOpeningIds: string[]) {
+    super(api, query, group)
+    this.upcomingOpeningIds = upcomingOpeningIds
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string> {
+    return this.api.getLeadRoleKey(this.group)
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    return this.upcomingOpeningIds.map((id) => {
+      return this.api.tx[this.group].setStatusText(this.getActionMetadataBytes(id))
+    })
+  }
+
+  protected async getEventFromResult(result: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(result, this.group, 'StatusTextChanged')
+  }
+
+  protected getActionMetadataBytes(upcomingOpeningId: string): Bytes {
+    return Utils.metadataToBytes(WorkingGroupMetadataAction, {
+      removeUpcomingOpening: {
+        id: upcomingOpeningId,
+      },
+    })
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: StatusTextChangedEventFieldsFragment, i: number): void {
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.metadata, this.getActionMetadataBytes(this.upcomingOpeningIds[i]).toString())
+    Utils.assert(qEvent.result.__typename === 'UpcomingOpeningRemoved', 'Unexpected StatuxTextChangedEvent result type')
+    assert.equal(qEvent.result.upcomingOpeningId, this.upcomingOpeningIds[i])
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    // Query & check the event
+    await this.query.tryQueryWithTimeout(
+      () => this.query.getStatusTextChangedEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+    // Query the openings and make sure they no longer exist
+    await Promise.all(
+      this.upcomingOpeningIds.map(async (id) => {
+        const qUpcomingOpening = await this.query.getUpcomingOpeningById(id)
+        assert.isNull(qUpcomingOpening)
+      })
+    )
+  }
+}

+ 56 - 0
tests/integration-tests/src/fixtures/workingGroups/SetBudgetFixture.ts

@@ -0,0 +1,56 @@
+import BN from 'bn.js'
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+import { BudgetSetEventFieldsFragment, WorkingGroupFieldsFragment } from '../../graphql/generated/queries'
+
+export class SetBudgetFixture extends BaseWorkingGroupFixture {
+  protected budgets: BN[]
+
+  public constructor(api: Api, query: QueryNodeApi, group: WorkingGroupModuleName, budgets: BN[]) {
+    super(api, query, group)
+    this.budgets = budgets
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string> {
+    return (await this.api.query.sudo.key()).toString()
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    const extrinsics = this.budgets.map((budget) => this.api.tx[this.group].setBudget(budget))
+    return extrinsics.map((tx) => this.api.tx.sudo.sudo(tx))
+  }
+
+  protected getEventFromResult(result: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(result, this.group, 'BudgetSet')
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: BudgetSetEventFieldsFragment, i: number): void {
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.newBudget, this.budgets[i].toString())
+  }
+
+  protected assertQueriedGroupIsValid(qGroup: WorkingGroupFieldsFragment | null): void {
+    Utils.assert(qGroup, 'Query node: Working group not found!')
+    assert.equal(qGroup.budget, this.budgets[this.budgets.length - 1].toString())
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+
+    // Query and check the events
+    await this.query.tryQueryWithTimeout(
+      () => this.query.getBudgetSetEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+
+    // Check the group
+    const qGroup = await this.query.getWorkingGroup(this.group)
+    this.assertQueriedGroupIsValid(qGroup)
+  }
+}

+ 105 - 0
tests/integration-tests/src/fixtures/workingGroups/SlashWorkerStakesFixture.ts

@@ -0,0 +1,105 @@
+import BN from 'bn.js'
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { Worker, WorkerId } from '@joystream/types/working-group'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+import { lockIdByWorkingGroup } from '../../consts'
+import { StakeSlashedEventFieldsFragment, WorkerFieldsFragment } from '../../graphql/generated/queries'
+
+export class SlashWorkerStakesFixture extends BaseWorkingGroupFixture {
+  protected asSudo: boolean
+
+  protected workerIds: WorkerId[]
+  protected penalties: BN[]
+  protected workers: Worker[] = []
+  protected workerStakes: BN[] = []
+
+  public constructor(
+    api: Api,
+    query: QueryNodeApi,
+    group: WorkingGroupModuleName,
+    workerIds: WorkerId[],
+    penalties: BN[],
+    asSudo = false
+  ) {
+    super(api, query, group)
+    this.workerIds = workerIds
+    this.penalties = penalties
+    this.asSudo = asSudo
+  }
+
+  protected async loadWorkersData(): Promise<void> {
+    this.workers = await this.api.query[this.group].workerById.multi<Worker>(this.workerIds)
+    this.workerStakes = await Promise.all(
+      this.workers.map((w) => this.api.getStakedBalance(w.staking_account_id, lockIdByWorkingGroup[this.group]))
+    )
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string> {
+    return this.asSudo ? (await this.api.query.sudo.key()).toString() : await this.api.getLeadRoleKey(this.group)
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    const extrinsics = this.workerIds.map((workerId, i) =>
+      this.api.tx[this.group].slashStake(workerId, this.penalties[i], this.getRationale(workerId))
+    )
+    return this.asSudo ? extrinsics.map((tx) => this.api.tx.sudo.sudo(tx)) : extrinsics
+  }
+
+  protected getEventFromResult(result: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(result, this.group, 'StakeSlashed')
+  }
+
+  public async execute(): Promise<void> {
+    await this.loadWorkersData()
+    await super.execute()
+  }
+
+  protected getRationale(workerId: WorkerId): string {
+    return `Worker ${workerId.toString()} slashing rationale`
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: StakeSlashedEventFieldsFragment, i: number): void {
+    assert.equal(qEvent.worker.runtimeId, this.workerIds[i].toNumber())
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.rationale, this.getRationale(this.workerIds[i]))
+    assert.equal(qEvent.requestedAmount, this.penalties[i].toString())
+    assert.equal(qEvent.slashedAmount, BN.min(this.penalties[i], this.workerStakes[i]))
+  }
+
+  protected assertQueriedWorkersAreValid(
+    qEvents: StakeSlashedEventFieldsFragment[],
+    qWorkers: WorkerFieldsFragment[]
+  ): void {
+    this.events.map((e, i) => {
+      const qEvent = this.findMatchingQueryNodeEvent(e, qEvents)
+      const workerId = this.workerIds[i]
+      const worker = qWorkers.find((w) => w.runtimeId === workerId.toNumber())
+      Utils.assert(worker, 'Query node: Worker not found!')
+      assert.equal(worker.stake, BN.max(this.workerStakes[i].sub(this.penalties[i]), new BN(0)).toString())
+      assert.include(
+        worker.slashes.map((e) => e.id),
+        qEvent.id
+      )
+    })
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+
+    // Query and check the events
+    const qEvents = await this.query.tryQueryWithTimeout(
+      () => this.query.getStakeSlashedEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+
+    // Check workers
+    const qWorkers = await this.query.getWorkersByIds(this.workerIds, this.group)
+    this.assertQueriedWorkersAreValid(qEvents, qWorkers)
+  }
+}

+ 71 - 0
tests/integration-tests/src/fixtures/workingGroups/SpendBudgetFixture.ts

@@ -0,0 +1,71 @@
+import BN from 'bn.js'
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+import { BudgetSpendingEventFieldsFragment, WorkingGroupFieldsFragment } from '../../graphql/generated/queries'
+
+export class SpendBudgetFixture extends BaseWorkingGroupFixture {
+  protected recievers: string[]
+  protected amounts: BN[]
+  protected preExecuteBudget?: BN
+
+  public constructor(api: Api, query: QueryNodeApi, group: WorkingGroupModuleName, recievers: string[], amounts: BN[]) {
+    super(api, query, group)
+    this.recievers = recievers
+    this.amounts = amounts
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string> {
+    return this.api.getLeadRoleKey(this.group)
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    return this.recievers.map((reciever, i) =>
+      this.api.tx[this.group].spendFromBudget(reciever, this.amounts[i], this.getRationale(reciever))
+    )
+  }
+
+  protected getEventFromResult(result: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(result, this.group, 'BudgetSpending')
+  }
+
+  protected getRationale(reciever: string): string {
+    return `Budget spending to ${reciever} rationale`
+  }
+
+  public async execute(): Promise<void> {
+    this.preExecuteBudget = await this.api.query[this.group].budget()
+    await super.execute()
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: BudgetSpendingEventFieldsFragment, i: number): void {
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.amount, this.amounts[i].toString())
+    assert.equal(qEvent.reciever, this.recievers[i])
+    assert.equal(qEvent.rationale, this.getRationale(this.recievers[i]))
+  }
+
+  protected assertQueriedGroupIsValid(qGroup: WorkingGroupFieldsFragment | null): void {
+    Utils.assert(qGroup, 'Query node: Working group not found!')
+    assert.equal(qGroup.budget, this.preExecuteBudget!.sub(this.amounts.reduce((a, b) => a.add(b), new BN(0))))
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+
+    // Query and check the events
+    await this.query.tryQueryWithTimeout(
+      () => this.query.getBudgetSpendingEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+
+    // Check the group
+    const qGroup = await this.query.getWorkingGroup(this.group)
+    this.assertQueriedGroupIsValid(qGroup)
+  }
+}

+ 145 - 0
tests/integration-tests/src/fixtures/workingGroups/TerminateWorkersFixture.ts

@@ -0,0 +1,145 @@
+import BN from 'bn.js'
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { Worker, WorkerId } from '@joystream/types/working-group'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+import { lockIdByWorkingGroup } from '../../consts'
+import {
+  LeaderUnsetEventFieldsFragment,
+  TerminatedLeaderEventFieldsFragment,
+  TerminatedWorkerEventFieldsFragment,
+  WorkerFieldsFragment,
+} from '../../graphql/generated/queries'
+
+export class TerminateWorkersFixture extends BaseWorkingGroupFixture {
+  protected asSudo: boolean
+
+  protected workerIds: WorkerId[]
+  protected penalties: BN[]
+  protected workers: Worker[] = []
+  protected workerStakes: BN[] = []
+
+  public constructor(
+    api: Api,
+    query: QueryNodeApi,
+    group: WorkingGroupModuleName,
+    workerIds: WorkerId[],
+    penalties: BN[],
+    asSudo = false
+  ) {
+    super(api, query, group)
+    this.workerIds = workerIds
+    this.penalties = penalties
+    this.asSudo = asSudo
+  }
+
+  protected async loadWorkersData(): Promise<void> {
+    this.workers = await this.api.query[this.group].workerById.multi<Worker>(this.workerIds)
+    this.workerStakes = await Promise.all(
+      this.workers.map((w) => this.api.getStakedBalance(w.staking_account_id, lockIdByWorkingGroup[this.group]))
+    )
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string> {
+    return this.asSudo ? (await this.api.query.sudo.key()).toString() : await this.api.getLeadRoleKey(this.group)
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    const extrinsics = this.workerIds.map((workerId, i) =>
+      this.api.tx[this.group].terminateRole(workerId, this.penalties[i], this.getRationale(workerId))
+    )
+    return this.asSudo ? extrinsics.map((tx) => this.api.tx.sudo.sudo(tx)) : extrinsics
+  }
+
+  protected getEventFromResult(result: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(
+      result,
+      this.group,
+      this.asSudo ? 'TerminatedLeader' : 'TerminatedWorker'
+    )
+  }
+
+  public async execute(): Promise<void> {
+    await this.loadWorkersData()
+    await super.execute()
+  }
+
+  protected getRationale(workerId: WorkerId): string {
+    return `Worker ${workerId.toString()} termination rationale`
+  }
+
+  protected assertQueryNodeEventIsValid(
+    qEvent: TerminatedWorkerEventFieldsFragment | TerminatedLeaderEventFieldsFragment,
+    i: number
+  ): void {
+    assert.equal(qEvent.worker.runtimeId, this.workerIds[i].toNumber())
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.rationale, this.getRationale(this.workerIds[i]))
+    assert.equal(qEvent.penalty, this.penalties[i].toString())
+  }
+
+  protected assertQueriedWorkersAreValid(
+    qEvents: (TerminatedWorkerEventFieldsFragment | TerminatedLeaderEventFieldsFragment)[],
+    qWorkers: WorkerFieldsFragment[]
+  ): void {
+    this.events.map((e, i) => {
+      const qEvent = this.findMatchingQueryNodeEvent(e, qEvents)
+      const workerId = this.workerIds[i]
+      const worker = qWorkers.find((w) => w.runtimeId === workerId.toNumber())
+      Utils.assert(worker, 'Query node: Worker not found!')
+      assert.equal(worker.stake, '0')
+      assert.equal(worker.rewardPerBlock, '0')
+      Utils.assert(
+        worker.status.__typename === 'WorkerStatusTerminated',
+        `Invalid worker status: ${worker.status.__typename}`
+      )
+      Utils.assert(worker.status.terminatedWorkerEvent, 'Query node: Missing terminatedWorkerEvent relation')
+      assert.equal(worker.status.terminatedWorkerEvent.id, qEvent.id)
+    })
+  }
+
+  protected assertQueriedLeaderUnsetEventIsValid(
+    eventDetails: EventDetails,
+    qEvent: LeaderUnsetEventFieldsFragment | null
+  ): void {
+    Utils.assert(qEvent, 'Query node: LeaderUnsetEvent not found!')
+    assert.equal(qEvent.inExtrinsic, this.extrinsics[0].hash.toString())
+    assert.equal(qEvent.inBlock, eventDetails.blockNumber)
+    assert.equal(new Date(qEvent.createdAt).getTime(), eventDetails.blockTimestamp)
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.leader.runtimeId, this.workerIds[0].toNumber())
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+
+    // Query the event and check event + hiredWorkers
+    const qEvents = await this.query.tryQueryWithTimeout(
+      () =>
+        this.asSudo
+          ? this.query.getTerminatedLeaderEvents(this.events)
+          : this.query.getTerminatedWorkerEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+
+    // Check workers
+    const qWorkers = await this.query.getWorkersByIds(this.workerIds, this.group)
+    this.assertQueriedWorkersAreValid(qEvents, qWorkers)
+
+    // If lead - check LeaderUnset event
+    if (this.asSudo) {
+      const leaderUnsetEvent = await this.api.retrieveWorkingGroupsEventDetails(
+        this.results[0],
+        this.group,
+        'LeaderUnset'
+      )
+      const qEvent = await this.query.getLeaderUnsetEvent(leaderUnsetEvent)
+      this.assertQueriedLeaderUnsetEventIsValid(leaderUnsetEvent, qEvent)
+    }
+  }
+}

+ 128 - 0
tests/integration-tests/src/fixtures/workingGroups/UpdateGroupStatusFixture.ts

@@ -0,0 +1,128 @@
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+import { IWorkingGroupMetadata, WorkingGroupMetadataAction } from '@joystream/metadata-protobuf'
+import {
+  StatusTextChangedEventFieldsFragment,
+  WorkingGroupFieldsFragment,
+  WorkingGroupMetadataFieldsFragment,
+} from '../../graphql/generated/queries'
+import _ from 'lodash'
+import { Bytes } from '@polkadot/types'
+
+export class UpdateGroupStatusFixture extends BaseWorkingGroupFixture {
+  protected updates: IWorkingGroupMetadata[]
+  protected areExtrinsicsOrderSensitive = true
+
+  public constructor(api: Api, query: QueryNodeApi, group: WorkingGroupModuleName, updates: IWorkingGroupMetadata[]) {
+    super(api, query, group)
+    this.updates = updates
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string> {
+    return this.api.getLeadRoleKey(this.group)
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    return this.updates.map((update) => {
+      return this.api.tx[this.group].setStatusText(this.getActionMetadataBytes(update))
+    })
+  }
+
+  protected async getEventFromResult(r: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(r, this.group, 'StatusTextChanged')
+  }
+
+  protected getActionMetadataBytes(update: IWorkingGroupMetadata): Bytes {
+    return Utils.metadataToBytes(WorkingGroupMetadataAction, {
+      setGroupMetadata: {
+        newMetadata: update,
+      },
+    })
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: StatusTextChangedEventFieldsFragment, i: number): void {
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.metadata, this.getActionMetadataBytes(this.updates[i]).toString())
+    assert.equal(qEvent.result.__typename, 'WorkingGroupMetadataSet')
+  }
+
+  protected assertQueriedGroupIsValid(
+    qGroup: WorkingGroupFieldsFragment,
+    qMeta: WorkingGroupMetadataFieldsFragment
+  ): void {
+    if (!qGroup.metadata) {
+      throw new Error(`Query node: Group metadata is empty!`)
+    }
+    assert.equal(qGroup.metadata.id, qMeta.id)
+  }
+
+  protected assertQueriedMetadataSnapshotsAreValid(
+    eventDetails: EventDetails,
+    preUpdateSnapshot: WorkingGroupMetadataFieldsFragment | null,
+    postUpdateSnapshot: WorkingGroupMetadataFieldsFragment | null,
+    update: IWorkingGroupMetadata
+  ): asserts postUpdateSnapshot is WorkingGroupMetadataFieldsFragment {
+    if (!postUpdateSnapshot) {
+      throw new Error('Query node: WorkingGroupMetadata snapshot not found!')
+    }
+    const expectedMeta = _.mergeWith(preUpdateSnapshot, update, (destValue, sourceValue) =>
+      sourceValue === null || sourceValue === undefined ? destValue : sourceValue
+    )
+    assert.equal(postUpdateSnapshot.status, expectedMeta.status || null)
+    assert.equal(postUpdateSnapshot.statusMessage, expectedMeta.statusMessage || null)
+    assert.equal(postUpdateSnapshot.description, expectedMeta.description || null)
+    assert.equal(postUpdateSnapshot.about, expectedMeta.about || null)
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    // Query & check the event
+    const qEvents = await this.query.tryQueryWithTimeout(
+      () => this.query.getStatusTextChangedEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+
+    // Query the group
+    const qGroup = await this.query.getWorkingGroup(this.group)
+    if (!qGroup) {
+      throw new Error('Query node: Working group not found!')
+    }
+
+    // Query & check the metadata snapshots
+    const snapshots = await this.query.getGroupMetaSnapshotsByTimeAsc(qGroup.id)
+    let lastSnapshot: WorkingGroupMetadataFieldsFragment | null = null
+    this.events.forEach((postUpdateEvent, i) => {
+      const postUpdateSnapshotIndex = snapshots.findIndex(
+        (s) =>
+          s.setInEvent.id === this.query.getQueryNodeEventId(postUpdateEvent.blockNumber, postUpdateEvent.indexInBlock)
+      )
+      const postUpdateSnapshot = postUpdateSnapshotIndex > -1 ? snapshots[postUpdateSnapshotIndex] : null
+      const preUpdateSnapshot = postUpdateSnapshotIndex > 0 ? snapshots[postUpdateSnapshotIndex - 1] : null
+      this.assertQueriedMetadataSnapshotsAreValid(
+        postUpdateEvent,
+        preUpdateSnapshot,
+        postUpdateSnapshot,
+        this.updates[i]
+      )
+      const qEvent = qEvents[i]
+      Utils.assert(
+        qEvent.result.__typename === 'WorkingGroupMetadataSet',
+        'Invalid StatusTextChanged event result type'
+      )
+      Utils.assert(qEvent.result.metadata, 'Query node: Missing metadata relation')
+      assert(qEvent.result.metadata.id, postUpdateSnapshot.id)
+      lastSnapshot = postUpdateSnapshot
+    })
+
+    // Check the group
+    if (lastSnapshot) {
+      this.assertQueriedGroupIsValid(qGroup, lastSnapshot)
+    }
+  }
+}

+ 76 - 0
tests/integration-tests/src/fixtures/workingGroups/UpdateWorkerRewardAccountsFixture.ts

@@ -0,0 +1,76 @@
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { WorkerId, Worker } from '@joystream/types/working-group'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+import { WorkerFieldsFragment, WorkerRewardAccountUpdatedEventFieldsFragment } from '../../graphql/generated/queries'
+import { AccountId } from '@joystream/types/common'
+
+export class UpdateWorkerRewardAccountsFixture extends BaseWorkingGroupFixture {
+  protected workerIds: WorkerId[] = []
+  protected rewardAccounts: (string | AccountId)[] = []
+
+  protected workers: Worker[] = []
+
+  public constructor(
+    api: Api,
+    query: QueryNodeApi,
+    group: WorkingGroupModuleName,
+    workerIds: WorkerId[],
+    rewardAccounts: (string | AccountId)[]
+  ) {
+    super(api, query, group)
+    this.workerIds = workerIds
+    this.rewardAccounts = rewardAccounts
+  }
+
+  protected async loadWorkersData(): Promise<void> {
+    this.workers = await this.api.query[this.group].workerById.multi<Worker>(this.workerIds)
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string[]> {
+    await this.loadWorkersData()
+    return this.workers.map((w) => w.role_account_id.toString())
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    return this.workerIds.map((workerId, i) =>
+      this.api.tx[this.group].updateRewardAccount(workerId, this.rewardAccounts[i])
+    )
+  }
+
+  protected getEventFromResult(result: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(result, this.group, 'WorkerRewardAccountUpdated')
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: WorkerRewardAccountUpdatedEventFieldsFragment, i: number): void {
+    assert.equal(qEvent.worker.runtimeId, this.workerIds[i].toNumber())
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.newRewardAccount, this.rewardAccounts[i].toString())
+  }
+
+  protected assertQueriedWorkersAreValid(qWorkers: WorkerFieldsFragment[]): void {
+    this.workerIds.map((workerId, i) => {
+      const worker = qWorkers.find((w) => w.runtimeId === workerId.toNumber())
+      Utils.assert(worker, 'Query node: Worker not found!')
+      assert.equal(worker.rewardAccount, this.rewardAccounts[i].toString())
+    })
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    // Query and check the events
+    await this.query.tryQueryWithTimeout(
+      () => this.query.getWorkerRewardAccountUpdatedEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+
+    // Check the worker
+    const qWorkers = await this.query.getWorkersByIds(this.workerIds, this.group)
+    this.assertQueriedWorkersAreValid(qWorkers)
+  }
+}

+ 78 - 0
tests/integration-tests/src/fixtures/workingGroups/UpdateWorkerRewardAmountsFixture.ts

@@ -0,0 +1,78 @@
+import BN from 'bn.js'
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { Worker, WorkerId } from '@joystream/types/working-group'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+import { WorkerFieldsFragment, WorkerRewardAmountUpdatedEventFieldsFragment } from '../../graphql/generated/queries'
+
+export class UpdateWorkerRewardAmountsFixture extends BaseWorkingGroupFixture {
+  protected asSudo: boolean
+
+  protected workerIds: WorkerId[]
+  protected newRewards: (BN | null)[]
+  protected workers: Worker[] = []
+
+  public constructor(
+    api: Api,
+    query: QueryNodeApi,
+    group: WorkingGroupModuleName,
+    workerIds: WorkerId[],
+    newRewards: (BN | null)[],
+    asSudo = false
+  ) {
+    super(api, query, group)
+    this.workerIds = workerIds
+    this.newRewards = newRewards
+    this.asSudo = asSudo
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string> {
+    return this.asSudo ? (await this.api.query.sudo.key()).toString() : await this.api.getLeadRoleKey(this.group)
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    const extrinsics = this.workerIds.map((workerId, i) =>
+      this.api.tx[this.group].updateRewardAmount(workerId, this.newRewards[i])
+    )
+    return this.asSudo ? extrinsics.map((tx) => this.api.tx.sudo.sudo(tx)) : extrinsics
+  }
+
+  protected getEventFromResult(result: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(result, this.group, 'WorkerRewardAmountUpdated')
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: WorkerRewardAmountUpdatedEventFieldsFragment, i: number): void {
+    const newReward = this.newRewards[i]
+    assert.equal(qEvent.worker.runtimeId, this.workerIds[i].toNumber())
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.newRewardPerBlock, newReward ? newReward.toString() : '0')
+  }
+
+  protected assertQueriedWorkersAreValid(qWorkers: WorkerFieldsFragment[]): void {
+    this.workerIds.map((workerId, i) => {
+      const newReward = this.newRewards[i]
+      const worker = qWorkers.find((w) => w.runtimeId === workerId.toNumber())
+      Utils.assert(worker, 'Query node: Worker not found!')
+      assert.equal(worker.rewardPerBlock, newReward ? newReward.toString() : '0')
+    })
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+
+    // Query the event and check event + hiredWorkers
+    await this.query.tryQueryWithTimeout(
+      () => this.query.getWorkerRewardAmountUpdatedEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+
+    // Check workers
+    const qWorkers = await this.query.getWorkersByIds(this.workerIds, this.group)
+    this.assertQueriedWorkersAreValid(qWorkers)
+  }
+}

+ 78 - 0
tests/integration-tests/src/fixtures/workingGroups/UpdateWorkerRoleAccountsFixture.ts

@@ -0,0 +1,78 @@
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { WorkerId, Worker } from '@joystream/types/working-group'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+import { WorkerFieldsFragment, WorkerRoleAccountUpdatedEventFieldsFragment } from '../../graphql/generated/queries'
+import { AccountId } from '@joystream/types/common'
+import { Membership } from '@joystream/types/members'
+
+export class UpdateWorkerRoleAccountsFixture extends BaseWorkingGroupFixture {
+  protected workerIds: WorkerId[] = []
+  protected roleAccounts: (string | AccountId)[] = []
+
+  protected workerMembers: Membership[] = []
+
+  public constructor(
+    api: Api,
+    query: QueryNodeApi,
+    group: WorkingGroupModuleName,
+    workerIds: WorkerId[],
+    roleAccounts: (string | AccountId)[]
+  ) {
+    super(api, query, group)
+    this.workerIds = workerIds
+    this.roleAccounts = roleAccounts
+  }
+
+  protected async loadWorkersData(): Promise<void> {
+    const workers = await this.api.query[this.group].workerById.multi<Worker>(this.workerIds)
+    this.workerMembers = await this.api.query.members.membershipById.multi(workers.map((w) => w.member_id))
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string[]> {
+    await this.loadWorkersData()
+    return this.workerMembers.map((m) => m.controller_account.toString())
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    return this.workerIds.map((workerId, i) =>
+      this.api.tx[this.group].updateRoleAccount(workerId, this.roleAccounts[i])
+    )
+  }
+
+  protected getEventFromResult(result: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(result, this.group, 'WorkerRoleAccountUpdated')
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: WorkerRoleAccountUpdatedEventFieldsFragment, i: number): void {
+    assert.equal(qEvent.worker.runtimeId, this.workerIds[i].toNumber())
+    assert.equal(qEvent.group.name, this.group)
+    assert.equal(qEvent.newRoleAccount, this.roleAccounts[i].toString())
+  }
+
+  protected assertQueriedWorkersAreValid(qWorkers: WorkerFieldsFragment[]): void {
+    this.workerIds.map((workerId, i) => {
+      const worker = qWorkers.find((w) => w.runtimeId === workerId.toNumber())
+      Utils.assert(worker, 'Query node: Worker not found!')
+      assert.equal(worker.roleAccount, this.roleAccounts[i].toString())
+    })
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+    // Query and check the events
+    await this.query.tryQueryWithTimeout(
+      () => this.query.getWorkerRoleAccountUpdatedEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+
+    // Check the worker
+    const qWorkers = await this.query.getWorkersByIds(this.workerIds, this.group)
+    this.assertQueriedWorkersAreValid(qWorkers)
+  }
+}

+ 78 - 0
tests/integration-tests/src/fixtures/workingGroups/WithdrawApplicationsFixture.ts

@@ -0,0 +1,78 @@
+import { assert } from 'chai'
+import { Api } from '../../Api'
+import { QueryNodeApi } from '../../QueryNodeApi'
+import { EventDetails, WorkingGroupModuleName } from '../../types'
+import { BaseWorkingGroupFixture } from './BaseWorkingGroupFixture'
+import { ApplicationId } from '@joystream/types/working-group'
+import { SubmittableExtrinsic } from '@polkadot/api/types'
+import { ISubmittableResult } from '@polkadot/types/types/'
+import { Utils } from '../../utils'
+import { ApplicationFieldsFragment, ApplicationWithdrawnEventFieldsFragment } from '../../graphql/generated/queries'
+
+export class WithdrawApplicationsFixture extends BaseWorkingGroupFixture {
+  protected applicationIds: ApplicationId[]
+  protected accounts: string[]
+
+  public constructor(
+    api: Api,
+    query: QueryNodeApi,
+    group: WorkingGroupModuleName,
+    accounts: string[],
+    applicationIds: ApplicationId[]
+  ) {
+    super(api, query, group)
+    this.accounts = accounts
+    this.applicationIds = applicationIds
+  }
+
+  protected async getSignerAccountOrAccounts(): Promise<string[]> {
+    return this.accounts
+  }
+
+  protected async getExtrinsics(): Promise<SubmittableExtrinsic<'promise'>[]> {
+    return this.applicationIds.map((id) => this.api.tx[this.group].withdrawApplication(id))
+  }
+
+  protected async getEventFromResult(result: ISubmittableResult): Promise<EventDetails> {
+    return this.api.retrieveWorkingGroupsEventDetails(result, this.group, 'ApplicationWithdrawn')
+  }
+
+  protected assertQueryNodeEventIsValid(qEvent: ApplicationWithdrawnEventFieldsFragment, i: number): void {
+    assert.equal(qEvent.application.runtimeId, this.applicationIds[i].toNumber())
+    assert.equal(qEvent.group.name, this.group)
+  }
+
+  protected assertApplicationStatusesAreValid(
+    qEvents: ApplicationWithdrawnEventFieldsFragment[],
+    qApplications: ApplicationFieldsFragment[]
+  ): void {
+    this.events.map((e, i) => {
+      const qEvent = this.findMatchingQueryNodeEvent(e, qEvents)
+      const qApplication = qApplications.find((a) => a.runtimeId === this.applicationIds[i].toNumber())
+      Utils.assert(qApplication, 'Query node: Application not found!')
+      Utils.assert(
+        qApplication.status.__typename === 'ApplicationStatusWithdrawn',
+        'Query node: Invalid application status!'
+      )
+      Utils.assert(
+        qApplication.status.applicationWithdrawnEvent,
+        'Query node: Missing applicationWithdrawnEvent relation'
+      )
+      assert.equal(qApplication.status.applicationWithdrawnEvent.id, qEvent.id)
+    })
+  }
+
+  async runQueryNodeChecks(): Promise<void> {
+    await super.runQueryNodeChecks()
+
+    // Query the evens
+    const qEvents = await this.query.tryQueryWithTimeout(
+      () => this.query.getApplicationWithdrawnEvents(this.events),
+      (qEvents) => this.assertQueryNodeEventsAreValid(qEvents)
+    )
+
+    // Check application statuses
+    const qApplciations = await this.query.getApplicationsByIds(this.applicationIds, this.group)
+    this.assertApplicationStatusesAreValid(qEvents, qApplciations)
+  }
+}

+ 16 - 0
tests/integration-tests/src/fixtures/workingGroups/index.ts

@@ -0,0 +1,16 @@
+export {
+  ApplyOnOpeningsHappyCaseFixture,
+  ApplicantDetails,
+  OpeningApplications,
+} from './ApplyOnOpeningsHappyCaseFixture'
+export { CancelOpeningsFixture } from './CancelOpeningsFixture'
+export { DEFAULT_OPENING_PARAMS, OpeningParams, CreateOpeningsFixture } from './CreateOpeningsFixture'
+export {
+  DEFAULT_UPCOMING_OPENING_META,
+  UpcomingOpeningParams,
+  CreateUpcomingOpeningsFixture,
+} from './CreateUpcomingOpeningsFixture'
+export { FillOpeningsFixture } from './FillOpeningsFixture'
+export { RemoveUpcomingOpeningsFixture } from './RemoveUpcomingOpeningsFixture'
+export { UpdateGroupStatusFixture } from './UpdateGroupStatusFixture'
+export { WithdrawApplicationsFixture } from './WithdrawApplicationsFixture'

+ 12 - 0
tests/integration-tests/src/fixtures/workingGroups/utils.ts

@@ -0,0 +1,12 @@
+import { OpeningMetadata } from '@joystream/metadata-protobuf'
+import { ApplicationFormQuestionType } from '../../graphql/generated/schema'
+
+export const queryNodeQuestionTypeToMetadataQuestionType = (
+  type: ApplicationFormQuestionType
+): OpeningMetadata.ApplicationFormQuestion.InputType => {
+  if (type === ApplicationFormQuestionType.Text) {
+    return OpeningMetadata.ApplicationFormQuestion.InputType.TEXT
+  }
+
+  return OpeningMetadata.ApplicationFormQuestion.InputType.TEXTAREA
+}

+ 5 - 8
tests/integration-tests/src/flows/membership/creatingMemberships.ts

@@ -1,14 +1,11 @@
 import { FlowProps } from '../../Flow'
-import {
-  BuyMembershipHappyCaseFixture,
-  BuyMembershipWithInsufficienFundsFixture,
-} from '../../fixtures/membershipModule'
+import { BuyMembershipHappyCaseFixture, BuyMembershipWithInsufficienFundsFixture } from '../../fixtures/membership'
 
 import Debugger from 'debug'
 import { FixtureRunner } from '../../Fixture'
 import { assert } from 'chai'
 
-export default async function membershipCreation({ api, query, env }: FlowProps): Promise<void> {
+export default async function creatingMemberships({ api, query, env }: FlowProps): Promise<void> {
   const debug = Debugger('flow:creating-members')
   debug('Started')
   api.enableDebugTxLogs()
@@ -17,12 +14,12 @@ export default async function membershipCreation({ api, query, env }: FlowProps)
   assert(N > 0)
 
   // Assert membership can be bought if sufficient funds are available
-  const nAccounts = api.createKeyPairs(N).map((key) => key.address)
+  const nAccounts = (await api.createKeyPairs(N)).map((key) => key.address)
   const happyCaseFixture = new BuyMembershipHappyCaseFixture(api, query, nAccounts)
-  await new FixtureRunner(happyCaseFixture).run()
+  await new FixtureRunner(happyCaseFixture).runWithQueryNodeChecks()
 
   // Assert account can not buy the membership with insufficient funds
-  const aAccount = api.createKeyPairs(1)[0].address
+  const aAccount = (await api.createKeyPairs(1))[0].address
   const insufficientFundsFixture = new BuyMembershipWithInsufficienFundsFixture(api, aAccount)
   await new FixtureRunner(insufficientFundsFixture).run()
 

+ 5 - 5
tests/integration-tests/src/flows/membership/invitingMembers.ts

@@ -1,11 +1,11 @@
 import { FlowProps } from '../../Flow'
-import { BuyMembershipHappyCaseFixture, InviteMembersHappyCaseFixture } from '../../fixtures/membershipModule'
+import { BuyMembershipHappyCaseFixture, InviteMembersHappyCaseFixture } from '../../fixtures/membership'
 
 import Debugger from 'debug'
 import { FixtureRunner } from '../../Fixture'
 import { assert } from 'chai'
 
-export default async function membershipCreation({ api, query, env }: FlowProps): Promise<void> {
+export default async function invitingMembers({ api, query, env }: FlowProps): Promise<void> {
   const debug = Debugger('flow:inviting-members')
   debug('Started')
   api.enableDebugTxLogs()
@@ -13,19 +13,19 @@ export default async function membershipCreation({ api, query, env }: FlowProps)
   const N: number = +env.MEMBERS_INVITE_N!
   assert(N > 0)
 
-  const [inviterAcc] = api.createKeyPairs(1).map((key) => key.address)
+  const [inviterAcc] = (await api.createKeyPairs(1)).map((key) => key.address)
   const buyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(api, query, [inviterAcc])
   await new FixtureRunner(buyMembershipHappyCaseFixture).run()
   const [inviterMemberId] = buyMembershipHappyCaseFixture.getCreatedMembers()
 
-  const inviteesAccs = api.createKeyPairs(N).map((key) => key.address)
+  const inviteesAccs = (await api.createKeyPairs(N)).map((key) => key.address)
   const inviteMembersHappyCaseFixture = new InviteMembersHappyCaseFixture(
     api,
     query,
     { account: inviterAcc, memberId: inviterMemberId },
     inviteesAccs
   )
-  await new FixtureRunner(inviteMembersHappyCaseFixture).run()
+  await new FixtureRunner(inviteMembersHappyCaseFixture).runWithQueryNodeChecks()
 
   debug('Done')
 }

+ 6 - 6
tests/integration-tests/src/flows/membership/managingStakingAccounts.ts

@@ -3,18 +3,18 @@ import {
   AddStakingAccountsHappyCaseFixture,
   BuyMembershipHappyCaseFixture,
   RemoveStakingAccountsHappyCaseFixture,
-} from '../../fixtures/membershipModule'
+} from '../../fixtures/membership'
 
 import Debugger from 'debug'
 import { FixtureRunner } from '../../Fixture'
 import { assert } from 'chai'
 
-export default async function membershipCreation({ api, query, env }: FlowProps): Promise<void> {
+export default async function managingStakingAccounts({ api, query, env }: FlowProps): Promise<void> {
   const debug = Debugger('flow:adding-staking-accounts')
   debug('Started')
   api.enableDebugTxLogs()
 
-  const [account] = api.createKeyPairs(1).map((key) => key.address)
+  const [account] = (await api.createKeyPairs(1)).map((key) => key.address)
   const buyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(api, query, [account])
   await new FixtureRunner(buyMembershipHappyCaseFixture).run()
   const [memberId] = buyMembershipHappyCaseFixture.getCreatedMembers()
@@ -22,14 +22,14 @@ export default async function membershipCreation({ api, query, env }: FlowProps)
   const N: number = +env.STAKING_ACCOUNTS_ADD_N!
   assert(N > 0)
 
-  const stakingAccounts = api.createKeyPairs(N).map((k) => k.address)
+  const stakingAccounts = (await api.createKeyPairs(N)).map((k) => k.address)
   const addStakingAccountsHappyCaseFixture = new AddStakingAccountsHappyCaseFixture(
     api,
     query,
     { account, memberId },
     stakingAccounts
   )
-  await new FixtureRunner(addStakingAccountsHappyCaseFixture).run()
+  await new FixtureRunner(addStakingAccountsHappyCaseFixture).runWithQueryNodeChecks()
 
   const removeStakingAccountsHappyCaseFixture = new RemoveStakingAccountsHappyCaseFixture(
     api,
@@ -37,7 +37,7 @@ export default async function membershipCreation({ api, query, env }: FlowProps)
     { account, memberId },
     stakingAccounts
   )
-  await new FixtureRunner(removeStakingAccountsHappyCaseFixture).run()
+  await new FixtureRunner(removeStakingAccountsHappyCaseFixture).runWithQueryNodeChecks()
 
   debug('Done')
 }

+ 42 - 0
tests/integration-tests/src/flows/membership/membershipSystem.ts

@@ -0,0 +1,42 @@
+import { FlowProps } from '../../Flow'
+import { SudoUpdateMembershipSystem } from '../../fixtures/membership'
+
+import Debugger from 'debug'
+import { FixtureRunner } from '../../Fixture'
+import BN from 'bn.js'
+
+export default async function membershipSystem({ api, query, env }: FlowProps): Promise<void> {
+  const debug = Debugger('flow:membership-system')
+  debug('Started')
+  api.enableDebugTxLogs()
+
+  const updates = [
+    {
+      defaultInviteCount: 10,
+      membershipPrice: new BN(1000),
+      referralCut: 5,
+      invitedInitialBalance: new BN(500),
+    },
+    {
+      defaultInviteCount: 5,
+      membershipPrice: new BN(500),
+    },
+    {
+      referralCut: 0,
+      invitedInitialBalance: new BN(100),
+    },
+  ]
+
+  const fixtures = updates.map((u) => new SudoUpdateMembershipSystem(api, query, u))
+  const runners = fixtures.map((f) => new FixtureRunner(f))
+  // Fixtures should be executed one-by-one to not interfere with each other (before->after snapshot checks)
+  for (const key in runners) {
+    debug(`Running update fixture number ${parseInt(key) + 1}`)
+    await runners[key].run()
+  }
+
+  debug('Running query node checks')
+  await Promise.all(runners.map((r) => r.runQueryNodeChecks()))
+
+  debug('Done')
+}

+ 4 - 4
tests/integration-tests/src/flows/membership/transferringInvites.ts

@@ -1,15 +1,15 @@
 import { FlowProps } from '../../Flow'
-import { BuyMembershipHappyCaseFixture, TransferInvitesHappyCaseFixture } from '../../fixtures/membershipModule'
+import { BuyMembershipHappyCaseFixture, TransferInvitesHappyCaseFixture } from '../../fixtures/membership'
 
 import Debugger from 'debug'
 import { FixtureRunner } from '../../Fixture'
 
-export default async function membershipCreation({ api, query, env }: FlowProps): Promise<void> {
+export default async function transferringInvites({ api, query, env }: FlowProps): Promise<void> {
   const debug = Debugger('flow:transferring-invites')
   debug('Started')
   api.enableDebugTxLogs()
 
-  const [fromAcc, toAcc] = api.createKeyPairs(2).map((key) => key.address)
+  const [fromAcc, toAcc] = (await api.createKeyPairs(2)).map((key) => key.address)
   const buyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(api, query, [fromAcc, toAcc])
   await new FixtureRunner(buyMembershipHappyCaseFixture).run()
   const [fromMemberId, toMemberId] = buyMembershipHappyCaseFixture.getCreatedMembers()
@@ -20,7 +20,7 @@ export default async function membershipCreation({ api, query, env }: FlowProps)
     { memberId: fromMemberId, account: fromAcc },
     { memberId: toMemberId, account: toAcc }
   )
-  await new FixtureRunner(transferInvitesHappyCaseFixture).run()
+  await new FixtureRunner(transferInvitesHappyCaseFixture).runWithQueryNodeChecks()
 
   debug('Done')
 }

+ 15 - 8
tests/integration-tests/src/flows/membership/updatingAccounts.ts

@@ -1,23 +1,30 @@
 import { FlowProps } from '../../Flow'
-import { BuyMembershipHappyCaseFixture, UpdateAccountsHappyCaseFixture } from '../../fixtures/membershipModule'
+import { BuyMembershipHappyCaseFixture, UpdateAccountsHappyCaseFixture } from '../../fixtures/membership'
 
 import Debugger from 'debug'
 import { FixtureRunner } from '../../Fixture'
 
-export default async function profileUpdate({ api, query }: FlowProps): Promise<void> {
+export default async function updatingAccounts({ api, query }: FlowProps): Promise<void> {
   const debug = Debugger('flow:member-accounts-update')
   debug('Started')
   api.enableDebugTxLogs()
 
-  const [account] = api.createKeyPairs(1).map((key) => key.address)
+  const [account] = (await api.createKeyPairs(1)).map((key) => key.address)
   const buyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(api, query, [account])
   await new FixtureRunner(buyMembershipHappyCaseFixture).run()
   const [memberId] = buyMembershipHappyCaseFixture.getCreatedMembers()
-  const updateAccountsHappyCaseFixture = new UpdateAccountsHappyCaseFixture(api, query, {
-    account,
-    memberId,
-  })
-  await new FixtureRunner(updateAccountsHappyCaseFixture).run()
+  const [newRootAccount, newControllerAccount] = (await api.createKeyPairs(2)).map((key) => key.address)
+  const updateAccountsHappyCaseFixture = new UpdateAccountsHappyCaseFixture(
+    api,
+    query,
+    {
+      account,
+      memberId,
+    },
+    newRootAccount,
+    newControllerAccount
+  )
+  await new FixtureRunner(updateAccountsHappyCaseFixture).runWithQueryNodeChecks()
 
   debug('Done')
 }

+ 4 - 4
tests/integration-tests/src/flows/membership/updatingProfile.ts

@@ -1,15 +1,15 @@
 import { FlowProps } from '../../Flow'
-import { BuyMembershipHappyCaseFixture, UpdateProfileHappyCaseFixture } from '../../fixtures/membershipModule'
+import { BuyMembershipHappyCaseFixture, UpdateProfileHappyCaseFixture } from '../../fixtures/membership'
 
 import Debugger from 'debug'
 import { FixtureRunner } from '../../Fixture'
 
-export default async function profileUpdate({ api, query }: FlowProps): Promise<void> {
+export default async function updatingProfile({ api, query }: FlowProps): Promise<void> {
   const debug = Debugger('flow:member-profile-update')
   debug('Started')
   api.enableDebugTxLogs()
 
-  const [account] = api.createKeyPairs(1).map((key) => key.address)
+  const [account] = (await api.createKeyPairs(1)).map((key) => key.address)
   const buyMembershipHappyCaseFixture = new BuyMembershipHappyCaseFixture(api, query, [account])
   await new FixtureRunner(buyMembershipHappyCaseFixture).run()
   const [memberId] = buyMembershipHappyCaseFixture.getCreatedMembers()
@@ -17,7 +17,7 @@ export default async function profileUpdate({ api, query }: FlowProps): Promise<
     account,
     memberId,
   })
-  await new FixtureRunner(updateProfileHappyCaseFixture).run()
+  await new FixtureRunner(updateProfileHappyCaseFixture).runWithQueryNodeChecks()
 
   debug('Done')
 }

+ 29 - 0
tests/integration-tests/src/flows/working-groups/groupBudget.ts

@@ -0,0 +1,29 @@
+import BN from 'bn.js'
+import { FlowProps } from '../../Flow'
+import Debugger from 'debug'
+import { FixtureRunner } from '../../Fixture'
+import { workingGroups } from '../../consts'
+import { SetBudgetFixture } from '../../fixtures/workingGroups/SetBudgetFixture'
+import { SpendBudgetFixture } from '../../fixtures/workingGroups/SpendBudgetFixture'
+
+export default async function groupBudget({ api, query }: FlowProps): Promise<void> {
+  await Promise.all(
+    workingGroups.map(async (group) => {
+      const budgets: BN[] = [new BN(1000000)]
+
+      const debug = Debugger(`flow:group-budget:${group}`)
+      debug('Started')
+      api.enableDebugTxLogs()
+
+      const setGroupBudgetFixture = new SetBudgetFixture(api, query, group, budgets)
+      await new FixtureRunner(setGroupBudgetFixture).runWithQueryNodeChecks()
+
+      const recievers = (await api.createKeyPairs(5)).map((kp) => kp.address)
+      const amounts = recievers.map((reciever, i) => new BN(10000 * (i + 1)))
+      const spendGroupBudgetFixture = new SpendBudgetFixture(api, query, group, recievers, amounts)
+      await new FixtureRunner(spendGroupBudgetFixture).runWithQueryNodeChecks()
+
+      debug('Done')
+    })
+  )
+}

+ 64 - 0
tests/integration-tests/src/flows/working-groups/groupStatus.ts

@@ -0,0 +1,64 @@
+import { FlowProps } from '../../Flow'
+import { UpdateGroupStatusFixture } from '../../fixtures/workingGroups'
+
+import Debugger from 'debug'
+import { FixtureRunner } from '../../Fixture'
+import { workingGroups } from '../../consts'
+import { IWorkingGroupMetadata } from '@joystream/metadata-protobuf'
+import _ from 'lodash'
+
+export default async function groupStatus({ api, query, env }: FlowProps): Promise<void> {
+  await Promise.all(
+    workingGroups.map(async (group) => {
+      const updates: IWorkingGroupMetadata[] = [
+        { description: `${_.startCase(group)} Test Description`, about: `${_.startCase(group)} Test About Text` },
+        {
+          status: 'Testing',
+          statusMessage: `${_.startCase(group)} is beeing tested`,
+        },
+        {
+          description: `${_.startCase(group)} New Test Description`,
+        },
+        {
+          status: 'Testing continues',
+          statusMessage: `${_.startCase(group)} testing continues`,
+        },
+        {
+          about: `${_.startCase(group)} New Test About`,
+        },
+        // Some edge cases:
+        // Should not change anything:
+        {},
+        // Should not change anything:
+        {
+          status: null,
+          statusMessage: null,
+          about: null,
+          description: null,
+        },
+        // Should unset everything:
+        {
+          status: '',
+          statusMessage: '',
+          about: '',
+          description: '',
+        },
+        {
+          status: 'Testing finished',
+          statusMessage: '',
+          description: `${_.startCase(group)} Test Description`,
+          about: `${_.startCase(group)} Test About Text`,
+        },
+      ]
+
+      const debug = Debugger(`flow:group-status:${group}`)
+      debug('Started')
+      api.enableDebugTxLogs()
+
+      const updateGroupStatusFixture = new UpdateGroupStatusFixture(api, query, group, updates)
+      await new FixtureRunner(updateGroupStatusFixture).runWithQueryNodeChecks()
+
+      debug('Done')
+    })
+  )
+}

+ 69 - 0
tests/integration-tests/src/flows/working-groups/leadOpening.ts

@@ -0,0 +1,69 @@
+import { FlowProps } from '../../Flow'
+import {
+  ApplyOnOpeningsHappyCaseFixture,
+  CreateOpeningsFixture,
+  FillOpeningsFixture,
+  ApplicantDetails,
+  DEFAULT_OPENING_PARAMS,
+} from '../../fixtures/workingGroups'
+
+import Debugger from 'debug'
+import { FixtureRunner } from '../../Fixture'
+import { AddStakingAccountsHappyCaseFixture, BuyMembershipHappyCaseFixture } from '../../fixtures/membership'
+import { workingGroups } from '../../consts'
+
+export default async function leadOpening({ api, query, env }: FlowProps): Promise<void> {
+  await Promise.all(
+    workingGroups.map(async (group) => {
+      const debug = Debugger(`flow:lead-opening:${group}`)
+      debug('Started')
+      api.enableDebugTxLogs()
+
+      const createOpeningFixture = new CreateOpeningsFixture(api, query, group, undefined, true)
+      const openingRunner = new FixtureRunner(createOpeningFixture)
+      await openingRunner.run()
+      const [openingId] = createOpeningFixture.getCreatedOpeningIds()
+      const { stake: openingStake, metadata: openingMetadata } = DEFAULT_OPENING_PARAMS
+
+      const [roleAccount, stakingAccount, rewardAccount] = (await api.createKeyPairs(3)).map((kp) => kp.address)
+      const buyMembershipFixture = new BuyMembershipHappyCaseFixture(api, query, [roleAccount])
+      await new FixtureRunner(buyMembershipFixture).run()
+      const [memberId] = buyMembershipFixture.getCreatedMembers()
+
+      const applicantContext = { account: roleAccount, memberId }
+
+      const addStakingAccFixture = new AddStakingAccountsHappyCaseFixture(api, query, applicantContext, [
+        stakingAccount,
+      ])
+      await new FixtureRunner(addStakingAccFixture).run()
+      await api.treasuryTransferBalance(stakingAccount, openingStake)
+
+      const applicantDetails: ApplicantDetails = {
+        memberId,
+        roleAccount,
+        rewardAccount,
+        stakingAccount,
+      }
+
+      const applyOnOpeningFixture = new ApplyOnOpeningsHappyCaseFixture(api, query, group, [
+        {
+          openingId,
+          openingMetadata,
+          applicants: [applicantDetails],
+        },
+      ])
+      const applicationRunner = new FixtureRunner(applyOnOpeningFixture)
+      await applicationRunner.run()
+      const [applicationId] = applyOnOpeningFixture.getCreatedApplicationsByOpeningId(openingId)
+
+      // Run query node checks once this part of the flow is done
+      await Promise.all([openingRunner.runQueryNodeChecks(), applicationRunner.runQueryNodeChecks()])
+
+      // Fill opening
+      const fillOpeningFixture = new FillOpeningsFixture(api, query, group, [openingId], [[applicationId]], true)
+      await new FixtureRunner(fillOpeningFixture).runWithQueryNodeChecks()
+
+      debug('Done')
+    })
+  )
+}

+ 150 - 0
tests/integration-tests/src/flows/working-groups/openingsAndApplications.ts

@@ -0,0 +1,150 @@
+import { FlowProps } from '../../Flow'
+import {
+  ApplyOnOpeningsHappyCaseFixture,
+  CancelOpeningsFixture,
+  CreateOpeningsFixture,
+  WithdrawApplicationsFixture,
+  ApplicantDetails,
+  DEFAULT_OPENING_PARAMS,
+  OpeningParams,
+} from '../../fixtures/workingGroups'
+
+import Debugger from 'debug'
+import { FixtureRunner } from '../../Fixture'
+import { AddStakingAccountsHappyCaseFixture, BuyMembershipHappyCaseFixture } from '../../fixtures/membership'
+import { workingGroups, LEADER_OPENING_STAKE } from '../../consts'
+import { assert } from 'chai'
+
+const openingsToCreate: OpeningParams[] = [
+  // All defaults case:
+  DEFAULT_OPENING_PARAMS,
+  // Invalid metadata case:
+  {
+    ...DEFAULT_OPENING_PARAMS,
+    metadata: '0xff',
+    expectMetadataFailure: true,
+  },
+  // Valid metadata edge-cases:
+  {
+    ...DEFAULT_OPENING_PARAMS,
+    metadata: {
+      shortDescription: '',
+      description: '',
+      expectedEndingTimestamp: 0,
+      hiringLimit: 0,
+      applicationDetails: '',
+      applicationFormQuestions: [],
+    },
+  },
+  {
+    ...DEFAULT_OPENING_PARAMS,
+    metadata: {
+      shortDescription: null,
+      description: null,
+      expectedEndingTimestamp: null,
+      hiringLimit: null,
+      applicationDetails: null,
+      applicationFormQuestions: null,
+    },
+  },
+  {
+    ...DEFAULT_OPENING_PARAMS,
+    metadata: {},
+  },
+  {
+    ...DEFAULT_OPENING_PARAMS,
+    metadata: {
+      hiringLimit: 1,
+      applicationFormQuestions: [{}],
+    },
+  },
+]
+
+export default async function openingsAndApplications({ api, query, env }: FlowProps): Promise<void> {
+  const APPLICATION_CREATE_N = parseInt(env.APPLICATION_STATUS_CREATE_N || '')
+  const APPLICATION_WITHDRAW_N = parseInt(env.APPLICATION_STATUS_WITHDRAW_N || '')
+  assert.isAbove(APPLICATION_CREATE_N, 0)
+  assert.isAbove(APPLICATION_WITHDRAW_N, 0)
+  assert.isBelow(APPLICATION_WITHDRAW_N, APPLICATION_CREATE_N)
+
+  await Promise.all(
+    workingGroups.map(async (group) => {
+      const debug = Debugger(`flow:openings-and-applications:${group}`)
+      debug('Started')
+      api.enableDebugTxLogs()
+
+      // Transfer funds to leader staking acc to cover opening stake
+      const leaderStakingAcc = await api.getLeaderStakingKey(group)
+      await api.treasuryTransferBalance(leaderStakingAcc, LEADER_OPENING_STAKE.muln(openingsToCreate.length))
+
+      // Create an opening
+      const createOpeningsFixture = new CreateOpeningsFixture(api, query, group, openingsToCreate)
+      const openingsRunner = new FixtureRunner(createOpeningsFixture)
+      await openingsRunner.run()
+      const [openingId] = createOpeningsFixture.getCreatedOpeningIds()
+      const { stake: openingStake, metadata: openingMetadata } = DEFAULT_OPENING_PARAMS
+
+      // Create some applications
+      const roleAccounts = (await api.createKeyPairs(APPLICATION_CREATE_N)).map((kp) => kp.address)
+      const stakingAccounts = (await api.createKeyPairs(APPLICATION_CREATE_N)).map((kp) => kp.address)
+      const rewardAccounts = (await api.createKeyPairs(APPLICATION_CREATE_N)).map((kp) => kp.address)
+
+      const buyMembershipFixture = new BuyMembershipHappyCaseFixture(api, query, roleAccounts)
+      await new FixtureRunner(buyMembershipFixture).run()
+      const memberIds = buyMembershipFixture.getCreatedMembers()
+
+      const applicantContexts = roleAccounts.map((account, i) => ({
+        account,
+        memberId: memberIds[i],
+      }))
+
+      await Promise.all(
+        applicantContexts.map((applicantContext, i) => {
+          const addStakingAccFixture = new AddStakingAccountsHappyCaseFixture(api, query, applicantContext, [
+            stakingAccounts[i],
+          ])
+          return new FixtureRunner(addStakingAccFixture).run()
+        })
+      )
+      await Promise.all(stakingAccounts.map((a) => api.treasuryTransferBalance(a, openingStake)))
+
+      const applicants: ApplicantDetails[] = memberIds.map((memberId, i) => ({
+        memberId,
+        roleAccount: roleAccounts[i],
+        stakingAccount: stakingAccounts[i],
+        rewardAccount: rewardAccounts[i],
+      }))
+      const applyOnOpeningFixture = new ApplyOnOpeningsHappyCaseFixture(api, query, group, [
+        {
+          openingId,
+          openingMetadata,
+          applicants,
+        },
+      ])
+      const applyRunner = new FixtureRunner(applyOnOpeningFixture)
+      await applyRunner.run()
+      const applicationIds = await applyOnOpeningFixture.getCreatedApplicationsByOpeningId(openingId)
+
+      // Withdraw some applications
+      const withdrawApplicationsFixture = new WithdrawApplicationsFixture(
+        api,
+        query,
+        group,
+        roleAccounts.slice(0, APPLICATION_WITHDRAW_N),
+        applicationIds.slice(0, APPLICATION_WITHDRAW_N)
+      )
+      const withdrawApplicationsRunner = new FixtureRunner(withdrawApplicationsFixture)
+      await withdrawApplicationsRunner.run()
+
+      // Cancel the opening
+      const cancelOpeningFixture = new CancelOpeningsFixture(api, query, group, [openingId])
+      const cancelOpeningRunner = new FixtureRunner(cancelOpeningFixture)
+      await cancelOpeningRunner.run()
+
+      // Run query node check
+      await Promise.all([withdrawApplicationsRunner.runQueryNodeChecks(), cancelOpeningRunner.runQueryNodeChecks()])
+
+      debug('Done')
+    })
+  )
+}

+ 94 - 0
tests/integration-tests/src/flows/working-groups/upcomingOpenings.ts

@@ -0,0 +1,94 @@
+import { FlowProps } from '../../Flow'
+import {
+  CreateUpcomingOpeningsFixture,
+  DEFAULT_UPCOMING_OPENING_META,
+  RemoveUpcomingOpeningsFixture,
+  UpcomingOpeningParams,
+} from '../../fixtures/workingGroups'
+
+import Debugger from 'debug'
+import { FixtureRunner } from '../../Fixture'
+import { workingGroups } from '../../consts'
+import Long from 'long'
+
+const upcomingOpeningsToCreate: UpcomingOpeningParams[] = [
+  // All defaults case:
+  {
+    meta: DEFAULT_UPCOMING_OPENING_META,
+  },
+  // Invalid metadata case:
+  {
+    meta: '0xff',
+    expectMetadataFailure: true,
+  },
+  // Valid metadata edge-cases
+  {
+    meta: {
+      expectedStart: 0,
+      minApplicationStake: Long.fromString('0'),
+      rewardPerBlock: Long.fromString('0'),
+      metadata: {
+        shortDescription: '',
+        description: '',
+        expectedEndingTimestamp: 0,
+        hiringLimit: 0,
+        applicationDetails: '',
+        applicationFormQuestions: [],
+      },
+    },
+  },
+  {
+    meta: {
+      expectedStart: null,
+      minApplicationStake: null,
+      rewardPerBlock: null,
+      metadata: {
+        shortDescription: null,
+        description: null,
+        expectedEndingTimestamp: null,
+        hiringLimit: null,
+        applicationDetails: null,
+        applicationFormQuestions: null,
+      },
+    },
+  },
+  {
+    meta: {},
+  },
+  {
+    meta: {
+      metadata: {
+        hiringLimit: 1,
+        applicationFormQuestions: [{}],
+      },
+    },
+  },
+]
+
+export default async function upcomingOpenings({ api, query, env }: FlowProps): Promise<void> {
+  await Promise.all(
+    workingGroups.map(async (group) => {
+      const debug = Debugger(`flow:upcoming-openings:${group}`)
+      debug('Started')
+      api.enableDebugTxLogs()
+      const createUpcomingOpeningFixture = new CreateUpcomingOpeningsFixture(
+        api,
+        query,
+        group,
+        upcomingOpeningsToCreate
+      )
+      await new FixtureRunner(createUpcomingOpeningFixture).runWithQueryNodeChecks()
+      const createdUpcomingOpeningIds = createUpcomingOpeningFixture.getCreatedUpcomingOpeningIds()
+
+      const removeUpcomingOpeningFixture = new RemoveUpcomingOpeningsFixture(
+        api,
+        query,
+        group,
+        createdUpcomingOpeningIds
+      )
+      await new FixtureRunner(removeUpcomingOpeningFixture).runWithQueryNodeChecks()
+
+      debug('Done')
+    })
+  )
+}

+ 127 - 0
tests/integration-tests/src/flows/working-groups/workerActions.ts

@@ -0,0 +1,127 @@
+import { FlowProps } from '../../Flow'
+import Debugger from 'debug'
+import { FixtureRunner } from '../../Fixture'
+import { workingGroups } from '../../consts'
+import { HireWorkersFixture } from '../../fixtures/workingGroups/HireWorkersFixture'
+import { UpdateWorkerRoleAccountsFixture } from '../../fixtures/workingGroups/UpdateWorkerRoleAccountsFixture'
+import { IncreaseWorkerStakesFixture } from '../../fixtures/workingGroups/IncreaseWorkerStakesFixture'
+import { UpdateWorkerRewardAccountsFixture } from '../../fixtures/workingGroups/UpdateWorkerRewardAccountsFixture'
+import { Worker } from '@joystream/types/working-group'
+import { LeaveRoleFixture } from '../../fixtures/workingGroups/LeaveRoleFixture'
+import { assert } from 'chai'
+import BN from 'bn.js'
+import { UpdateWorkerRewardAmountsFixture } from '../../fixtures/workingGroups/UpdateWorkerRewardAmountsFixture'
+import { DecreaseWorkerStakesFixture } from '../../fixtures/workingGroups/DecreaseWorkerStakesFixture'
+import { SlashWorkerStakesFixture } from '../../fixtures/workingGroups/SlashWorkerStakesFixture'
+import { TerminateWorkersFixture } from '../../fixtures/workingGroups/TerminateWorkersFixture'
+
+export default async function workerActions({ api, query, env }: FlowProps): Promise<void> {
+  await Promise.all(
+    workingGroups.map(async (group) => {
+      const debug = Debugger(`flow:worker-actions:${group}`)
+      debug('Started')
+      api.enableDebugTxLogs()
+
+      const WORKERS_N = parseInt(env.WORKER_ACTIONS_WORKERS_N || '')
+      const TERMINATIONS_N = parseInt(env.WORKER_ACTIONS_TERMINATE_N || '')
+      assert.isAtLeast(WORKERS_N, 2)
+      assert.isAtLeast(TERMINATIONS_N, 1)
+      assert.isBelow(TERMINATIONS_N, WORKERS_N)
+
+      const hireWorkersFixture = new HireWorkersFixture(api, query, group, WORKERS_N)
+      await new FixtureRunner(hireWorkersFixture).run()
+      const workerIds = hireWorkersFixture.getCreatedWorkerIds()
+      const workers = await api.query[group].workerById.multi<Worker>(workerIds)
+
+      // Independent updates that don't interfere with each other
+      const workerUpdatesRunners: FixtureRunner[] = []
+
+      const newRoleAccounts = (await api.createKeyPairs(WORKERS_N)).map((kp) => kp.address)
+      const updateRoleAccountsFixture = new UpdateWorkerRoleAccountsFixture(
+        api,
+        query,
+        group,
+        workerIds,
+        newRoleAccounts
+      )
+      const updateRoleAccountsRunner = new FixtureRunner(updateRoleAccountsFixture)
+      await updateRoleAccountsRunner.run()
+      workerUpdatesRunners.push(updateRoleAccountsRunner)
+
+      const newRewardAccounts = (await api.createKeyPairs(WORKERS_N)).map((kp) => kp.address)
+      const updateRewardAccountsFixture = new UpdateWorkerRewardAccountsFixture(
+        api,
+        query,
+        group,
+        workerIds,
+        newRewardAccounts
+      )
+      const updateRewardAccountsRunner = new FixtureRunner(updateRewardAccountsFixture)
+      await updateRewardAccountsRunner.run()
+      workerUpdatesRunners.push(updateRewardAccountsRunner)
+
+      const stakeIncreases = workerIds.map((id) => id.addn(1).muln(1000))
+      // Transfer balances
+      await Promise.all(
+        stakeIncreases.map((amount, i) => api.treasuryTransferBalance(workers[i].staking_account_id.toString(), amount))
+      )
+      const increaseWorkerStakesFixture = new IncreaseWorkerStakesFixture(api, query, group, workerIds, stakeIncreases)
+      const increaseWorkerStakesRunner = new FixtureRunner(increaseWorkerStakesFixture)
+      await increaseWorkerStakesRunner.run()
+      workerUpdatesRunners.push(increaseWorkerStakesRunner)
+
+      const newRewards: (BN | null)[] = workerIds.map((id) => id.addn(1).muln(10))
+      // At least one case should be null
+      newRewards[0] = null
+      const updateRewardsFixture = new UpdateWorkerRewardAmountsFixture(api, query, group, workerIds, newRewards)
+      const updateRewardsRunner = new FixtureRunner(updateRewardsFixture)
+      await updateRewardsRunner.run()
+      workerUpdatesRunners.push(updateRewardsRunner)
+
+      // Run query node checks for all above fixtures
+      await Promise.all(workerUpdatesRunners.map((r) => r.runQueryNodeChecks()))
+
+      // Those updates are separated since they affect worker stake and could interfere with each other:
+
+      // Stake decreases
+      const decreaseAmounts = workerIds.map((id) => id.addn(1).muln(100))
+      const decreaseStakesFixture = new DecreaseWorkerStakesFixture(api, query, group, workerIds, decreaseAmounts)
+      const decreaseStakesRunner = new FixtureRunner(decreaseStakesFixture)
+      await decreaseStakesRunner.runWithQueryNodeChecks()
+
+      // Termination / leaving runners
+      const exitRunners: FixtureRunner[] = []
+      const terminatedWorkerIds = workerIds.slice(0, TERMINATIONS_N)
+      const leavingWorkerIds = workerIds.slice(TERMINATIONS_N)
+
+      // Worker terminations
+      const penaltyAmounts = workerIds.map((id) => id.addn(1).muln(200))
+      const terminateWorkersFixture = new TerminateWorkersFixture(
+        api,
+        query,
+        group,
+        terminatedWorkerIds,
+        penaltyAmounts
+      )
+      const terminateWorkersRunner = new FixtureRunner(terminateWorkersFixture)
+      exitRunners.push(terminateWorkersRunner)
+
+      // Workers leaving
+      const leaveRoleFixture = new LeaveRoleFixture(api, query, group, leavingWorkerIds)
+      const leaveRoleRunner = new FixtureRunner(leaveRoleFixture)
+      exitRunners.push(leaveRoleRunner)
+
+      await Promise.all(exitRunners.map((r) => r.runWithQueryNodeChecks()))
+
+      // Slashes (post-leave-role to make sure they still work while worker is unstaking)
+      const slashAmounts = leavingWorkerIds.map((id) => id.addn(1).muln(300))
+      // Add at least 1 case where slashAmount > stake
+      slashAmounts[0] = slashAmounts[0].muln(10)
+      const slashStakesFixture = new SlashWorkerStakesFixture(api, query, group, leavingWorkerIds, slashAmounts)
+      const slashStakesRunner = new FixtureRunner(slashStakesFixture)
+      await slashStakesRunner.runWithQueryNodeChecks()
+
+      await debug('Done')
+    })
+  )
+}

+ 1995 - 0
tests/integration-tests/src/graphql/generated/queries.ts

@@ -0,0 +1,1995 @@
+import * as Types from './schema'
+
+import gql from 'graphql-tag'
+export type MemberMetadataFieldsFragment = { name?: Types.Maybe<string>; about?: Types.Maybe<string> }
+
+export type MembershipFieldsFragment = {
+  id: string
+  handle: string
+  controllerAccount: string
+  rootAccount: string
+  isVerified: boolean
+  inviteCount: number
+  boundAccounts: Array<string>
+  metadata: MemberMetadataFieldsFragment
+  entry:
+    | { __typename: 'MembershipEntryPaid'; membershipBoughtEvent?: Types.Maybe<{ id: string }> }
+    | { __typename: 'MembershipEntryInvited'; memberInvitedEvent?: Types.Maybe<{ id: string }> }
+    | { __typename: 'MembershipEntryGenesis' }
+  invitedBy?: Types.Maybe<{ id: string }>
+  invitees: Array<{ id: string }>
+}
+
+export type GetMemberByIdQueryVariables = Types.Exact<{
+  id: Types.Scalars['ID']
+}>
+
+export type GetMemberByIdQuery = { membershipByUniqueInput?: Types.Maybe<MembershipFieldsFragment> }
+
+export type GetMembersByIdsQueryVariables = Types.Exact<{
+  ids?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetMembersByIdsQuery = { memberships: Array<MembershipFieldsFragment> }
+
+export type MembershipSystemSnapshotFieldsFragment = {
+  createdAt: any
+  snapshotBlock: number
+  referralCut: number
+  invitedInitialBalance: any
+  defaultInviteCount: number
+  membershipPrice: any
+}
+
+export type GetMembershipSystemSnapshotAtQueryVariables = Types.Exact<{
+  time: Types.Scalars['DateTime']
+}>
+
+export type GetMembershipSystemSnapshotAtQuery = {
+  membershipSystemSnapshots: Array<MembershipSystemSnapshotFieldsFragment>
+}
+
+export type GetMembershipSystemSnapshotBeforeQueryVariables = Types.Exact<{
+  time: Types.Scalars['DateTime']
+}>
+
+export type GetMembershipSystemSnapshotBeforeQuery = {
+  membershipSystemSnapshots: Array<MembershipSystemSnapshotFieldsFragment>
+}
+
+export type MembershipBoughtEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  rootAccount: string
+  controllerAccount: string
+  handle: string
+  newMember: { id: string }
+  metadata: MemberMetadataFieldsFragment
+  referrer?: Types.Maybe<{ id: string }>
+}
+
+export type GetMembershipBoughtEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetMembershipBoughtEventsByEventIdsQuery = {
+  membershipBoughtEvents: Array<MembershipBoughtEventFieldsFragment>
+}
+
+export type MemberProfileUpdatedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  newHandle?: Types.Maybe<string>
+  member: { id: string }
+  newMetadata: { name?: Types.Maybe<string>; about?: Types.Maybe<string> }
+}
+
+export type GetMemberProfileUpdatedEventsByMemberIdQueryVariables = Types.Exact<{
+  memberId: Types.Scalars['ID']
+}>
+
+export type GetMemberProfileUpdatedEventsByMemberIdQuery = {
+  memberProfileUpdatedEvents: Array<MemberProfileUpdatedEventFieldsFragment>
+}
+
+export type MemberAccountsUpdatedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  newRootAccount?: Types.Maybe<string>
+  newControllerAccount?: Types.Maybe<string>
+  member: { id: string }
+}
+
+export type GetMemberAccountsUpdatedEventsByMemberIdQueryVariables = Types.Exact<{
+  memberId: Types.Scalars['ID']
+}>
+
+export type GetMemberAccountsUpdatedEventsByMemberIdQuery = {
+  memberAccountsUpdatedEvents: Array<MemberAccountsUpdatedEventFieldsFragment>
+}
+
+export type MemberInvitedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  rootAccount: string
+  controllerAccount: string
+  handle: string
+  invitingMember: { id: string }
+  newMember: { id: string }
+  metadata: MemberMetadataFieldsFragment
+}
+
+export type GetMemberInvitedEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetMemberInvitedEventsByEventIdsQuery = { memberInvitedEvents: Array<MemberInvitedEventFieldsFragment> }
+
+export type InvitesTransferredEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  numberOfInvites: number
+  sourceMember: { id: string }
+  targetMember: { id: string }
+}
+
+export type GetInvitesTransferredEventsBySourceMemberIdQueryVariables = Types.Exact<{
+  sourceMemberId: Types.Scalars['ID']
+}>
+
+export type GetInvitesTransferredEventsBySourceMemberIdQuery = {
+  invitesTransferredEvents: Array<InvitesTransferredEventFieldsFragment>
+}
+
+export type StakingAccountAddedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  account: string
+  member: { id: string }
+}
+
+export type GetStakingAccountAddedEventsByMemberIdQueryVariables = Types.Exact<{
+  memberId: Types.Scalars['ID']
+}>
+
+export type GetStakingAccountAddedEventsByMemberIdQuery = {
+  stakingAccountAddedEvents: Array<StakingAccountAddedEventFieldsFragment>
+}
+
+export type StakingAccountConfirmedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  account: string
+  member: { id: string }
+}
+
+export type GetStakingAccountConfirmedEventsByMemberIdQueryVariables = Types.Exact<{
+  memberId: Types.Scalars['ID']
+}>
+
+export type GetStakingAccountConfirmedEventsByMemberIdQuery = {
+  stakingAccountConfirmedEvents: Array<StakingAccountConfirmedEventFieldsFragment>
+}
+
+export type StakingAccountRemovedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  account: string
+  member: { id: string }
+}
+
+export type GetStakingAccountRemovedEventsByMemberIdQueryVariables = Types.Exact<{
+  memberId: Types.Scalars['ID']
+}>
+
+export type GetStakingAccountRemovedEventsByMemberIdQuery = {
+  stakingAccountRemovedEvents: Array<StakingAccountRemovedEventFieldsFragment>
+}
+
+export type ReferralCutUpdatedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  newValue: number
+}
+
+export type GetReferralCutUpdatedEventsByEventIdQueryVariables = Types.Exact<{
+  eventId: Types.Scalars['ID']
+}>
+
+export type GetReferralCutUpdatedEventsByEventIdQuery = {
+  referralCutUpdatedEvents: Array<ReferralCutUpdatedEventFieldsFragment>
+}
+
+export type MembershipPriceUpdatedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  newPrice: any
+}
+
+export type GetMembershipPriceUpdatedEventsByEventIdQueryVariables = Types.Exact<{
+  eventId: Types.Scalars['ID']
+}>
+
+export type GetMembershipPriceUpdatedEventsByEventIdQuery = {
+  membershipPriceUpdatedEvents: Array<MembershipPriceUpdatedEventFieldsFragment>
+}
+
+export type InitialInvitationBalanceUpdatedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  newInitialBalance: any
+}
+
+export type GetInitialInvitationBalanceUpdatedEventsByEventIdQueryVariables = Types.Exact<{
+  eventId: Types.Scalars['ID']
+}>
+
+export type GetInitialInvitationBalanceUpdatedEventsByEventIdQuery = {
+  initialInvitationBalanceUpdatedEvents: Array<InitialInvitationBalanceUpdatedEventFieldsFragment>
+}
+
+export type InitialInvitationCountUpdatedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  newInitialInvitationCount: number
+}
+
+export type GetInitialInvitationCountUpdatedEventsByEventIdQueryVariables = Types.Exact<{
+  eventId: Types.Scalars['ID']
+}>
+
+export type GetInitialInvitationCountUpdatedEventsByEventIdQuery = {
+  initialInvitationCountUpdatedEvents: Array<InitialInvitationCountUpdatedEventFieldsFragment>
+}
+
+export type ApplicationBasicFieldsFragment = {
+  id: string
+  runtimeId: number
+  status:
+    | { __typename: 'ApplicationStatusPending' }
+    | { __typename: 'ApplicationStatusAccepted'; openingFilledEvent?: Types.Maybe<{ id: string }> }
+    | { __typename: 'ApplicationStatusRejected'; openingFilledEvent?: Types.Maybe<{ id: string }> }
+    | { __typename: 'ApplicationStatusWithdrawn'; applicationWithdrawnEvent?: Types.Maybe<{ id: string }> }
+    | { __typename: 'ApplicationStatusCancelled'; openingCanceledEvent?: Types.Maybe<{ id: string }> }
+}
+
+type OpeningStatusFields_OpeningStatusOpen_Fragment = { __typename: 'OpeningStatusOpen' }
+
+type OpeningStatusFields_OpeningStatusFilled_Fragment = {
+  __typename: 'OpeningStatusFilled'
+  openingFilledEvent?: Types.Maybe<{ id: string }>
+}
+
+type OpeningStatusFields_OpeningStatusCancelled_Fragment = {
+  __typename: 'OpeningStatusCancelled'
+  openingCanceledEvent?: Types.Maybe<{ id: string }>
+}
+
+export type OpeningStatusFieldsFragment =
+  | OpeningStatusFields_OpeningStatusOpen_Fragment
+  | OpeningStatusFields_OpeningStatusFilled_Fragment
+  | OpeningStatusFields_OpeningStatusCancelled_Fragment
+
+export type ApplicationFormQuestionFieldsFragment = {
+  question?: Types.Maybe<string>
+  type: Types.ApplicationFormQuestionType
+  index: number
+}
+
+export type OpeningMetadataFieldsFragment = {
+  shortDescription?: Types.Maybe<string>
+  description?: Types.Maybe<string>
+  hiringLimit?: Types.Maybe<number>
+  expectedEnding?: Types.Maybe<any>
+  applicationDetails?: Types.Maybe<string>
+  applicationFormQuestions: Array<ApplicationFormQuestionFieldsFragment>
+}
+
+export type WorkerFieldsFragment = {
+  id: string
+  runtimeId: number
+  roleAccount: string
+  rewardAccount: string
+  stakeAccount: string
+  isLead: boolean
+  stake: any
+  storage?: Types.Maybe<string>
+  rewardPerBlock: any
+  missingRewardAmount?: Types.Maybe<any>
+  group: { name: string }
+  membership: { id: string }
+  status:
+    | { __typename: 'WorkerStatusActive' }
+    | {
+        __typename: 'WorkerStatusLeft'
+        workerStartedLeavingEvent?: Types.Maybe<{ id: string }>
+        workerExitedEvent?: Types.Maybe<{ id: string }>
+      }
+    | { __typename: 'WorkerStatusTerminated'; terminatedWorkerEvent?: Types.Maybe<{ id: string }> }
+  payouts: Array<{ id: string }>
+  slashes: Array<{ id: string }>
+  entry: { id: string }
+  application: ApplicationBasicFieldsFragment
+}
+
+export type WorkingGroupMetadataFieldsFragment = {
+  id: string
+  status?: Types.Maybe<string>
+  statusMessage?: Types.Maybe<string>
+  about?: Types.Maybe<string>
+  description?: Types.Maybe<string>
+  setInEvent: { id: string }
+}
+
+export type OpeningFieldsFragment = {
+  id: string
+  runtimeId: number
+  type: Types.WorkingGroupOpeningType
+  stakeAmount: any
+  unstakingPeriod: number
+  rewardPerBlock: any
+  group: { name: string }
+  applications: Array<ApplicationBasicFieldsFragment>
+  status:
+    | OpeningStatusFields_OpeningStatusOpen_Fragment
+    | OpeningStatusFields_OpeningStatusFilled_Fragment
+    | OpeningStatusFields_OpeningStatusCancelled_Fragment
+  metadata: OpeningMetadataFieldsFragment
+  createdInEvent: { id: string }
+}
+
+export type GetOpeningByIdQueryVariables = Types.Exact<{
+  openingId: Types.Scalars['ID']
+}>
+
+export type GetOpeningByIdQuery = { workingGroupOpeningByUniqueInput?: Types.Maybe<OpeningFieldsFragment> }
+
+export type GetOpeningsByIdsQueryVariables = Types.Exact<{
+  openingIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetOpeningsByIdsQuery = { workingGroupOpenings: Array<OpeningFieldsFragment> }
+
+export type ApplicationFieldsFragment = {
+  roleAccount: string
+  rewardAccount: string
+  stakingAccount: string
+  stake: any
+  createdInEvent: { id: string }
+  opening: { id: string; runtimeId: number }
+  applicant: { id: string }
+  answers: Array<{ answer: string; question: { question?: Types.Maybe<string> } }>
+} & ApplicationBasicFieldsFragment
+
+export type GetApplicationByIdQueryVariables = Types.Exact<{
+  applicationId: Types.Scalars['ID']
+}>
+
+export type GetApplicationByIdQuery = { workingGroupApplicationByUniqueInput?: Types.Maybe<ApplicationFieldsFragment> }
+
+export type GetApplicationsByIdsQueryVariables = Types.Exact<{
+  applicationIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetApplicationsByIdsQuery = { workingGroupApplications: Array<ApplicationFieldsFragment> }
+
+export type WorkingGroupFieldsFragment = {
+  id: string
+  name: string
+  budget: any
+  metadata?: Types.Maybe<WorkingGroupMetadataFieldsFragment>
+  leader?: Types.Maybe<{ id: string; runtimeId: number }>
+}
+
+export type GetWorkingGroupByNameQueryVariables = Types.Exact<{
+  name: Types.Scalars['String']
+}>
+
+export type GetWorkingGroupByNameQuery = { workingGroupByUniqueInput?: Types.Maybe<WorkingGroupFieldsFragment> }
+
+export type UpcomingOpeningFieldsFragment = {
+  id: string
+  expectedStart?: Types.Maybe<any>
+  stakeAmount?: Types.Maybe<any>
+  rewardPerBlock?: Types.Maybe<any>
+  createdAt: any
+  group: { name: string }
+  metadata: OpeningMetadataFieldsFragment
+  createdInEvent: { id: string }
+}
+
+export type GetUpcomingOpeningByIdQueryVariables = Types.Exact<{
+  id: Types.Scalars['ID']
+}>
+
+export type GetUpcomingOpeningByIdQuery = {
+  upcomingWorkingGroupOpeningByUniqueInput?: Types.Maybe<UpcomingOpeningFieldsFragment>
+}
+
+export type GetUpcomingOpeningsByCreatedInEventIdsQueryVariables = Types.Exact<{
+  createdInEventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetUpcomingOpeningsByCreatedInEventIdsQuery = {
+  upcomingWorkingGroupOpenings: Array<UpcomingOpeningFieldsFragment>
+}
+
+export type GetWorkingGroupMetadataSnapshotsByTimeAscQueryVariables = Types.Exact<{
+  groupId: Types.Scalars['ID']
+}>
+
+export type GetWorkingGroupMetadataSnapshotsByTimeAscQuery = {
+  workingGroupMetadata: Array<WorkingGroupMetadataFieldsFragment>
+}
+
+export type GetWorkersByRuntimeIdsQueryVariables = Types.Exact<{
+  workerIds?: Types.Maybe<Array<Types.Scalars['Int']> | Types.Scalars['Int']>
+  groupId: Types.Scalars['ID']
+}>
+
+export type GetWorkersByRuntimeIdsQuery = { workers: Array<WorkerFieldsFragment> }
+
+export type AppliedOnOpeningEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  group: { name: string }
+  opening: { id: string; runtimeId: number }
+  application: { id: string; runtimeId: number }
+}
+
+export type GetAppliedOnOpeningEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetAppliedOnOpeningEventsByEventIdsQuery = {
+  appliedOnOpeningEvents: Array<AppliedOnOpeningEventFieldsFragment>
+}
+
+export type OpeningAddedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  group: { name: string }
+  opening: { id: string; runtimeId: number }
+}
+
+export type GetOpeningAddedEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetOpeningAddedEventsByEventIdsQuery = { openingAddedEvents: Array<OpeningAddedEventFieldsFragment> }
+
+export type LeaderSetEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  group: { name: string }
+  worker?: Types.Maybe<{ id: string; runtimeId: number }>
+}
+
+export type GetLeaderSetEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetLeaderSetEventsByEventIdsQuery = { leaderSetEvents: Array<LeaderSetEventFieldsFragment> }
+
+export type OpeningFilledEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  group: { name: string }
+  opening: { id: string; runtimeId: number }
+  workersHired: Array<WorkerFieldsFragment>
+}
+
+export type GetOpeningFilledEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetOpeningFilledEventsByEventIdsQuery = { openingFilledEvents: Array<OpeningFilledEventFieldsFragment> }
+
+export type ApplicationWithdrawnEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  group: { name: string }
+  application: { id: string; runtimeId: number }
+}
+
+export type GetApplicationWithdrawnEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetApplicationWithdrawnEventsByEventIdsQuery = {
+  applicationWithdrawnEvents: Array<ApplicationWithdrawnEventFieldsFragment>
+}
+
+export type OpeningCanceledEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  group: { name: string }
+  opening: { id: string; runtimeId: number }
+}
+
+export type GetOpeningCancelledEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetOpeningCancelledEventsByEventIdsQuery = {
+  openingCanceledEvents: Array<OpeningCanceledEventFieldsFragment>
+}
+
+export type StatusTextChangedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  metadata?: Types.Maybe<string>
+  group: { name: string }
+  result:
+    | { __typename: 'UpcomingOpeningAdded'; upcomingOpeningId: string }
+    | { __typename: 'UpcomingOpeningRemoved'; upcomingOpeningId: string }
+    | { __typename: 'WorkingGroupMetadataSet'; metadata?: Types.Maybe<{ id: string }> }
+    | { __typename: 'InvalidActionMetadata'; reason: string }
+}
+
+export type GetStatusTextChangedEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetStatusTextChangedEventsByEventIdsQuery = {
+  statusTextChangedEvents: Array<StatusTextChangedEventFieldsFragment>
+}
+
+export type WorkerRoleAccountUpdatedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  newRoleAccount: string
+  group: { name: string }
+  worker: { id: string; runtimeId: number }
+}
+
+export type GetWorkerRoleAccountUpdatedEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetWorkerRoleAccountUpdatedEventsByEventIdsQuery = {
+  workerRoleAccountUpdatedEvents: Array<WorkerRoleAccountUpdatedEventFieldsFragment>
+}
+
+export type WorkerRewardAccountUpdatedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  newRewardAccount: string
+  group: { name: string }
+  worker: { id: string; runtimeId: number }
+}
+
+export type GetWorkerRewardAccountUpdatedEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetWorkerRewardAccountUpdatedEventsByEventIdsQuery = {
+  workerRewardAccountUpdatedEvents: Array<WorkerRewardAccountUpdatedEventFieldsFragment>
+}
+
+export type StakeIncreasedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  amount: any
+  group: { name: string }
+  worker: { id: string; runtimeId: number }
+}
+
+export type GetStakeIncreasedEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetStakeIncreasedEventsByEventIdsQuery = { stakeIncreasedEvents: Array<StakeIncreasedEventFieldsFragment> }
+
+export type WorkerStartedLeavingEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  rationale?: Types.Maybe<string>
+  group: { name: string }
+  worker: { id: string; runtimeId: number }
+}
+
+export type GetWorkerStartedLeavingEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetWorkerStartedLeavingEventsByEventIdsQuery = {
+  workerStartedLeavingEvents: Array<WorkerStartedLeavingEventFieldsFragment>
+}
+
+export type WorkerRewardAmountUpdatedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  newRewardPerBlock: any
+  group: { name: string }
+  worker: { id: string; runtimeId: number }
+}
+
+export type GetWorkerRewardAmountUpdatedEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetWorkerRewardAmountUpdatedEventsByEventIdsQuery = {
+  workerRewardAmountUpdatedEvents: Array<WorkerRewardAmountUpdatedEventFieldsFragment>
+}
+
+export type StakeSlashedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  requestedAmount: any
+  slashedAmount: any
+  rationale?: Types.Maybe<string>
+  group: { name: string }
+  worker: { id: string; runtimeId: number }
+}
+
+export type GetStakeSlashedEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetStakeSlashedEventsByEventIdsQuery = { stakeSlashedEvents: Array<StakeSlashedEventFieldsFragment> }
+
+export type StakeDecreasedEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  amount: any
+  group: { name: string }
+  worker: { id: string; runtimeId: number }
+}
+
+export type GetStakeDecreasedEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetStakeDecreasedEventsByEventIdsQuery = { stakeDecreasedEvents: Array<StakeDecreasedEventFieldsFragment> }
+
+export type TerminatedWorkerEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  penalty?: Types.Maybe<any>
+  rationale?: Types.Maybe<string>
+  group: { name: string }
+  worker: { id: string; runtimeId: number }
+}
+
+export type GetTerminatedWorkerEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetTerminatedWorkerEventsByEventIdsQuery = {
+  terminatedWorkerEvents: Array<TerminatedWorkerEventFieldsFragment>
+}
+
+export type TerminatedLeaderEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  penalty?: Types.Maybe<any>
+  rationale?: Types.Maybe<string>
+  group: { name: string }
+  worker: { id: string; runtimeId: number }
+}
+
+export type GetTerminatedLeaderEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetTerminatedLeaderEventsByEventIdsQuery = {
+  terminatedLeaderEvents: Array<TerminatedLeaderEventFieldsFragment>
+}
+
+export type LeaderUnsetEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  group: { name: string }
+  leader: { id: string; runtimeId: number }
+}
+
+export type GetLeaderUnsetEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetLeaderUnsetEventsByEventIdsQuery = { leaderUnsetEvents: Array<LeaderUnsetEventFieldsFragment> }
+
+export type BudgetSetEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  newBudget: any
+  group: { name: string }
+}
+
+export type GetBudgetSetEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetBudgetSetEventsByEventIdsQuery = { budgetSetEvents: Array<BudgetSetEventFieldsFragment> }
+
+export type BudgetSpendingEventFieldsFragment = {
+  id: string
+  createdAt: any
+  inBlock: number
+  network: Types.Network
+  inExtrinsic?: Types.Maybe<string>
+  indexInBlock: number
+  reciever: string
+  amount: any
+  rationale?: Types.Maybe<string>
+  group: { name: string }
+}
+
+export type GetBudgetSpendingEventsByEventIdsQueryVariables = Types.Exact<{
+  eventIds?: Types.Maybe<Array<Types.Scalars['ID']> | Types.Scalars['ID']>
+}>
+
+export type GetBudgetSpendingEventsByEventIdsQuery = { budgetSpendingEvents: Array<BudgetSpendingEventFieldsFragment> }
+
+export const MemberMetadataFields = gql`
+  fragment MemberMetadataFields on MemberMetadata {
+    name
+    about
+  }
+`
+export const MembershipFields = gql`
+  fragment MembershipFields on Membership {
+    id
+    handle
+    metadata {
+      ...MemberMetadataFields
+    }
+    controllerAccount
+    rootAccount
+    entry {
+      __typename
+      ... on MembershipEntryPaid {
+        membershipBoughtEvent {
+          id
+        }
+      }
+      ... on MembershipEntryInvited {
+        memberInvitedEvent {
+          id
+        }
+      }
+    }
+    isVerified
+    inviteCount
+    invitedBy {
+      id
+    }
+    invitees {
+      id
+    }
+    boundAccounts
+  }
+  ${MemberMetadataFields}
+`
+export const MembershipSystemSnapshotFields = gql`
+  fragment MembershipSystemSnapshotFields on MembershipSystemSnapshot {
+    createdAt
+    snapshotBlock
+    referralCut
+    invitedInitialBalance
+    defaultInviteCount
+    membershipPrice
+  }
+`
+export const MembershipBoughtEventFields = gql`
+  fragment MembershipBoughtEventFields on MembershipBoughtEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    newMember {
+      id
+    }
+    rootAccount
+    controllerAccount
+    handle
+    metadata {
+      ...MemberMetadataFields
+    }
+    referrer {
+      id
+    }
+  }
+  ${MemberMetadataFields}
+`
+export const MemberProfileUpdatedEventFields = gql`
+  fragment MemberProfileUpdatedEventFields on MemberProfileUpdatedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    member {
+      id
+    }
+    newHandle
+    newMetadata {
+      name
+      about
+    }
+  }
+`
+export const MemberAccountsUpdatedEventFields = gql`
+  fragment MemberAccountsUpdatedEventFields on MemberAccountsUpdatedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    member {
+      id
+    }
+    newRootAccount
+    newControllerAccount
+  }
+`
+export const MemberInvitedEventFields = gql`
+  fragment MemberInvitedEventFields on MemberInvitedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    invitingMember {
+      id
+    }
+    newMember {
+      id
+    }
+    rootAccount
+    controllerAccount
+    handle
+    metadata {
+      ...MemberMetadataFields
+    }
+  }
+  ${MemberMetadataFields}
+`
+export const InvitesTransferredEventFields = gql`
+  fragment InvitesTransferredEventFields on InvitesTransferredEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    sourceMember {
+      id
+    }
+    targetMember {
+      id
+    }
+    numberOfInvites
+  }
+`
+export const StakingAccountAddedEventFields = gql`
+  fragment StakingAccountAddedEventFields on StakingAccountAddedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    member {
+      id
+    }
+    account
+  }
+`
+export const StakingAccountConfirmedEventFields = gql`
+  fragment StakingAccountConfirmedEventFields on StakingAccountConfirmedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    member {
+      id
+    }
+    account
+  }
+`
+export const StakingAccountRemovedEventFields = gql`
+  fragment StakingAccountRemovedEventFields on StakingAccountRemovedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    member {
+      id
+    }
+    account
+  }
+`
+export const ReferralCutUpdatedEventFields = gql`
+  fragment ReferralCutUpdatedEventFields on ReferralCutUpdatedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    newValue
+  }
+`
+export const MembershipPriceUpdatedEventFields = gql`
+  fragment MembershipPriceUpdatedEventFields on MembershipPriceUpdatedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    newPrice
+  }
+`
+export const InitialInvitationBalanceUpdatedEventFields = gql`
+  fragment InitialInvitationBalanceUpdatedEventFields on InitialInvitationBalanceUpdatedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    newInitialBalance
+  }
+`
+export const InitialInvitationCountUpdatedEventFields = gql`
+  fragment InitialInvitationCountUpdatedEventFields on InitialInvitationCountUpdatedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    newInitialInvitationCount
+  }
+`
+export const ApplicationBasicFields = gql`
+  fragment ApplicationBasicFields on WorkingGroupApplication {
+    id
+    runtimeId
+    status {
+      __typename
+      ... on ApplicationStatusCancelled {
+        openingCanceledEvent {
+          id
+        }
+      }
+      ... on ApplicationStatusWithdrawn {
+        applicationWithdrawnEvent {
+          id
+        }
+      }
+      ... on ApplicationStatusAccepted {
+        openingFilledEvent {
+          id
+        }
+      }
+      ... on ApplicationStatusRejected {
+        openingFilledEvent {
+          id
+        }
+      }
+    }
+  }
+`
+export const OpeningStatusFields = gql`
+  fragment OpeningStatusFields on WorkingGroupOpeningStatus {
+    __typename
+    ... on OpeningStatusFilled {
+      openingFilledEvent {
+        id
+      }
+    }
+    ... on OpeningStatusCancelled {
+      openingCanceledEvent {
+        id
+      }
+    }
+  }
+`
+export const ApplicationFormQuestionFields = gql`
+  fragment ApplicationFormQuestionFields on ApplicationFormQuestion {
+    question
+    type
+    index
+  }
+`
+export const OpeningMetadataFields = gql`
+  fragment OpeningMetadataFields on WorkingGroupOpeningMetadata {
+    shortDescription
+    description
+    hiringLimit
+    expectedEnding
+    applicationDetails
+    applicationFormQuestions {
+      ...ApplicationFormQuestionFields
+    }
+  }
+  ${ApplicationFormQuestionFields}
+`
+export const OpeningFields = gql`
+  fragment OpeningFields on WorkingGroupOpening {
+    id
+    runtimeId
+    group {
+      name
+    }
+    applications {
+      ...ApplicationBasicFields
+    }
+    type
+    status {
+      ...OpeningStatusFields
+    }
+    metadata {
+      ...OpeningMetadataFields
+    }
+    stakeAmount
+    unstakingPeriod
+    rewardPerBlock
+    createdInEvent {
+      id
+    }
+  }
+  ${ApplicationBasicFields}
+  ${OpeningStatusFields}
+  ${OpeningMetadataFields}
+`
+export const ApplicationFields = gql`
+  fragment ApplicationFields on WorkingGroupApplication {
+    ...ApplicationBasicFields
+    createdInEvent {
+      id
+    }
+    opening {
+      id
+      runtimeId
+    }
+    applicant {
+      id
+    }
+    roleAccount
+    rewardAccount
+    stakingAccount
+    answers {
+      question {
+        question
+      }
+      answer
+    }
+    stake
+  }
+  ${ApplicationBasicFields}
+`
+export const WorkingGroupMetadataFields = gql`
+  fragment WorkingGroupMetadataFields on WorkingGroupMetadata {
+    id
+    status
+    statusMessage
+    about
+    description
+    setInEvent {
+      id
+    }
+  }
+`
+export const WorkingGroupFields = gql`
+  fragment WorkingGroupFields on WorkingGroup {
+    id
+    name
+    metadata {
+      ...WorkingGroupMetadataFields
+    }
+    leader {
+      id
+      runtimeId
+    }
+    budget
+  }
+  ${WorkingGroupMetadataFields}
+`
+export const UpcomingOpeningFields = gql`
+  fragment UpcomingOpeningFields on UpcomingWorkingGroupOpening {
+    id
+    group {
+      name
+    }
+    metadata {
+      ...OpeningMetadataFields
+    }
+    expectedStart
+    stakeAmount
+    rewardPerBlock
+    createdInEvent {
+      id
+    }
+    createdAt
+  }
+  ${OpeningMetadataFields}
+`
+export const AppliedOnOpeningEventFields = gql`
+  fragment AppliedOnOpeningEventFields on AppliedOnOpeningEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    opening {
+      id
+      runtimeId
+    }
+    application {
+      id
+      runtimeId
+    }
+  }
+`
+export const OpeningAddedEventFields = gql`
+  fragment OpeningAddedEventFields on OpeningAddedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    opening {
+      id
+      runtimeId
+    }
+  }
+`
+export const LeaderSetEventFields = gql`
+  fragment LeaderSetEventFields on LeaderSetEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    worker {
+      id
+      runtimeId
+    }
+  }
+`
+export const WorkerFields = gql`
+  fragment WorkerFields on Worker {
+    id
+    runtimeId
+    group {
+      name
+    }
+    membership {
+      id
+    }
+    roleAccount
+    rewardAccount
+    stakeAccount
+    status {
+      __typename
+      ... on WorkerStatusLeft {
+        workerStartedLeavingEvent {
+          id
+        }
+        workerExitedEvent {
+          id
+        }
+      }
+      ... on WorkerStatusTerminated {
+        terminatedWorkerEvent {
+          id
+        }
+      }
+    }
+    isLead
+    stake
+    payouts {
+      id
+    }
+    slashes {
+      id
+    }
+    entry {
+      id
+    }
+    application {
+      ...ApplicationBasicFields
+    }
+    storage
+    rewardPerBlock
+    missingRewardAmount
+  }
+  ${ApplicationBasicFields}
+`
+export const OpeningFilledEventFields = gql`
+  fragment OpeningFilledEventFields on OpeningFilledEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    opening {
+      id
+      runtimeId
+    }
+    workersHired {
+      ...WorkerFields
+    }
+  }
+  ${WorkerFields}
+`
+export const ApplicationWithdrawnEventFields = gql`
+  fragment ApplicationWithdrawnEventFields on ApplicationWithdrawnEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    application {
+      id
+      runtimeId
+    }
+  }
+`
+export const OpeningCanceledEventFields = gql`
+  fragment OpeningCanceledEventFields on OpeningCanceledEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    opening {
+      id
+      runtimeId
+    }
+  }
+`
+export const StatusTextChangedEventFields = gql`
+  fragment StatusTextChangedEventFields on StatusTextChangedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    metadata
+    result {
+      __typename
+      ... on UpcomingOpeningAdded {
+        upcomingOpeningId
+      }
+      ... on UpcomingOpeningRemoved {
+        upcomingOpeningId
+      }
+      ... on WorkingGroupMetadataSet {
+        metadata {
+          id
+        }
+      }
+      ... on InvalidActionMetadata {
+        reason
+      }
+    }
+  }
+`
+export const WorkerRoleAccountUpdatedEventFields = gql`
+  fragment WorkerRoleAccountUpdatedEventFields on WorkerRoleAccountUpdatedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    worker {
+      id
+      runtimeId
+    }
+    newRoleAccount
+  }
+`
+export const WorkerRewardAccountUpdatedEventFields = gql`
+  fragment WorkerRewardAccountUpdatedEventFields on WorkerRewardAccountUpdatedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    worker {
+      id
+      runtimeId
+    }
+    newRewardAccount
+  }
+`
+export const StakeIncreasedEventFields = gql`
+  fragment StakeIncreasedEventFields on StakeIncreasedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    worker {
+      id
+      runtimeId
+    }
+    amount
+  }
+`
+export const WorkerStartedLeavingEventFields = gql`
+  fragment WorkerStartedLeavingEventFields on WorkerStartedLeavingEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    worker {
+      id
+      runtimeId
+    }
+    rationale
+  }
+`
+export const WorkerRewardAmountUpdatedEventFields = gql`
+  fragment WorkerRewardAmountUpdatedEventFields on WorkerRewardAmountUpdatedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    worker {
+      id
+      runtimeId
+    }
+    newRewardPerBlock
+  }
+`
+export const StakeSlashedEventFields = gql`
+  fragment StakeSlashedEventFields on StakeSlashedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    worker {
+      id
+      runtimeId
+    }
+    requestedAmount
+    slashedAmount
+    rationale
+  }
+`
+export const StakeDecreasedEventFields = gql`
+  fragment StakeDecreasedEventFields on StakeDecreasedEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    worker {
+      id
+      runtimeId
+    }
+    amount
+  }
+`
+export const TerminatedWorkerEventFields = gql`
+  fragment TerminatedWorkerEventFields on TerminatedWorkerEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    worker {
+      id
+      runtimeId
+    }
+    penalty
+    rationale
+  }
+`
+export const TerminatedLeaderEventFields = gql`
+  fragment TerminatedLeaderEventFields on TerminatedLeaderEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    worker {
+      id
+      runtimeId
+    }
+    penalty
+    rationale
+  }
+`
+export const LeaderUnsetEventFields = gql`
+  fragment LeaderUnsetEventFields on LeaderUnsetEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    leader {
+      id
+      runtimeId
+    }
+  }
+`
+export const BudgetSetEventFields = gql`
+  fragment BudgetSetEventFields on BudgetSetEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    newBudget
+  }
+`
+export const BudgetSpendingEventFields = gql`
+  fragment BudgetSpendingEventFields on BudgetSpendingEvent {
+    id
+    createdAt
+    inBlock
+    network
+    inExtrinsic
+    indexInBlock
+    group {
+      name
+    }
+    reciever
+    amount
+    rationale
+  }
+`
+export const GetMemberById = gql`
+  query getMemberById($id: ID!) {
+    membershipByUniqueInput(where: { id: $id }) {
+      ...MembershipFields
+    }
+  }
+  ${MembershipFields}
+`
+export const GetMembersByIds = gql`
+  query getMembersByIds($ids: [ID!]) {
+    memberships(where: { id_in: $ids }) {
+      ...MembershipFields
+    }
+  }
+  ${MembershipFields}
+`
+export const GetMembershipSystemSnapshotAt = gql`
+  query getMembershipSystemSnapshotAt($time: DateTime!) {
+    membershipSystemSnapshots(where: { createdAt_eq: $time }, orderBy: createdAt_DESC, limit: 1) {
+      ...MembershipSystemSnapshotFields
+    }
+  }
+  ${MembershipSystemSnapshotFields}
+`
+export const GetMembershipSystemSnapshotBefore = gql`
+  query getMembershipSystemSnapshotBefore($time: DateTime!) {
+    membershipSystemSnapshots(where: { createdAt_lt: $time }, orderBy: createdAt_DESC, limit: 1) {
+      ...MembershipSystemSnapshotFields
+    }
+  }
+  ${MembershipSystemSnapshotFields}
+`
+export const GetMembershipBoughtEventsByEventIds = gql`
+  query getMembershipBoughtEventsByEventIds($eventIds: [ID!]) {
+    membershipBoughtEvents(where: { id_in: $eventIds }) {
+      ...MembershipBoughtEventFields
+    }
+  }
+  ${MembershipBoughtEventFields}
+`
+export const GetMemberProfileUpdatedEventsByMemberId = gql`
+  query getMemberProfileUpdatedEventsByMemberId($memberId: ID!) {
+    memberProfileUpdatedEvents(where: { member: { id_eq: $memberId } }) {
+      ...MemberProfileUpdatedEventFields
+    }
+  }
+  ${MemberProfileUpdatedEventFields}
+`
+export const GetMemberAccountsUpdatedEventsByMemberId = gql`
+  query getMemberAccountsUpdatedEventsByMemberId($memberId: ID!) {
+    memberAccountsUpdatedEvents(where: { member: { id_eq: $memberId } }) {
+      ...MemberAccountsUpdatedEventFields
+    }
+  }
+  ${MemberAccountsUpdatedEventFields}
+`
+export const GetMemberInvitedEventsByEventIds = gql`
+  query getMemberInvitedEventsByEventIds($eventIds: [ID!]) {
+    memberInvitedEvents(where: { id_in: $eventIds }) {
+      ...MemberInvitedEventFields
+    }
+  }
+  ${MemberInvitedEventFields}
+`
+export const GetInvitesTransferredEventsBySourceMemberId = gql`
+  query getInvitesTransferredEventsBySourceMemberId($sourceMemberId: ID!) {
+    invitesTransferredEvents(where: { sourceMember: { id_eq: $sourceMemberId } }) {
+      ...InvitesTransferredEventFields
+    }
+  }
+  ${InvitesTransferredEventFields}
+`
+export const GetStakingAccountAddedEventsByMemberId = gql`
+  query getStakingAccountAddedEventsByMemberId($memberId: ID!) {
+    stakingAccountAddedEvents(where: { member: { id_eq: $memberId } }) {
+      ...StakingAccountAddedEventFields
+    }
+  }
+  ${StakingAccountAddedEventFields}
+`
+export const GetStakingAccountConfirmedEventsByMemberId = gql`
+  query getStakingAccountConfirmedEventsByMemberId($memberId: ID!) {
+    stakingAccountConfirmedEvents(where: { member: { id_eq: $memberId } }) {
+      ...StakingAccountConfirmedEventFields
+    }
+  }
+  ${StakingAccountConfirmedEventFields}
+`
+export const GetStakingAccountRemovedEventsByMemberId = gql`
+  query getStakingAccountRemovedEventsByMemberId($memberId: ID!) {
+    stakingAccountRemovedEvents(where: { member: { id_eq: $memberId } }) {
+      ...StakingAccountRemovedEventFields
+    }
+  }
+  ${StakingAccountRemovedEventFields}
+`
+export const GetReferralCutUpdatedEventsByEventId = gql`
+  query getReferralCutUpdatedEventsByEventId($eventId: ID!) {
+    referralCutUpdatedEvents(where: { id_eq: $eventId }) {
+      ...ReferralCutUpdatedEventFields
+    }
+  }
+  ${ReferralCutUpdatedEventFields}
+`
+export const GetMembershipPriceUpdatedEventsByEventId = gql`
+  query getMembershipPriceUpdatedEventsByEventId($eventId: ID!) {
+    membershipPriceUpdatedEvents(where: { id_eq: $eventId }) {
+      ...MembershipPriceUpdatedEventFields
+    }
+  }
+  ${MembershipPriceUpdatedEventFields}
+`
+export const GetInitialInvitationBalanceUpdatedEventsByEventId = gql`
+  query getInitialInvitationBalanceUpdatedEventsByEventId($eventId: ID!) {
+    initialInvitationBalanceUpdatedEvents(where: { id_eq: $eventId }) {
+      ...InitialInvitationBalanceUpdatedEventFields
+    }
+  }
+  ${InitialInvitationBalanceUpdatedEventFields}
+`
+export const GetInitialInvitationCountUpdatedEventsByEventId = gql`
+  query getInitialInvitationCountUpdatedEventsByEventId($eventId: ID!) {
+    initialInvitationCountUpdatedEvents(where: { id_eq: $eventId }) {
+      ...InitialInvitationCountUpdatedEventFields
+    }
+  }
+  ${InitialInvitationCountUpdatedEventFields}
+`
+export const GetOpeningById = gql`
+  query getOpeningById($openingId: ID!) {
+    workingGroupOpeningByUniqueInput(where: { id: $openingId }) {
+      ...OpeningFields
+    }
+  }
+  ${OpeningFields}
+`
+export const GetOpeningsByIds = gql`
+  query getOpeningsByIds($openingIds: [ID!]) {
+    workingGroupOpenings(where: { id_in: $openingIds }) {
+      ...OpeningFields
+    }
+  }
+  ${OpeningFields}
+`
+export const GetApplicationById = gql`
+  query getApplicationById($applicationId: ID!) {
+    workingGroupApplicationByUniqueInput(where: { id: $applicationId }) {
+      ...ApplicationFields
+    }
+  }
+  ${ApplicationFields}
+`
+export const GetApplicationsByIds = gql`
+  query getApplicationsByIds($applicationIds: [ID!]) {
+    workingGroupApplications(where: { id_in: $applicationIds }) {
+      ...ApplicationFields
+    }
+  }
+  ${ApplicationFields}
+`
+export const GetWorkingGroupByName = gql`
+  query getWorkingGroupByName($name: String!) {
+    workingGroupByUniqueInput(where: { name: $name }) {
+      ...WorkingGroupFields
+    }
+  }
+  ${WorkingGroupFields}
+`
+export const GetUpcomingOpeningById = gql`
+  query getUpcomingOpeningById($id: ID!) {
+    upcomingWorkingGroupOpeningByUniqueInput(where: { id: $id }) {
+      ...UpcomingOpeningFields
+    }
+  }
+  ${UpcomingOpeningFields}
+`
+export const GetUpcomingOpeningsByCreatedInEventIds = gql`
+  query getUpcomingOpeningsByCreatedInEventIds($createdInEventIds: [ID!]) {
+    upcomingWorkingGroupOpenings(where: { createdInEvent: { id_in: $createdInEventIds } }) {
+      ...UpcomingOpeningFields
+    }
+  }
+  ${UpcomingOpeningFields}
+`
+export const GetWorkingGroupMetadataSnapshotsByTimeAsc = gql`
+  query getWorkingGroupMetadataSnapshotsByTimeAsc($groupId: ID!) {
+    workingGroupMetadata(where: { group: { id_eq: $groupId } }, orderBy: createdAt_ASC) {
+      ...WorkingGroupMetadataFields
+    }
+  }
+  ${WorkingGroupMetadataFields}
+`
+export const GetWorkersByRuntimeIds = gql`
+  query getWorkersByRuntimeIds($workerIds: [Int!], $groupId: ID!) {
+    workers(where: { runtimeId_in: $workerIds, group: { id_eq: $groupId } }) {
+      ...WorkerFields
+    }
+  }
+  ${WorkerFields}
+`
+export const GetAppliedOnOpeningEventsByEventIds = gql`
+  query getAppliedOnOpeningEventsByEventIds($eventIds: [ID!]) {
+    appliedOnOpeningEvents(where: { id_in: $eventIds }) {
+      ...AppliedOnOpeningEventFields
+    }
+  }
+  ${AppliedOnOpeningEventFields}
+`
+export const GetOpeningAddedEventsByEventIds = gql`
+  query getOpeningAddedEventsByEventIds($eventIds: [ID!]) {
+    openingAddedEvents(where: { id_in: $eventIds }) {
+      ...OpeningAddedEventFields
+    }
+  }
+  ${OpeningAddedEventFields}
+`
+export const GetLeaderSetEventsByEventIds = gql`
+  query getLeaderSetEventsByEventIds($eventIds: [ID!]) {
+    leaderSetEvents(where: { id_in: $eventIds }) {
+      ...LeaderSetEventFields
+    }
+  }
+  ${LeaderSetEventFields}
+`
+export const GetOpeningFilledEventsByEventIds = gql`
+  query getOpeningFilledEventsByEventIds($eventIds: [ID!]) {
+    openingFilledEvents(where: { id_in: $eventIds }) {
+      ...OpeningFilledEventFields
+    }
+  }
+  ${OpeningFilledEventFields}
+`
+export const GetApplicationWithdrawnEventsByEventIds = gql`
+  query getApplicationWithdrawnEventsByEventIds($eventIds: [ID!]) {
+    applicationWithdrawnEvents(where: { id_in: $eventIds }) {
+      ...ApplicationWithdrawnEventFields
+    }
+  }
+  ${ApplicationWithdrawnEventFields}
+`
+export const GetOpeningCancelledEventsByEventIds = gql`
+  query getOpeningCancelledEventsByEventIds($eventIds: [ID!]) {
+    openingCanceledEvents(where: { id_in: $eventIds }) {
+      ...OpeningCanceledEventFields
+    }
+  }
+  ${OpeningCanceledEventFields}
+`
+export const GetStatusTextChangedEventsByEventIds = gql`
+  query getStatusTextChangedEventsByEventIds($eventIds: [ID!]) {
+    statusTextChangedEvents(where: { id_in: $eventIds }) {
+      ...StatusTextChangedEventFields
+    }
+  }
+  ${StatusTextChangedEventFields}
+`
+export const GetWorkerRoleAccountUpdatedEventsByEventIds = gql`
+  query getWorkerRoleAccountUpdatedEventsByEventIds($eventIds: [ID!]) {
+    workerRoleAccountUpdatedEvents(where: { id_in: $eventIds }) {
+      ...WorkerRoleAccountUpdatedEventFields
+    }
+  }
+  ${WorkerRoleAccountUpdatedEventFields}
+`
+export const GetWorkerRewardAccountUpdatedEventsByEventIds = gql`
+  query getWorkerRewardAccountUpdatedEventsByEventIds($eventIds: [ID!]) {
+    workerRewardAccountUpdatedEvents(where: { id_in: $eventIds }) {
+      ...WorkerRewardAccountUpdatedEventFields
+    }
+  }
+  ${WorkerRewardAccountUpdatedEventFields}
+`
+export const GetStakeIncreasedEventsByEventIds = gql`
+  query getStakeIncreasedEventsByEventIds($eventIds: [ID!]) {
+    stakeIncreasedEvents(where: { id_in: $eventIds }) {
+      ...StakeIncreasedEventFields
+    }
+  }
+  ${StakeIncreasedEventFields}
+`
+export const GetWorkerStartedLeavingEventsByEventIds = gql`
+  query getWorkerStartedLeavingEventsByEventIds($eventIds: [ID!]) {
+    workerStartedLeavingEvents(where: { id_in: $eventIds }) {
+      ...WorkerStartedLeavingEventFields
+    }
+  }
+  ${WorkerStartedLeavingEventFields}
+`
+export const GetWorkerRewardAmountUpdatedEventsByEventIds = gql`
+  query getWorkerRewardAmountUpdatedEventsByEventIds($eventIds: [ID!]) {
+    workerRewardAmountUpdatedEvents(where: { id_in: $eventIds }) {
+      ...WorkerRewardAmountUpdatedEventFields
+    }
+  }
+  ${WorkerRewardAmountUpdatedEventFields}
+`
+export const GetStakeSlashedEventsByEventIds = gql`
+  query getStakeSlashedEventsByEventIds($eventIds: [ID!]) {
+    stakeSlashedEvents(where: { id_in: $eventIds }) {
+      ...StakeSlashedEventFields
+    }
+  }
+  ${StakeSlashedEventFields}
+`
+export const GetStakeDecreasedEventsByEventIds = gql`
+  query getStakeDecreasedEventsByEventIds($eventIds: [ID!]) {
+    stakeDecreasedEvents(where: { id_in: $eventIds }) {
+      ...StakeDecreasedEventFields
+    }
+  }
+  ${StakeDecreasedEventFields}
+`
+export const GetTerminatedWorkerEventsByEventIds = gql`
+  query getTerminatedWorkerEventsByEventIds($eventIds: [ID!]) {
+    terminatedWorkerEvents(where: { id_in: $eventIds }) {
+      ...TerminatedWorkerEventFields
+    }
+  }
+  ${TerminatedWorkerEventFields}
+`
+export const GetTerminatedLeaderEventsByEventIds = gql`
+  query getTerminatedLeaderEventsByEventIds($eventIds: [ID!]) {
+    terminatedLeaderEvents(where: { id_in: $eventIds }) {
+      ...TerminatedLeaderEventFields
+    }
+  }
+  ${TerminatedLeaderEventFields}
+`
+export const GetLeaderUnsetEventsByEventIds = gql`
+  query getLeaderUnsetEventsByEventIds($eventIds: [ID!]) {
+    leaderUnsetEvents(where: { id_in: $eventIds }) {
+      ...LeaderUnsetEventFields
+    }
+  }
+  ${LeaderUnsetEventFields}
+`
+export const GetBudgetSetEventsByEventIds = gql`
+  query getBudgetSetEventsByEventIds($eventIds: [ID!]) {
+    budgetSetEvents(where: { id_in: $eventIds }) {
+      ...BudgetSetEventFields
+    }
+  }
+  ${BudgetSetEventFields}
+`
+export const GetBudgetSpendingEventsByEventIds = gql`
+  query getBudgetSpendingEventsByEventIds($eventIds: [ID!]) {
+    budgetSpendingEvents(where: { id_in: $eventIds }) {
+      ...BudgetSpendingEventFields
+    }
+  }
+  ${BudgetSpendingEventFields}
+`

+ 9255 - 0
tests/integration-tests/src/graphql/generated/schema.ts

@@ -0,0 +1,9255 @@
+export type Maybe<T> = T | null
+export type Exact<T extends { [key: string]: unknown }> = { [K in keyof T]: T[K] }
+export type MakeOptional<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]?: Maybe<T[SubKey]> }
+export type MakeMaybe<T, K extends keyof T> = Omit<T, K> & { [SubKey in K]: Maybe<T[SubKey]> }
+/** All built-in and custom scalars, mapped to their actual values */
+export type Scalars = {
+  ID: string
+  String: string
+  Boolean: boolean
+  Int: number
+  Float: number
+  /** The javascript `Date` as string. Type represents date and time as the ISO Date string. */
+  DateTime: any
+  /** GraphQL representation of BigInt */
+  BigInt: any
+  /** The `JSONObject` scalar type represents JSON objects as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). */
+  JSONObject: any
+}
+
+export type ApplicationFormQuestion = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  openingMetadata: WorkingGroupOpeningMetadata
+  openingMetadataId: Scalars['String']
+  /** The question itself */
+  question?: Maybe<Scalars['String']>
+  /** Type of the question (UI answer input type) */
+  type: ApplicationFormQuestionType
+  /** Index of the question */
+  index: Scalars['Int']
+  applicationformquestionanswerquestion?: Maybe<Array<ApplicationFormQuestionAnswer>>
+}
+
+export type ApplicationFormQuestionAnswer = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  application: WorkingGroupApplication
+  applicationId: Scalars['String']
+  question: ApplicationFormQuestion
+  questionId: Scalars['String']
+  /** Applicant's answer */
+  answer: Scalars['String']
+}
+
+export type ApplicationFormQuestionAnswerConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<ApplicationFormQuestionAnswerEdge>
+  pageInfo: PageInfo
+}
+
+export type ApplicationFormQuestionAnswerCreateInput = {
+  application: Scalars['ID']
+  question: Scalars['ID']
+  answer: Scalars['String']
+}
+
+export type ApplicationFormQuestionAnswerEdge = {
+  node: ApplicationFormQuestionAnswer
+  cursor: Scalars['String']
+}
+
+export enum ApplicationFormQuestionAnswerOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  ApplicationAsc = 'application_ASC',
+  ApplicationDesc = 'application_DESC',
+  QuestionAsc = 'question_ASC',
+  QuestionDesc = 'question_DESC',
+  AnswerAsc = 'answer_ASC',
+  AnswerDesc = 'answer_DESC',
+}
+
+export type ApplicationFormQuestionAnswerUpdateInput = {
+  application?: Maybe<Scalars['ID']>
+  question?: Maybe<Scalars['ID']>
+  answer?: Maybe<Scalars['String']>
+}
+
+export type ApplicationFormQuestionAnswerWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  application_eq?: Maybe<Scalars['ID']>
+  application_in?: Maybe<Array<Scalars['ID']>>
+  question_eq?: Maybe<Scalars['ID']>
+  question_in?: Maybe<Array<Scalars['ID']>>
+  answer_eq?: Maybe<Scalars['String']>
+  answer_contains?: Maybe<Scalars['String']>
+  answer_startsWith?: Maybe<Scalars['String']>
+  answer_endsWith?: Maybe<Scalars['String']>
+  answer_in?: Maybe<Array<Scalars['String']>>
+  application?: Maybe<WorkingGroupApplicationWhereInput>
+  question?: Maybe<ApplicationFormQuestionWhereInput>
+  AND?: Maybe<Array<ApplicationFormQuestionAnswerWhereInput>>
+  OR?: Maybe<Array<ApplicationFormQuestionAnswerWhereInput>>
+}
+
+export type ApplicationFormQuestionAnswerWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type ApplicationFormQuestionConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<ApplicationFormQuestionEdge>
+  pageInfo: PageInfo
+}
+
+export type ApplicationFormQuestionCreateInput = {
+  openingMetadata: Scalars['ID']
+  question?: Maybe<Scalars['String']>
+  type: ApplicationFormQuestionType
+  index: Scalars['Float']
+}
+
+export type ApplicationFormQuestionEdge = {
+  node: ApplicationFormQuestion
+  cursor: Scalars['String']
+}
+
+export enum ApplicationFormQuestionOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  OpeningMetadataAsc = 'openingMetadata_ASC',
+  OpeningMetadataDesc = 'openingMetadata_DESC',
+  QuestionAsc = 'question_ASC',
+  QuestionDesc = 'question_DESC',
+  TypeAsc = 'type_ASC',
+  TypeDesc = 'type_DESC',
+  IndexAsc = 'index_ASC',
+  IndexDesc = 'index_DESC',
+}
+
+export enum ApplicationFormQuestionType {
+  Text = 'TEXT',
+  Textarea = 'TEXTAREA',
+}
+
+export type ApplicationFormQuestionUpdateInput = {
+  openingMetadata?: Maybe<Scalars['ID']>
+  question?: Maybe<Scalars['String']>
+  type?: Maybe<ApplicationFormQuestionType>
+  index?: Maybe<Scalars['Float']>
+}
+
+export type ApplicationFormQuestionWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  openingMetadata_eq?: Maybe<Scalars['ID']>
+  openingMetadata_in?: Maybe<Array<Scalars['ID']>>
+  question_eq?: Maybe<Scalars['String']>
+  question_contains?: Maybe<Scalars['String']>
+  question_startsWith?: Maybe<Scalars['String']>
+  question_endsWith?: Maybe<Scalars['String']>
+  question_in?: Maybe<Array<Scalars['String']>>
+  type_eq?: Maybe<ApplicationFormQuestionType>
+  type_in?: Maybe<Array<ApplicationFormQuestionType>>
+  index_eq?: Maybe<Scalars['Int']>
+  index_gt?: Maybe<Scalars['Int']>
+  index_gte?: Maybe<Scalars['Int']>
+  index_lt?: Maybe<Scalars['Int']>
+  index_lte?: Maybe<Scalars['Int']>
+  index_in?: Maybe<Array<Scalars['Int']>>
+  openingMetadata?: Maybe<WorkingGroupOpeningMetadataWhereInput>
+  applicationformquestionanswerquestion_none?: Maybe<ApplicationFormQuestionAnswerWhereInput>
+  applicationformquestionanswerquestion_some?: Maybe<ApplicationFormQuestionAnswerWhereInput>
+  applicationformquestionanswerquestion_every?: Maybe<ApplicationFormQuestionAnswerWhereInput>
+  AND?: Maybe<Array<ApplicationFormQuestionWhereInput>>
+  OR?: Maybe<Array<ApplicationFormQuestionWhereInput>>
+}
+
+export type ApplicationFormQuestionWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type ApplicationStatusAccepted = {
+  /** Related OpeningFilled event */
+  openingFilledEvent?: Maybe<OpeningFilledEvent>
+}
+
+export type ApplicationStatusCancelled = {
+  /** Related OpeningCanceled event */
+  openingCanceledEvent?: Maybe<OpeningCanceledEvent>
+}
+
+export type ApplicationStatusPending = {
+  phantom?: Maybe<Scalars['Int']>
+}
+
+export type ApplicationStatusPendingCreateInput = {
+  phantom?: Maybe<Scalars['Float']>
+}
+
+export type ApplicationStatusPendingUpdateInput = {
+  phantom?: Maybe<Scalars['Float']>
+}
+
+export type ApplicationStatusPendingWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  phantom_eq?: Maybe<Scalars['Int']>
+  phantom_gt?: Maybe<Scalars['Int']>
+  phantom_gte?: Maybe<Scalars['Int']>
+  phantom_lt?: Maybe<Scalars['Int']>
+  phantom_lte?: Maybe<Scalars['Int']>
+  phantom_in?: Maybe<Array<Scalars['Int']>>
+  AND?: Maybe<Array<ApplicationStatusPendingWhereInput>>
+  OR?: Maybe<Array<ApplicationStatusPendingWhereInput>>
+}
+
+export type ApplicationStatusPendingWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type ApplicationStatusRejected = {
+  /** Related OpeningFilled event */
+  openingFilledEvent?: Maybe<OpeningFilledEvent>
+}
+
+export type ApplicationStatusWithdrawn = {
+  /** Related ApplicationWithdrawn event */
+  applicationWithdrawnEvent?: Maybe<ApplicationWithdrawnEvent>
+}
+
+export type ApplicationWithdrawnEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  application: WorkingGroupApplication
+  applicationId: Scalars['String']
+}
+
+export type ApplicationWithdrawnEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<ApplicationWithdrawnEventEdge>
+  pageInfo: PageInfo
+}
+
+export type ApplicationWithdrawnEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  application: Scalars['ID']
+}
+
+export type ApplicationWithdrawnEventEdge = {
+  node: ApplicationWithdrawnEvent
+  cursor: Scalars['String']
+}
+
+export enum ApplicationWithdrawnEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  ApplicationAsc = 'application_ASC',
+  ApplicationDesc = 'application_DESC',
+}
+
+export type ApplicationWithdrawnEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  application?: Maybe<Scalars['ID']>
+}
+
+export type ApplicationWithdrawnEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  application_eq?: Maybe<Scalars['ID']>
+  application_in?: Maybe<Array<Scalars['ID']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  application?: Maybe<WorkingGroupApplicationWhereInput>
+  AND?: Maybe<Array<ApplicationWithdrawnEventWhereInput>>
+  OR?: Maybe<Array<ApplicationWithdrawnEventWhereInput>>
+}
+
+export type ApplicationWithdrawnEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type AppliedOnOpeningEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  opening: WorkingGroupOpening
+  openingId: Scalars['String']
+  application: WorkingGroupApplication
+  applicationId: Scalars['String']
+}
+
+export type AppliedOnOpeningEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<AppliedOnOpeningEventEdge>
+  pageInfo: PageInfo
+}
+
+export type AppliedOnOpeningEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  opening: Scalars['ID']
+  application: Scalars['ID']
+}
+
+export type AppliedOnOpeningEventEdge = {
+  node: AppliedOnOpeningEvent
+  cursor: Scalars['String']
+}
+
+export enum AppliedOnOpeningEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  OpeningAsc = 'opening_ASC',
+  OpeningDesc = 'opening_DESC',
+  ApplicationAsc = 'application_ASC',
+  ApplicationDesc = 'application_DESC',
+}
+
+export type AppliedOnOpeningEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  opening?: Maybe<Scalars['ID']>
+  application?: Maybe<Scalars['ID']>
+}
+
+export type AppliedOnOpeningEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  opening_eq?: Maybe<Scalars['ID']>
+  opening_in?: Maybe<Array<Scalars['ID']>>
+  application_eq?: Maybe<Scalars['ID']>
+  application_in?: Maybe<Array<Scalars['ID']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  opening?: Maybe<WorkingGroupOpeningWhereInput>
+  application?: Maybe<WorkingGroupApplicationWhereInput>
+  AND?: Maybe<Array<AppliedOnOpeningEventWhereInput>>
+  OR?: Maybe<Array<AppliedOnOpeningEventWhereInput>>
+}
+
+export type AppliedOnOpeningEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type BaseGraphQlObject = {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+}
+
+export type BaseModel = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+}
+
+export type BaseModelUuid = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+}
+
+export type BaseWhereInput = {
+  id_eq?: Maybe<Scalars['String']>
+  id_in?: Maybe<Array<Scalars['String']>>
+  createdAt_eq?: Maybe<Scalars['String']>
+  createdAt_lt?: Maybe<Scalars['String']>
+  createdAt_lte?: Maybe<Scalars['String']>
+  createdAt_gt?: Maybe<Scalars['String']>
+  createdAt_gte?: Maybe<Scalars['String']>
+  createdById_eq?: Maybe<Scalars['String']>
+  updatedAt_eq?: Maybe<Scalars['String']>
+  updatedAt_lt?: Maybe<Scalars['String']>
+  updatedAt_lte?: Maybe<Scalars['String']>
+  updatedAt_gt?: Maybe<Scalars['String']>
+  updatedAt_gte?: Maybe<Scalars['String']>
+  updatedById_eq?: Maybe<Scalars['String']>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['String']>
+  deletedAt_lt?: Maybe<Scalars['String']>
+  deletedAt_lte?: Maybe<Scalars['String']>
+  deletedAt_gt?: Maybe<Scalars['String']>
+  deletedAt_gte?: Maybe<Scalars['String']>
+  deletedById_eq?: Maybe<Scalars['String']>
+}
+
+export type BudgetSetEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  /** New working group budget */
+  newBudget: Scalars['BigInt']
+}
+
+export type BudgetSetEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<BudgetSetEventEdge>
+  pageInfo: PageInfo
+}
+
+export type BudgetSetEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  newBudget: Scalars['BigInt']
+}
+
+export type BudgetSetEventEdge = {
+  node: BudgetSetEvent
+  cursor: Scalars['String']
+}
+
+export enum BudgetSetEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  NewBudgetAsc = 'newBudget_ASC',
+  NewBudgetDesc = 'newBudget_DESC',
+}
+
+export type BudgetSetEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  newBudget?: Maybe<Scalars['BigInt']>
+}
+
+export type BudgetSetEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  newBudget_eq?: Maybe<Scalars['BigInt']>
+  newBudget_gt?: Maybe<Scalars['BigInt']>
+  newBudget_gte?: Maybe<Scalars['BigInt']>
+  newBudget_lt?: Maybe<Scalars['BigInt']>
+  newBudget_lte?: Maybe<Scalars['BigInt']>
+  newBudget_in?: Maybe<Array<Scalars['BigInt']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  AND?: Maybe<Array<BudgetSetEventWhereInput>>
+  OR?: Maybe<Array<BudgetSetEventWhereInput>>
+}
+
+export type BudgetSetEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type BudgetSpendingEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  /** Reciever account address */
+  reciever: Scalars['String']
+  /** Amount beeing spent */
+  amount: Scalars['BigInt']
+  /** Optional rationale */
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type BudgetSpendingEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<BudgetSpendingEventEdge>
+  pageInfo: PageInfo
+}
+
+export type BudgetSpendingEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  reciever: Scalars['String']
+  amount: Scalars['BigInt']
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type BudgetSpendingEventEdge = {
+  node: BudgetSpendingEvent
+  cursor: Scalars['String']
+}
+
+export enum BudgetSpendingEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  RecieverAsc = 'reciever_ASC',
+  RecieverDesc = 'reciever_DESC',
+  AmountAsc = 'amount_ASC',
+  AmountDesc = 'amount_DESC',
+  RationaleAsc = 'rationale_ASC',
+  RationaleDesc = 'rationale_DESC',
+}
+
+export type BudgetSpendingEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  reciever?: Maybe<Scalars['String']>
+  amount?: Maybe<Scalars['BigInt']>
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type BudgetSpendingEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  reciever_eq?: Maybe<Scalars['String']>
+  reciever_contains?: Maybe<Scalars['String']>
+  reciever_startsWith?: Maybe<Scalars['String']>
+  reciever_endsWith?: Maybe<Scalars['String']>
+  reciever_in?: Maybe<Array<Scalars['String']>>
+  amount_eq?: Maybe<Scalars['BigInt']>
+  amount_gt?: Maybe<Scalars['BigInt']>
+  amount_gte?: Maybe<Scalars['BigInt']>
+  amount_lt?: Maybe<Scalars['BigInt']>
+  amount_lte?: Maybe<Scalars['BigInt']>
+  amount_in?: Maybe<Array<Scalars['BigInt']>>
+  rationale_eq?: Maybe<Scalars['String']>
+  rationale_contains?: Maybe<Scalars['String']>
+  rationale_startsWith?: Maybe<Scalars['String']>
+  rationale_endsWith?: Maybe<Scalars['String']>
+  rationale_in?: Maybe<Array<Scalars['String']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  AND?: Maybe<Array<BudgetSpendingEventWhereInput>>
+  OR?: Maybe<Array<BudgetSpendingEventWhereInput>>
+}
+
+export type BudgetSpendingEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+/** Manages content ids, type and storage provider decision about it */
+export type DataObject = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Content owner */
+  owner: DataObjectOwner
+  /** Content added at */
+  addedAt: Scalars['Int']
+  /** Content type id */
+  typeId: Scalars['Int']
+  /** Content size in bytes */
+  size: Scalars['BigInt']
+  /** Storage provider id of the liaison */
+  liaisonId: Scalars['BigInt']
+  /** Storage provider as liaison judgment */
+  liaisonJudgement: LiaisonJudgement
+  /** IPFS content id */
+  ipfsContentId: Scalars['String']
+  /** Joystream runtime content */
+  joystreamContentId: Scalars['String']
+  membermetadataavatar?: Maybe<Array<MemberMetadata>>
+}
+
+export type DataObjectConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<DataObjectEdge>
+  pageInfo: PageInfo
+}
+
+export type DataObjectCreateInput = {
+  owner: Scalars['JSONObject']
+  addedAt: Scalars['Float']
+  typeId: Scalars['Float']
+  size: Scalars['BigInt']
+  liaisonId: Scalars['BigInt']
+  liaisonJudgement: LiaisonJudgement
+  ipfsContentId: Scalars['String']
+  joystreamContentId: Scalars['String']
+}
+
+export type DataObjectEdge = {
+  node: DataObject
+  cursor: Scalars['String']
+}
+
+export enum DataObjectOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  AddedAtAsc = 'addedAt_ASC',
+  AddedAtDesc = 'addedAt_DESC',
+  TypeIdAsc = 'typeId_ASC',
+  TypeIdDesc = 'typeId_DESC',
+  SizeAsc = 'size_ASC',
+  SizeDesc = 'size_DESC',
+  LiaisonIdAsc = 'liaisonId_ASC',
+  LiaisonIdDesc = 'liaisonId_DESC',
+  LiaisonJudgementAsc = 'liaisonJudgement_ASC',
+  LiaisonJudgementDesc = 'liaisonJudgement_DESC',
+  IpfsContentIdAsc = 'ipfsContentId_ASC',
+  IpfsContentIdDesc = 'ipfsContentId_DESC',
+  JoystreamContentIdAsc = 'joystreamContentId_ASC',
+  JoystreamContentIdDesc = 'joystreamContentId_DESC',
+}
+
+export type DataObjectOwner =
+  | DataObjectOwnerMember
+  | DataObjectOwnerChannel
+  | DataObjectOwnerDao
+  | DataObjectOwnerCouncil
+  | DataObjectOwnerWorkingGroup
+
+export type DataObjectOwnerChannel = {
+  /** Channel identifier */
+  channel: Scalars['BigInt']
+  /** Variant needs to have at least one property. This value is not used. */
+  dummy?: Maybe<Scalars['Int']>
+}
+
+export type DataObjectOwnerChannelCreateInput = {
+  channel: Scalars['BigInt']
+  dummy?: Maybe<Scalars['Float']>
+}
+
+export type DataObjectOwnerChannelUpdateInput = {
+  channel?: Maybe<Scalars['BigInt']>
+  dummy?: Maybe<Scalars['Float']>
+}
+
+export type DataObjectOwnerChannelWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  channel_eq?: Maybe<Scalars['BigInt']>
+  channel_gt?: Maybe<Scalars['BigInt']>
+  channel_gte?: Maybe<Scalars['BigInt']>
+  channel_lt?: Maybe<Scalars['BigInt']>
+  channel_lte?: Maybe<Scalars['BigInt']>
+  channel_in?: Maybe<Array<Scalars['BigInt']>>
+  dummy_eq?: Maybe<Scalars['Int']>
+  dummy_gt?: Maybe<Scalars['Int']>
+  dummy_gte?: Maybe<Scalars['Int']>
+  dummy_lt?: Maybe<Scalars['Int']>
+  dummy_lte?: Maybe<Scalars['Int']>
+  dummy_in?: Maybe<Array<Scalars['Int']>>
+  AND?: Maybe<Array<DataObjectOwnerChannelWhereInput>>
+  OR?: Maybe<Array<DataObjectOwnerChannelWhereInput>>
+}
+
+export type DataObjectOwnerChannelWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type DataObjectOwnerCouncil = {
+  /** Variant needs to have at least one property. This value is not used. */
+  dummy?: Maybe<Scalars['Int']>
+}
+
+export type DataObjectOwnerCouncilCreateInput = {
+  dummy?: Maybe<Scalars['Float']>
+}
+
+export type DataObjectOwnerCouncilUpdateInput = {
+  dummy?: Maybe<Scalars['Float']>
+}
+
+export type DataObjectOwnerCouncilWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  dummy_eq?: Maybe<Scalars['Int']>
+  dummy_gt?: Maybe<Scalars['Int']>
+  dummy_gte?: Maybe<Scalars['Int']>
+  dummy_lt?: Maybe<Scalars['Int']>
+  dummy_lte?: Maybe<Scalars['Int']>
+  dummy_in?: Maybe<Array<Scalars['Int']>>
+  AND?: Maybe<Array<DataObjectOwnerCouncilWhereInput>>
+  OR?: Maybe<Array<DataObjectOwnerCouncilWhereInput>>
+}
+
+export type DataObjectOwnerCouncilWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type DataObjectOwnerDao = {
+  /** DAO identifier */
+  dao: Scalars['BigInt']
+}
+
+export type DataObjectOwnerDaoCreateInput = {
+  dao: Scalars['BigInt']
+}
+
+export type DataObjectOwnerDaoUpdateInput = {
+  dao?: Maybe<Scalars['BigInt']>
+}
+
+export type DataObjectOwnerDaoWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  dao_eq?: Maybe<Scalars['BigInt']>
+  dao_gt?: Maybe<Scalars['BigInt']>
+  dao_gte?: Maybe<Scalars['BigInt']>
+  dao_lt?: Maybe<Scalars['BigInt']>
+  dao_lte?: Maybe<Scalars['BigInt']>
+  dao_in?: Maybe<Array<Scalars['BigInt']>>
+  AND?: Maybe<Array<DataObjectOwnerDaoWhereInput>>
+  OR?: Maybe<Array<DataObjectOwnerDaoWhereInput>>
+}
+
+export type DataObjectOwnerDaoWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type DataObjectOwnerMember = {
+  /** Member identifier */
+  member: Scalars['BigInt']
+  /** Variant needs to have at least one property. This value is not used. */
+  dummy?: Maybe<Scalars['Int']>
+}
+
+export type DataObjectOwnerMemberCreateInput = {
+  member: Scalars['BigInt']
+  dummy?: Maybe<Scalars['Float']>
+}
+
+export type DataObjectOwnerMemberUpdateInput = {
+  member?: Maybe<Scalars['BigInt']>
+  dummy?: Maybe<Scalars['Float']>
+}
+
+export type DataObjectOwnerMemberWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  member_eq?: Maybe<Scalars['BigInt']>
+  member_gt?: Maybe<Scalars['BigInt']>
+  member_gte?: Maybe<Scalars['BigInt']>
+  member_lt?: Maybe<Scalars['BigInt']>
+  member_lte?: Maybe<Scalars['BigInt']>
+  member_in?: Maybe<Array<Scalars['BigInt']>>
+  dummy_eq?: Maybe<Scalars['Int']>
+  dummy_gt?: Maybe<Scalars['Int']>
+  dummy_gte?: Maybe<Scalars['Int']>
+  dummy_lt?: Maybe<Scalars['Int']>
+  dummy_lte?: Maybe<Scalars['Int']>
+  dummy_in?: Maybe<Array<Scalars['Int']>>
+  AND?: Maybe<Array<DataObjectOwnerMemberWhereInput>>
+  OR?: Maybe<Array<DataObjectOwnerMemberWhereInput>>
+}
+
+export type DataObjectOwnerMemberWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type DataObjectOwnerWorkingGroup = {
+  /** Variant needs to have at least one property. This value is not used. */
+  dummy?: Maybe<Scalars['Int']>
+}
+
+export type DataObjectOwnerWorkingGroupCreateInput = {
+  dummy?: Maybe<Scalars['Float']>
+}
+
+export type DataObjectOwnerWorkingGroupUpdateInput = {
+  dummy?: Maybe<Scalars['Float']>
+}
+
+export type DataObjectOwnerWorkingGroupWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  dummy_eq?: Maybe<Scalars['Int']>
+  dummy_gt?: Maybe<Scalars['Int']>
+  dummy_gte?: Maybe<Scalars['Int']>
+  dummy_lt?: Maybe<Scalars['Int']>
+  dummy_lte?: Maybe<Scalars['Int']>
+  dummy_in?: Maybe<Array<Scalars['Int']>>
+  AND?: Maybe<Array<DataObjectOwnerWorkingGroupWhereInput>>
+  OR?: Maybe<Array<DataObjectOwnerWorkingGroupWhereInput>>
+}
+
+export type DataObjectOwnerWorkingGroupWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type DataObjectUpdateInput = {
+  owner?: Maybe<Scalars['JSONObject']>
+  addedAt?: Maybe<Scalars['Float']>
+  typeId?: Maybe<Scalars['Float']>
+  size?: Maybe<Scalars['BigInt']>
+  liaisonId?: Maybe<Scalars['BigInt']>
+  liaisonJudgement?: Maybe<LiaisonJudgement>
+  ipfsContentId?: Maybe<Scalars['String']>
+  joystreamContentId?: Maybe<Scalars['String']>
+}
+
+export type DataObjectWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  owner_json?: Maybe<Scalars['JSONObject']>
+  addedAt_eq?: Maybe<Scalars['Int']>
+  addedAt_gt?: Maybe<Scalars['Int']>
+  addedAt_gte?: Maybe<Scalars['Int']>
+  addedAt_lt?: Maybe<Scalars['Int']>
+  addedAt_lte?: Maybe<Scalars['Int']>
+  addedAt_in?: Maybe<Array<Scalars['Int']>>
+  typeId_eq?: Maybe<Scalars['Int']>
+  typeId_gt?: Maybe<Scalars['Int']>
+  typeId_gte?: Maybe<Scalars['Int']>
+  typeId_lt?: Maybe<Scalars['Int']>
+  typeId_lte?: Maybe<Scalars['Int']>
+  typeId_in?: Maybe<Array<Scalars['Int']>>
+  size_eq?: Maybe<Scalars['BigInt']>
+  size_gt?: Maybe<Scalars['BigInt']>
+  size_gte?: Maybe<Scalars['BigInt']>
+  size_lt?: Maybe<Scalars['BigInt']>
+  size_lte?: Maybe<Scalars['BigInt']>
+  size_in?: Maybe<Array<Scalars['BigInt']>>
+  liaisonId_eq?: Maybe<Scalars['BigInt']>
+  liaisonId_gt?: Maybe<Scalars['BigInt']>
+  liaisonId_gte?: Maybe<Scalars['BigInt']>
+  liaisonId_lt?: Maybe<Scalars['BigInt']>
+  liaisonId_lte?: Maybe<Scalars['BigInt']>
+  liaisonId_in?: Maybe<Array<Scalars['BigInt']>>
+  liaisonJudgement_eq?: Maybe<LiaisonJudgement>
+  liaisonJudgement_in?: Maybe<Array<LiaisonJudgement>>
+  ipfsContentId_eq?: Maybe<Scalars['String']>
+  ipfsContentId_contains?: Maybe<Scalars['String']>
+  ipfsContentId_startsWith?: Maybe<Scalars['String']>
+  ipfsContentId_endsWith?: Maybe<Scalars['String']>
+  ipfsContentId_in?: Maybe<Array<Scalars['String']>>
+  joystreamContentId_eq?: Maybe<Scalars['String']>
+  joystreamContentId_contains?: Maybe<Scalars['String']>
+  joystreamContentId_startsWith?: Maybe<Scalars['String']>
+  joystreamContentId_endsWith?: Maybe<Scalars['String']>
+  joystreamContentId_in?: Maybe<Array<Scalars['String']>>
+  membermetadataavatar_none?: Maybe<MemberMetadataWhereInput>
+  membermetadataavatar_some?: Maybe<MemberMetadataWhereInput>
+  membermetadataavatar_every?: Maybe<MemberMetadataWhereInput>
+  AND?: Maybe<Array<DataObjectWhereInput>>
+  OR?: Maybe<Array<DataObjectWhereInput>>
+}
+
+export type DataObjectWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type DeleteResponse = {
+  id: Scalars['ID']
+}
+
+export type Event = {
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+}
+
+export type EventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+}
+
+export enum EventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+}
+
+export type EventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+}
+
+export type EventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  AND?: Maybe<Array<EventWhereInput>>
+  OR?: Maybe<Array<EventWhereInput>>
+}
+
+export type EventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type InitialInvitationBalanceUpdatedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  /** New initial invitation balance. */
+  newInitialBalance: Scalars['BigInt']
+}
+
+export type InitialInvitationBalanceUpdatedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<InitialInvitationBalanceUpdatedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type InitialInvitationBalanceUpdatedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  newInitialBalance: Scalars['BigInt']
+}
+
+export type InitialInvitationBalanceUpdatedEventEdge = {
+  node: InitialInvitationBalanceUpdatedEvent
+  cursor: Scalars['String']
+}
+
+export enum InitialInvitationBalanceUpdatedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  NewInitialBalanceAsc = 'newInitialBalance_ASC',
+  NewInitialBalanceDesc = 'newInitialBalance_DESC',
+}
+
+export type InitialInvitationBalanceUpdatedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  newInitialBalance?: Maybe<Scalars['BigInt']>
+}
+
+export type InitialInvitationBalanceUpdatedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  newInitialBalance_eq?: Maybe<Scalars['BigInt']>
+  newInitialBalance_gt?: Maybe<Scalars['BigInt']>
+  newInitialBalance_gte?: Maybe<Scalars['BigInt']>
+  newInitialBalance_lt?: Maybe<Scalars['BigInt']>
+  newInitialBalance_lte?: Maybe<Scalars['BigInt']>
+  newInitialBalance_in?: Maybe<Array<Scalars['BigInt']>>
+  AND?: Maybe<Array<InitialInvitationBalanceUpdatedEventWhereInput>>
+  OR?: Maybe<Array<InitialInvitationBalanceUpdatedEventWhereInput>>
+}
+
+export type InitialInvitationBalanceUpdatedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type InitialInvitationCountUpdatedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  /** New initial invitation count for members. */
+  newInitialInvitationCount: Scalars['Int']
+}
+
+export type InitialInvitationCountUpdatedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<InitialInvitationCountUpdatedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type InitialInvitationCountUpdatedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  newInitialInvitationCount: Scalars['Float']
+}
+
+export type InitialInvitationCountUpdatedEventEdge = {
+  node: InitialInvitationCountUpdatedEvent
+  cursor: Scalars['String']
+}
+
+export enum InitialInvitationCountUpdatedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  NewInitialInvitationCountAsc = 'newInitialInvitationCount_ASC',
+  NewInitialInvitationCountDesc = 'newInitialInvitationCount_DESC',
+}
+
+export type InitialInvitationCountUpdatedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  newInitialInvitationCount?: Maybe<Scalars['Float']>
+}
+
+export type InitialInvitationCountUpdatedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  newInitialInvitationCount_eq?: Maybe<Scalars['Int']>
+  newInitialInvitationCount_gt?: Maybe<Scalars['Int']>
+  newInitialInvitationCount_gte?: Maybe<Scalars['Int']>
+  newInitialInvitationCount_lt?: Maybe<Scalars['Int']>
+  newInitialInvitationCount_lte?: Maybe<Scalars['Int']>
+  newInitialInvitationCount_in?: Maybe<Array<Scalars['Int']>>
+  AND?: Maybe<Array<InitialInvitationCountUpdatedEventWhereInput>>
+  OR?: Maybe<Array<InitialInvitationCountUpdatedEventWhereInput>>
+}
+
+export type InitialInvitationCountUpdatedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type InvalidActionMetadata = {
+  /** Reason why the action metadata was considered invalid */
+  reason: Scalars['String']
+}
+
+export type InvalidActionMetadataCreateInput = {
+  reason: Scalars['String']
+}
+
+export type InvalidActionMetadataUpdateInput = {
+  reason?: Maybe<Scalars['String']>
+}
+
+export type InvalidActionMetadataWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  reason_eq?: Maybe<Scalars['String']>
+  reason_contains?: Maybe<Scalars['String']>
+  reason_startsWith?: Maybe<Scalars['String']>
+  reason_endsWith?: Maybe<Scalars['String']>
+  reason_in?: Maybe<Array<Scalars['String']>>
+  AND?: Maybe<Array<InvalidActionMetadataWhereInput>>
+  OR?: Maybe<Array<InvalidActionMetadataWhereInput>>
+}
+
+export type InvalidActionMetadataWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type InvitesTransferredEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  sourceMember: Membership
+  sourceMemberId: Scalars['String']
+  targetMember: Membership
+  targetMemberId: Scalars['String']
+  /** Number of invites transferred. */
+  numberOfInvites: Scalars['Int']
+}
+
+export type InvitesTransferredEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<InvitesTransferredEventEdge>
+  pageInfo: PageInfo
+}
+
+export type InvitesTransferredEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  sourceMember: Scalars['ID']
+  targetMember: Scalars['ID']
+  numberOfInvites: Scalars['Float']
+}
+
+export type InvitesTransferredEventEdge = {
+  node: InvitesTransferredEvent
+  cursor: Scalars['String']
+}
+
+export enum InvitesTransferredEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  SourceMemberAsc = 'sourceMember_ASC',
+  SourceMemberDesc = 'sourceMember_DESC',
+  TargetMemberAsc = 'targetMember_ASC',
+  TargetMemberDesc = 'targetMember_DESC',
+  NumberOfInvitesAsc = 'numberOfInvites_ASC',
+  NumberOfInvitesDesc = 'numberOfInvites_DESC',
+}
+
+export type InvitesTransferredEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  sourceMember?: Maybe<Scalars['ID']>
+  targetMember?: Maybe<Scalars['ID']>
+  numberOfInvites?: Maybe<Scalars['Float']>
+}
+
+export type InvitesTransferredEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  sourceMember_eq?: Maybe<Scalars['ID']>
+  sourceMember_in?: Maybe<Array<Scalars['ID']>>
+  targetMember_eq?: Maybe<Scalars['ID']>
+  targetMember_in?: Maybe<Array<Scalars['ID']>>
+  numberOfInvites_eq?: Maybe<Scalars['Int']>
+  numberOfInvites_gt?: Maybe<Scalars['Int']>
+  numberOfInvites_gte?: Maybe<Scalars['Int']>
+  numberOfInvites_lt?: Maybe<Scalars['Int']>
+  numberOfInvites_lte?: Maybe<Scalars['Int']>
+  numberOfInvites_in?: Maybe<Array<Scalars['Int']>>
+  sourceMember?: Maybe<MembershipWhereInput>
+  targetMember?: Maybe<MembershipWhereInput>
+  AND?: Maybe<Array<InvitesTransferredEventWhereInput>>
+  OR?: Maybe<Array<InvitesTransferredEventWhereInput>>
+}
+
+export type InvitesTransferredEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type LeaderInvitationQuotaUpdatedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  /** New quota. */
+  newInvitationQuota: Scalars['Int']
+}
+
+export type LeaderInvitationQuotaUpdatedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<LeaderInvitationQuotaUpdatedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type LeaderInvitationQuotaUpdatedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  newInvitationQuota: Scalars['Float']
+}
+
+export type LeaderInvitationQuotaUpdatedEventEdge = {
+  node: LeaderInvitationQuotaUpdatedEvent
+  cursor: Scalars['String']
+}
+
+export enum LeaderInvitationQuotaUpdatedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  NewInvitationQuotaAsc = 'newInvitationQuota_ASC',
+  NewInvitationQuotaDesc = 'newInvitationQuota_DESC',
+}
+
+export type LeaderInvitationQuotaUpdatedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  newInvitationQuota?: Maybe<Scalars['Float']>
+}
+
+export type LeaderInvitationQuotaUpdatedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  newInvitationQuota_eq?: Maybe<Scalars['Int']>
+  newInvitationQuota_gt?: Maybe<Scalars['Int']>
+  newInvitationQuota_gte?: Maybe<Scalars['Int']>
+  newInvitationQuota_lt?: Maybe<Scalars['Int']>
+  newInvitationQuota_lte?: Maybe<Scalars['Int']>
+  newInvitationQuota_in?: Maybe<Array<Scalars['Int']>>
+  AND?: Maybe<Array<LeaderInvitationQuotaUpdatedEventWhereInput>>
+  OR?: Maybe<Array<LeaderInvitationQuotaUpdatedEventWhereInput>>
+}
+
+export type LeaderInvitationQuotaUpdatedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type LeaderSetEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  worker?: Maybe<Worker>
+  workerId?: Maybe<Scalars['String']>
+}
+
+export type LeaderSetEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<LeaderSetEventEdge>
+  pageInfo: PageInfo
+}
+
+export type LeaderSetEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  worker?: Maybe<Scalars['ID']>
+}
+
+export type LeaderSetEventEdge = {
+  node: LeaderSetEvent
+  cursor: Scalars['String']
+}
+
+export enum LeaderSetEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  WorkerAsc = 'worker_ASC',
+  WorkerDesc = 'worker_DESC',
+}
+
+export type LeaderSetEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  worker?: Maybe<Scalars['ID']>
+}
+
+export type LeaderSetEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  worker_eq?: Maybe<Scalars['ID']>
+  worker_in?: Maybe<Array<Scalars['ID']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  worker?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<LeaderSetEventWhereInput>>
+  OR?: Maybe<Array<LeaderSetEventWhereInput>>
+}
+
+export type LeaderSetEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type LeaderUnsetEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  leader: Worker
+  leaderId: Scalars['String']
+}
+
+export type LeaderUnsetEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<LeaderUnsetEventEdge>
+  pageInfo: PageInfo
+}
+
+export type LeaderUnsetEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  leader: Scalars['ID']
+}
+
+export type LeaderUnsetEventEdge = {
+  node: LeaderUnsetEvent
+  cursor: Scalars['String']
+}
+
+export enum LeaderUnsetEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  LeaderAsc = 'leader_ASC',
+  LeaderDesc = 'leader_DESC',
+}
+
+export type LeaderUnsetEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  leader?: Maybe<Scalars['ID']>
+}
+
+export type LeaderUnsetEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  leader_eq?: Maybe<Scalars['ID']>
+  leader_in?: Maybe<Array<Scalars['ID']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  leader?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<LeaderUnsetEventWhereInput>>
+  OR?: Maybe<Array<LeaderUnsetEventWhereInput>>
+}
+
+export type LeaderUnsetEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export enum LiaisonJudgement {
+  Pending = 'PENDING',
+  Accepted = 'ACCEPTED',
+  Rejected = 'REJECTED',
+}
+
+export type MemberAccountsUpdatedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  member: Membership
+  memberId: Scalars['String']
+  /** New member root account in SS58 encoding. Null means no new value was provided. */
+  newRootAccount?: Maybe<Scalars['String']>
+  /** New member controller in SS58 encoding. Null means no new value was provided. */
+  newControllerAccount?: Maybe<Scalars['String']>
+}
+
+export type MemberAccountsUpdatedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<MemberAccountsUpdatedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type MemberAccountsUpdatedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  member: Scalars['ID']
+  newRootAccount?: Maybe<Scalars['String']>
+  newControllerAccount?: Maybe<Scalars['String']>
+}
+
+export type MemberAccountsUpdatedEventEdge = {
+  node: MemberAccountsUpdatedEvent
+  cursor: Scalars['String']
+}
+
+export enum MemberAccountsUpdatedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  MemberAsc = 'member_ASC',
+  MemberDesc = 'member_DESC',
+  NewRootAccountAsc = 'newRootAccount_ASC',
+  NewRootAccountDesc = 'newRootAccount_DESC',
+  NewControllerAccountAsc = 'newControllerAccount_ASC',
+  NewControllerAccountDesc = 'newControllerAccount_DESC',
+}
+
+export type MemberAccountsUpdatedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  member?: Maybe<Scalars['ID']>
+  newRootAccount?: Maybe<Scalars['String']>
+  newControllerAccount?: Maybe<Scalars['String']>
+}
+
+export type MemberAccountsUpdatedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  member_eq?: Maybe<Scalars['ID']>
+  member_in?: Maybe<Array<Scalars['ID']>>
+  newRootAccount_eq?: Maybe<Scalars['String']>
+  newRootAccount_contains?: Maybe<Scalars['String']>
+  newRootAccount_startsWith?: Maybe<Scalars['String']>
+  newRootAccount_endsWith?: Maybe<Scalars['String']>
+  newRootAccount_in?: Maybe<Array<Scalars['String']>>
+  newControllerAccount_eq?: Maybe<Scalars['String']>
+  newControllerAccount_contains?: Maybe<Scalars['String']>
+  newControllerAccount_startsWith?: Maybe<Scalars['String']>
+  newControllerAccount_endsWith?: Maybe<Scalars['String']>
+  newControllerAccount_in?: Maybe<Array<Scalars['String']>>
+  member?: Maybe<MembershipWhereInput>
+  AND?: Maybe<Array<MemberAccountsUpdatedEventWhereInput>>
+  OR?: Maybe<Array<MemberAccountsUpdatedEventWhereInput>>
+}
+
+export type MemberAccountsUpdatedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type MemberInvitedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  invitingMember: Membership
+  invitingMemberId: Scalars['String']
+  newMember: Membership
+  newMemberId: Scalars['String']
+  /** New member root account in SS58 encoding. */
+  rootAccount: Scalars['String']
+  /** New member controller in SS58 encoding. */
+  controllerAccount: Scalars['String']
+  /** New member handle. */
+  handle: Scalars['String']
+  metadata: MemberMetadata
+  metadataId: Scalars['String']
+}
+
+export type MemberInvitedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<MemberInvitedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type MemberInvitedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  invitingMember: Scalars['ID']
+  newMember: Scalars['ID']
+  rootAccount: Scalars['String']
+  controllerAccount: Scalars['String']
+  handle: Scalars['String']
+  metadata: Scalars['ID']
+}
+
+export type MemberInvitedEventEdge = {
+  node: MemberInvitedEvent
+  cursor: Scalars['String']
+}
+
+export enum MemberInvitedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  InvitingMemberAsc = 'invitingMember_ASC',
+  InvitingMemberDesc = 'invitingMember_DESC',
+  NewMemberAsc = 'newMember_ASC',
+  NewMemberDesc = 'newMember_DESC',
+  RootAccountAsc = 'rootAccount_ASC',
+  RootAccountDesc = 'rootAccount_DESC',
+  ControllerAccountAsc = 'controllerAccount_ASC',
+  ControllerAccountDesc = 'controllerAccount_DESC',
+  HandleAsc = 'handle_ASC',
+  HandleDesc = 'handle_DESC',
+  MetadataAsc = 'metadata_ASC',
+  MetadataDesc = 'metadata_DESC',
+}
+
+export type MemberInvitedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  invitingMember?: Maybe<Scalars['ID']>
+  newMember?: Maybe<Scalars['ID']>
+  rootAccount?: Maybe<Scalars['String']>
+  controllerAccount?: Maybe<Scalars['String']>
+  handle?: Maybe<Scalars['String']>
+  metadata?: Maybe<Scalars['ID']>
+}
+
+export type MemberInvitedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  invitingMember_eq?: Maybe<Scalars['ID']>
+  invitingMember_in?: Maybe<Array<Scalars['ID']>>
+  newMember_eq?: Maybe<Scalars['ID']>
+  newMember_in?: Maybe<Array<Scalars['ID']>>
+  rootAccount_eq?: Maybe<Scalars['String']>
+  rootAccount_contains?: Maybe<Scalars['String']>
+  rootAccount_startsWith?: Maybe<Scalars['String']>
+  rootAccount_endsWith?: Maybe<Scalars['String']>
+  rootAccount_in?: Maybe<Array<Scalars['String']>>
+  controllerAccount_eq?: Maybe<Scalars['String']>
+  controllerAccount_contains?: Maybe<Scalars['String']>
+  controllerAccount_startsWith?: Maybe<Scalars['String']>
+  controllerAccount_endsWith?: Maybe<Scalars['String']>
+  controllerAccount_in?: Maybe<Array<Scalars['String']>>
+  handle_eq?: Maybe<Scalars['String']>
+  handle_contains?: Maybe<Scalars['String']>
+  handle_startsWith?: Maybe<Scalars['String']>
+  handle_endsWith?: Maybe<Scalars['String']>
+  handle_in?: Maybe<Array<Scalars['String']>>
+  metadata_eq?: Maybe<Scalars['ID']>
+  metadata_in?: Maybe<Array<Scalars['ID']>>
+  invitingMember?: Maybe<MembershipWhereInput>
+  newMember?: Maybe<MembershipWhereInput>
+  metadata?: Maybe<MemberMetadataWhereInput>
+  AND?: Maybe<Array<MemberInvitedEventWhereInput>>
+  OR?: Maybe<Array<MemberInvitedEventWhereInput>>
+}
+
+export type MemberInvitedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type MemberMetadata = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Member's name */
+  name?: Maybe<Scalars['String']>
+  avatar?: Maybe<DataObject>
+  avatarId?: Maybe<Scalars['String']>
+  /** Short text chosen by member to share information about themselves */
+  about?: Maybe<Scalars['String']>
+  memberinvitedeventmetadata?: Maybe<Array<MemberInvitedEvent>>
+  memberprofileupdatedeventnewMetadata?: Maybe<Array<MemberProfileUpdatedEvent>>
+  membershipmetadata?: Maybe<Array<Membership>>
+  membershipboughteventmetadata?: Maybe<Array<MembershipBoughtEvent>>
+}
+
+export type MemberMetadataConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<MemberMetadataEdge>
+  pageInfo: PageInfo
+}
+
+export type MemberMetadataCreateInput = {
+  name?: Maybe<Scalars['String']>
+  avatar?: Maybe<Scalars['ID']>
+  about?: Maybe<Scalars['String']>
+}
+
+export type MemberMetadataEdge = {
+  node: MemberMetadata
+  cursor: Scalars['String']
+}
+
+export enum MemberMetadataOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  NameAsc = 'name_ASC',
+  NameDesc = 'name_DESC',
+  AvatarAsc = 'avatar_ASC',
+  AvatarDesc = 'avatar_DESC',
+  AboutAsc = 'about_ASC',
+  AboutDesc = 'about_DESC',
+}
+
+export type MemberMetadataUpdateInput = {
+  name?: Maybe<Scalars['String']>
+  avatar?: Maybe<Scalars['ID']>
+  about?: Maybe<Scalars['String']>
+}
+
+export type MemberMetadataWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  name_eq?: Maybe<Scalars['String']>
+  name_contains?: Maybe<Scalars['String']>
+  name_startsWith?: Maybe<Scalars['String']>
+  name_endsWith?: Maybe<Scalars['String']>
+  name_in?: Maybe<Array<Scalars['String']>>
+  avatar_eq?: Maybe<Scalars['ID']>
+  avatar_in?: Maybe<Array<Scalars['ID']>>
+  about_eq?: Maybe<Scalars['String']>
+  about_contains?: Maybe<Scalars['String']>
+  about_startsWith?: Maybe<Scalars['String']>
+  about_endsWith?: Maybe<Scalars['String']>
+  about_in?: Maybe<Array<Scalars['String']>>
+  avatar?: Maybe<DataObjectWhereInput>
+  memberinvitedeventmetadata_none?: Maybe<MemberInvitedEventWhereInput>
+  memberinvitedeventmetadata_some?: Maybe<MemberInvitedEventWhereInput>
+  memberinvitedeventmetadata_every?: Maybe<MemberInvitedEventWhereInput>
+  memberprofileupdatedeventnewMetadata_none?: Maybe<MemberProfileUpdatedEventWhereInput>
+  memberprofileupdatedeventnewMetadata_some?: Maybe<MemberProfileUpdatedEventWhereInput>
+  memberprofileupdatedeventnewMetadata_every?: Maybe<MemberProfileUpdatedEventWhereInput>
+  membershipmetadata_none?: Maybe<MembershipWhereInput>
+  membershipmetadata_some?: Maybe<MembershipWhereInput>
+  membershipmetadata_every?: Maybe<MembershipWhereInput>
+  membershipboughteventmetadata_none?: Maybe<MembershipBoughtEventWhereInput>
+  membershipboughteventmetadata_some?: Maybe<MembershipBoughtEventWhereInput>
+  membershipboughteventmetadata_every?: Maybe<MembershipBoughtEventWhereInput>
+  AND?: Maybe<Array<MemberMetadataWhereInput>>
+  OR?: Maybe<Array<MemberMetadataWhereInput>>
+}
+
+export type MemberMetadataWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type MemberProfileUpdatedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  member: Membership
+  memberId: Scalars['String']
+  /** New member handle. Null means no new value was provided. */
+  newHandle?: Maybe<Scalars['String']>
+  newMetadata: MemberMetadata
+  newMetadataId: Scalars['String']
+}
+
+export type MemberProfileUpdatedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<MemberProfileUpdatedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type MemberProfileUpdatedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  member: Scalars['ID']
+  newHandle?: Maybe<Scalars['String']>
+  newMetadata: Scalars['ID']
+}
+
+export type MemberProfileUpdatedEventEdge = {
+  node: MemberProfileUpdatedEvent
+  cursor: Scalars['String']
+}
+
+export enum MemberProfileUpdatedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  MemberAsc = 'member_ASC',
+  MemberDesc = 'member_DESC',
+  NewHandleAsc = 'newHandle_ASC',
+  NewHandleDesc = 'newHandle_DESC',
+  NewMetadataAsc = 'newMetadata_ASC',
+  NewMetadataDesc = 'newMetadata_DESC',
+}
+
+export type MemberProfileUpdatedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  member?: Maybe<Scalars['ID']>
+  newHandle?: Maybe<Scalars['String']>
+  newMetadata?: Maybe<Scalars['ID']>
+}
+
+export type MemberProfileUpdatedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  member_eq?: Maybe<Scalars['ID']>
+  member_in?: Maybe<Array<Scalars['ID']>>
+  newHandle_eq?: Maybe<Scalars['String']>
+  newHandle_contains?: Maybe<Scalars['String']>
+  newHandle_startsWith?: Maybe<Scalars['String']>
+  newHandle_endsWith?: Maybe<Scalars['String']>
+  newHandle_in?: Maybe<Array<Scalars['String']>>
+  newMetadata_eq?: Maybe<Scalars['ID']>
+  newMetadata_in?: Maybe<Array<Scalars['ID']>>
+  member?: Maybe<MembershipWhereInput>
+  newMetadata?: Maybe<MemberMetadataWhereInput>
+  AND?: Maybe<Array<MemberProfileUpdatedEventWhereInput>>
+  OR?: Maybe<Array<MemberProfileUpdatedEventWhereInput>>
+}
+
+export type MemberProfileUpdatedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type MembersByHandleFtsOutput = {
+  item: MembersByHandleSearchResult
+  rank: Scalars['Float']
+  isTypeOf: Scalars['String']
+  highlight: Scalars['String']
+}
+
+export type MembersByHandleSearchResult = Membership
+
+/** Stored information about a registered user */
+export type Membership = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** The unique handle chosen by member */
+  handle: Scalars['String']
+  metadata: MemberMetadata
+  metadataId: Scalars['String']
+  /** Member's controller account id */
+  controllerAccount: Scalars['String']
+  /** Member's root account id */
+  rootAccount: Scalars['String']
+  /** How the member was registered */
+  entry: MembershipEntryMethod
+  /** Whether member has been verified by membership working group. */
+  isVerified: Scalars['Boolean']
+  /** Staking accounts bounded to membership. */
+  boundAccounts: Array<Scalars['String']>
+  /** Current count of invites left to send. */
+  inviteCount: Scalars['Int']
+  invitees: Array<Membership>
+  invitedBy?: Maybe<Membership>
+  invitedById?: Maybe<Scalars['String']>
+  referredMembers: Array<Membership>
+  referredBy?: Maybe<Membership>
+  referredById?: Maybe<Scalars['String']>
+  /** Whether member is founding member. */
+  isFoundingMember: Scalars['Boolean']
+  roles: Array<Worker>
+  invitestransferredeventsourceMember?: Maybe<Array<InvitesTransferredEvent>>
+  invitestransferredeventtargetMember?: Maybe<Array<InvitesTransferredEvent>>
+  memberaccountsupdatedeventmember?: Maybe<Array<MemberAccountsUpdatedEvent>>
+  memberinvitedeventinvitingMember?: Maybe<Array<MemberInvitedEvent>>
+  memberinvitedeventnewMember?: Maybe<Array<MemberInvitedEvent>>
+  memberprofileupdatedeventmember?: Maybe<Array<MemberProfileUpdatedEvent>>
+  memberverificationstatusupdatedeventmember?: Maybe<Array<MemberVerificationStatusUpdatedEvent>>
+  membershipboughteventnewMember?: Maybe<Array<MembershipBoughtEvent>>
+  membershipboughteventreferrer?: Maybe<Array<MembershipBoughtEvent>>
+  stakingaccountaddedeventmember?: Maybe<Array<StakingAccountAddedEvent>>
+  stakingaccountconfirmedeventmember?: Maybe<Array<StakingAccountConfirmedEvent>>
+  stakingaccountremovedeventmember?: Maybe<Array<StakingAccountRemovedEvent>>
+  workinggroupapplicationapplicant?: Maybe<Array<WorkingGroupApplication>>
+}
+
+export type MembershipBoughtEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  newMember: Membership
+  newMemberId: Scalars['String']
+  /** New member root account in SS58 encoding. */
+  rootAccount: Scalars['String']
+  /** New member controller in SS58 encoding. */
+  controllerAccount: Scalars['String']
+  /** New member handle. */
+  handle: Scalars['String']
+  metadata: MemberMetadata
+  metadataId: Scalars['String']
+  referrer?: Maybe<Membership>
+  referrerId?: Maybe<Scalars['String']>
+}
+
+export type MembershipBoughtEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<MembershipBoughtEventEdge>
+  pageInfo: PageInfo
+}
+
+export type MembershipBoughtEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  newMember: Scalars['ID']
+  rootAccount: Scalars['String']
+  controllerAccount: Scalars['String']
+  handle: Scalars['String']
+  metadata: Scalars['ID']
+  referrer?: Maybe<Scalars['ID']>
+}
+
+export type MembershipBoughtEventEdge = {
+  node: MembershipBoughtEvent
+  cursor: Scalars['String']
+}
+
+export enum MembershipBoughtEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  NewMemberAsc = 'newMember_ASC',
+  NewMemberDesc = 'newMember_DESC',
+  RootAccountAsc = 'rootAccount_ASC',
+  RootAccountDesc = 'rootAccount_DESC',
+  ControllerAccountAsc = 'controllerAccount_ASC',
+  ControllerAccountDesc = 'controllerAccount_DESC',
+  HandleAsc = 'handle_ASC',
+  HandleDesc = 'handle_DESC',
+  MetadataAsc = 'metadata_ASC',
+  MetadataDesc = 'metadata_DESC',
+  ReferrerAsc = 'referrer_ASC',
+  ReferrerDesc = 'referrer_DESC',
+}
+
+export type MembershipBoughtEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  newMember?: Maybe<Scalars['ID']>
+  rootAccount?: Maybe<Scalars['String']>
+  controllerAccount?: Maybe<Scalars['String']>
+  handle?: Maybe<Scalars['String']>
+  metadata?: Maybe<Scalars['ID']>
+  referrer?: Maybe<Scalars['ID']>
+}
+
+export type MembershipBoughtEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  newMember_eq?: Maybe<Scalars['ID']>
+  newMember_in?: Maybe<Array<Scalars['ID']>>
+  rootAccount_eq?: Maybe<Scalars['String']>
+  rootAccount_contains?: Maybe<Scalars['String']>
+  rootAccount_startsWith?: Maybe<Scalars['String']>
+  rootAccount_endsWith?: Maybe<Scalars['String']>
+  rootAccount_in?: Maybe<Array<Scalars['String']>>
+  controllerAccount_eq?: Maybe<Scalars['String']>
+  controllerAccount_contains?: Maybe<Scalars['String']>
+  controllerAccount_startsWith?: Maybe<Scalars['String']>
+  controllerAccount_endsWith?: Maybe<Scalars['String']>
+  controllerAccount_in?: Maybe<Array<Scalars['String']>>
+  handle_eq?: Maybe<Scalars['String']>
+  handle_contains?: Maybe<Scalars['String']>
+  handle_startsWith?: Maybe<Scalars['String']>
+  handle_endsWith?: Maybe<Scalars['String']>
+  handle_in?: Maybe<Array<Scalars['String']>>
+  metadata_eq?: Maybe<Scalars['ID']>
+  metadata_in?: Maybe<Array<Scalars['ID']>>
+  referrer_eq?: Maybe<Scalars['ID']>
+  referrer_in?: Maybe<Array<Scalars['ID']>>
+  newMember?: Maybe<MembershipWhereInput>
+  metadata?: Maybe<MemberMetadataWhereInput>
+  referrer?: Maybe<MembershipWhereInput>
+  AND?: Maybe<Array<MembershipBoughtEventWhereInput>>
+  OR?: Maybe<Array<MembershipBoughtEventWhereInput>>
+}
+
+export type MembershipBoughtEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type MembershipConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<MembershipEdge>
+  pageInfo: PageInfo
+}
+
+export type MembershipCreateInput = {
+  handle: Scalars['String']
+  metadata: Scalars['ID']
+  controllerAccount: Scalars['String']
+  rootAccount: Scalars['String']
+  entry: Scalars['JSONObject']
+  isVerified: Scalars['Boolean']
+  boundAccounts: Array<Scalars['String']>
+  inviteCount: Scalars['Float']
+  invitedBy?: Maybe<Scalars['ID']>
+  referredBy?: Maybe<Scalars['ID']>
+  isFoundingMember: Scalars['Boolean']
+}
+
+export type MembershipEdge = {
+  node: Membership
+  cursor: Scalars['String']
+}
+
+export type MembershipEntryGenesis = {
+  phantom?: Maybe<Scalars['Int']>
+}
+
+export type MembershipEntryGenesisCreateInput = {
+  phantom?: Maybe<Scalars['Float']>
+}
+
+export type MembershipEntryGenesisUpdateInput = {
+  phantom?: Maybe<Scalars['Float']>
+}
+
+export type MembershipEntryGenesisWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  phantom_eq?: Maybe<Scalars['Int']>
+  phantom_gt?: Maybe<Scalars['Int']>
+  phantom_gte?: Maybe<Scalars['Int']>
+  phantom_lt?: Maybe<Scalars['Int']>
+  phantom_lte?: Maybe<Scalars['Int']>
+  phantom_in?: Maybe<Array<Scalars['Int']>>
+  AND?: Maybe<Array<MembershipEntryGenesisWhereInput>>
+  OR?: Maybe<Array<MembershipEntryGenesisWhereInput>>
+}
+
+export type MembershipEntryGenesisWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type MembershipEntryInvited = {
+  /** The event the member was invited in */
+  memberInvitedEvent?: Maybe<MemberInvitedEvent>
+}
+
+export type MembershipEntryMethod = MembershipEntryPaid | MembershipEntryInvited | MembershipEntryGenesis
+
+export type MembershipEntryPaid = {
+  /** The event the membership was bought in */
+  membershipBoughtEvent?: Maybe<MembershipBoughtEvent>
+}
+
+export enum MembershipOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  HandleAsc = 'handle_ASC',
+  HandleDesc = 'handle_DESC',
+  MetadataAsc = 'metadata_ASC',
+  MetadataDesc = 'metadata_DESC',
+  ControllerAccountAsc = 'controllerAccount_ASC',
+  ControllerAccountDesc = 'controllerAccount_DESC',
+  RootAccountAsc = 'rootAccount_ASC',
+  RootAccountDesc = 'rootAccount_DESC',
+  IsVerifiedAsc = 'isVerified_ASC',
+  IsVerifiedDesc = 'isVerified_DESC',
+  InviteCountAsc = 'inviteCount_ASC',
+  InviteCountDesc = 'inviteCount_DESC',
+  InvitedByAsc = 'invitedBy_ASC',
+  InvitedByDesc = 'invitedBy_DESC',
+  ReferredByAsc = 'referredBy_ASC',
+  ReferredByDesc = 'referredBy_DESC',
+  IsFoundingMemberAsc = 'isFoundingMember_ASC',
+  IsFoundingMemberDesc = 'isFoundingMember_DESC',
+}
+
+export type MembershipPriceUpdatedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  /** The new membership price. */
+  newPrice: Scalars['BigInt']
+}
+
+export type MembershipPriceUpdatedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<MembershipPriceUpdatedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type MembershipPriceUpdatedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  newPrice: Scalars['BigInt']
+}
+
+export type MembershipPriceUpdatedEventEdge = {
+  node: MembershipPriceUpdatedEvent
+  cursor: Scalars['String']
+}
+
+export enum MembershipPriceUpdatedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  NewPriceAsc = 'newPrice_ASC',
+  NewPriceDesc = 'newPrice_DESC',
+}
+
+export type MembershipPriceUpdatedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  newPrice?: Maybe<Scalars['BigInt']>
+}
+
+export type MembershipPriceUpdatedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  newPrice_eq?: Maybe<Scalars['BigInt']>
+  newPrice_gt?: Maybe<Scalars['BigInt']>
+  newPrice_gte?: Maybe<Scalars['BigInt']>
+  newPrice_lt?: Maybe<Scalars['BigInt']>
+  newPrice_lte?: Maybe<Scalars['BigInt']>
+  newPrice_in?: Maybe<Array<Scalars['BigInt']>>
+  AND?: Maybe<Array<MembershipPriceUpdatedEventWhereInput>>
+  OR?: Maybe<Array<MembershipPriceUpdatedEventWhereInput>>
+}
+
+export type MembershipPriceUpdatedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type MembershipSystemSnapshot = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** The snapshot block number */
+  snapshotBlock: Scalars['Int']
+  /** Initial invitation count of a new member. */
+  defaultInviteCount: Scalars['Int']
+  /** Current price to buy a membership. */
+  membershipPrice: Scalars['BigInt']
+  /** Percentage of tokens diverted to invitor. */
+  referralCut: Scalars['Int']
+  /** The initial, locked, balance credited to controller account of invitee. */
+  invitedInitialBalance: Scalars['BigInt']
+}
+
+export type MembershipSystemSnapshotConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<MembershipSystemSnapshotEdge>
+  pageInfo: PageInfo
+}
+
+export type MembershipSystemSnapshotCreateInput = {
+  snapshotBlock: Scalars['Float']
+  defaultInviteCount: Scalars['Float']
+  membershipPrice: Scalars['BigInt']
+  referralCut: Scalars['Float']
+  invitedInitialBalance: Scalars['BigInt']
+}
+
+export type MembershipSystemSnapshotEdge = {
+  node: MembershipSystemSnapshot
+  cursor: Scalars['String']
+}
+
+export enum MembershipSystemSnapshotOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  SnapshotBlockAsc = 'snapshotBlock_ASC',
+  SnapshotBlockDesc = 'snapshotBlock_DESC',
+  DefaultInviteCountAsc = 'defaultInviteCount_ASC',
+  DefaultInviteCountDesc = 'defaultInviteCount_DESC',
+  MembershipPriceAsc = 'membershipPrice_ASC',
+  MembershipPriceDesc = 'membershipPrice_DESC',
+  ReferralCutAsc = 'referralCut_ASC',
+  ReferralCutDesc = 'referralCut_DESC',
+  InvitedInitialBalanceAsc = 'invitedInitialBalance_ASC',
+  InvitedInitialBalanceDesc = 'invitedInitialBalance_DESC',
+}
+
+export type MembershipSystemSnapshotUpdateInput = {
+  snapshotBlock?: Maybe<Scalars['Float']>
+  defaultInviteCount?: Maybe<Scalars['Float']>
+  membershipPrice?: Maybe<Scalars['BigInt']>
+  referralCut?: Maybe<Scalars['Float']>
+  invitedInitialBalance?: Maybe<Scalars['BigInt']>
+}
+
+export type MembershipSystemSnapshotWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  snapshotBlock_eq?: Maybe<Scalars['Int']>
+  snapshotBlock_gt?: Maybe<Scalars['Int']>
+  snapshotBlock_gte?: Maybe<Scalars['Int']>
+  snapshotBlock_lt?: Maybe<Scalars['Int']>
+  snapshotBlock_lte?: Maybe<Scalars['Int']>
+  snapshotBlock_in?: Maybe<Array<Scalars['Int']>>
+  defaultInviteCount_eq?: Maybe<Scalars['Int']>
+  defaultInviteCount_gt?: Maybe<Scalars['Int']>
+  defaultInviteCount_gte?: Maybe<Scalars['Int']>
+  defaultInviteCount_lt?: Maybe<Scalars['Int']>
+  defaultInviteCount_lte?: Maybe<Scalars['Int']>
+  defaultInviteCount_in?: Maybe<Array<Scalars['Int']>>
+  membershipPrice_eq?: Maybe<Scalars['BigInt']>
+  membershipPrice_gt?: Maybe<Scalars['BigInt']>
+  membershipPrice_gte?: Maybe<Scalars['BigInt']>
+  membershipPrice_lt?: Maybe<Scalars['BigInt']>
+  membershipPrice_lte?: Maybe<Scalars['BigInt']>
+  membershipPrice_in?: Maybe<Array<Scalars['BigInt']>>
+  referralCut_eq?: Maybe<Scalars['Int']>
+  referralCut_gt?: Maybe<Scalars['Int']>
+  referralCut_gte?: Maybe<Scalars['Int']>
+  referralCut_lt?: Maybe<Scalars['Int']>
+  referralCut_lte?: Maybe<Scalars['Int']>
+  referralCut_in?: Maybe<Array<Scalars['Int']>>
+  invitedInitialBalance_eq?: Maybe<Scalars['BigInt']>
+  invitedInitialBalance_gt?: Maybe<Scalars['BigInt']>
+  invitedInitialBalance_gte?: Maybe<Scalars['BigInt']>
+  invitedInitialBalance_lt?: Maybe<Scalars['BigInt']>
+  invitedInitialBalance_lte?: Maybe<Scalars['BigInt']>
+  invitedInitialBalance_in?: Maybe<Array<Scalars['BigInt']>>
+  AND?: Maybe<Array<MembershipSystemSnapshotWhereInput>>
+  OR?: Maybe<Array<MembershipSystemSnapshotWhereInput>>
+}
+
+export type MembershipSystemSnapshotWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type MembershipUpdateInput = {
+  handle?: Maybe<Scalars['String']>
+  metadata?: Maybe<Scalars['ID']>
+  controllerAccount?: Maybe<Scalars['String']>
+  rootAccount?: Maybe<Scalars['String']>
+  entry?: Maybe<Scalars['JSONObject']>
+  isVerified?: Maybe<Scalars['Boolean']>
+  boundAccounts?: Maybe<Array<Scalars['String']>>
+  inviteCount?: Maybe<Scalars['Float']>
+  invitedBy?: Maybe<Scalars['ID']>
+  referredBy?: Maybe<Scalars['ID']>
+  isFoundingMember?: Maybe<Scalars['Boolean']>
+}
+
+export type MembershipWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  handle_eq?: Maybe<Scalars['String']>
+  handle_contains?: Maybe<Scalars['String']>
+  handle_startsWith?: Maybe<Scalars['String']>
+  handle_endsWith?: Maybe<Scalars['String']>
+  handle_in?: Maybe<Array<Scalars['String']>>
+  metadata_eq?: Maybe<Scalars['ID']>
+  metadata_in?: Maybe<Array<Scalars['ID']>>
+  controllerAccount_eq?: Maybe<Scalars['String']>
+  controllerAccount_contains?: Maybe<Scalars['String']>
+  controllerAccount_startsWith?: Maybe<Scalars['String']>
+  controllerAccount_endsWith?: Maybe<Scalars['String']>
+  controllerAccount_in?: Maybe<Array<Scalars['String']>>
+  rootAccount_eq?: Maybe<Scalars['String']>
+  rootAccount_contains?: Maybe<Scalars['String']>
+  rootAccount_startsWith?: Maybe<Scalars['String']>
+  rootAccount_endsWith?: Maybe<Scalars['String']>
+  rootAccount_in?: Maybe<Array<Scalars['String']>>
+  entry_json?: Maybe<Scalars['JSONObject']>
+  isVerified_eq?: Maybe<Scalars['Boolean']>
+  isVerified_in?: Maybe<Array<Scalars['Boolean']>>
+  inviteCount_eq?: Maybe<Scalars['Int']>
+  inviteCount_gt?: Maybe<Scalars['Int']>
+  inviteCount_gte?: Maybe<Scalars['Int']>
+  inviteCount_lt?: Maybe<Scalars['Int']>
+  inviteCount_lte?: Maybe<Scalars['Int']>
+  inviteCount_in?: Maybe<Array<Scalars['Int']>>
+  invitedBy_eq?: Maybe<Scalars['ID']>
+  invitedBy_in?: Maybe<Array<Scalars['ID']>>
+  referredBy_eq?: Maybe<Scalars['ID']>
+  referredBy_in?: Maybe<Array<Scalars['ID']>>
+  isFoundingMember_eq?: Maybe<Scalars['Boolean']>
+  isFoundingMember_in?: Maybe<Array<Scalars['Boolean']>>
+  metadata?: Maybe<MemberMetadataWhereInput>
+  invitees_none?: Maybe<MembershipWhereInput>
+  invitees_some?: Maybe<MembershipWhereInput>
+  invitees_every?: Maybe<MembershipWhereInput>
+  invitedBy?: Maybe<MembershipWhereInput>
+  referredMembers_none?: Maybe<MembershipWhereInput>
+  referredMembers_some?: Maybe<MembershipWhereInput>
+  referredMembers_every?: Maybe<MembershipWhereInput>
+  referredBy?: Maybe<MembershipWhereInput>
+  roles_none?: Maybe<WorkerWhereInput>
+  roles_some?: Maybe<WorkerWhereInput>
+  roles_every?: Maybe<WorkerWhereInput>
+  invitestransferredeventsourceMember_none?: Maybe<InvitesTransferredEventWhereInput>
+  invitestransferredeventsourceMember_some?: Maybe<InvitesTransferredEventWhereInput>
+  invitestransferredeventsourceMember_every?: Maybe<InvitesTransferredEventWhereInput>
+  invitestransferredeventtargetMember_none?: Maybe<InvitesTransferredEventWhereInput>
+  invitestransferredeventtargetMember_some?: Maybe<InvitesTransferredEventWhereInput>
+  invitestransferredeventtargetMember_every?: Maybe<InvitesTransferredEventWhereInput>
+  memberaccountsupdatedeventmember_none?: Maybe<MemberAccountsUpdatedEventWhereInput>
+  memberaccountsupdatedeventmember_some?: Maybe<MemberAccountsUpdatedEventWhereInput>
+  memberaccountsupdatedeventmember_every?: Maybe<MemberAccountsUpdatedEventWhereInput>
+  memberinvitedeventinvitingMember_none?: Maybe<MemberInvitedEventWhereInput>
+  memberinvitedeventinvitingMember_some?: Maybe<MemberInvitedEventWhereInput>
+  memberinvitedeventinvitingMember_every?: Maybe<MemberInvitedEventWhereInput>
+  memberinvitedeventnewMember_none?: Maybe<MemberInvitedEventWhereInput>
+  memberinvitedeventnewMember_some?: Maybe<MemberInvitedEventWhereInput>
+  memberinvitedeventnewMember_every?: Maybe<MemberInvitedEventWhereInput>
+  memberprofileupdatedeventmember_none?: Maybe<MemberProfileUpdatedEventWhereInput>
+  memberprofileupdatedeventmember_some?: Maybe<MemberProfileUpdatedEventWhereInput>
+  memberprofileupdatedeventmember_every?: Maybe<MemberProfileUpdatedEventWhereInput>
+  memberverificationstatusupdatedeventmember_none?: Maybe<MemberVerificationStatusUpdatedEventWhereInput>
+  memberverificationstatusupdatedeventmember_some?: Maybe<MemberVerificationStatusUpdatedEventWhereInput>
+  memberverificationstatusupdatedeventmember_every?: Maybe<MemberVerificationStatusUpdatedEventWhereInput>
+  membershipboughteventnewMember_none?: Maybe<MembershipBoughtEventWhereInput>
+  membershipboughteventnewMember_some?: Maybe<MembershipBoughtEventWhereInput>
+  membershipboughteventnewMember_every?: Maybe<MembershipBoughtEventWhereInput>
+  membershipboughteventreferrer_none?: Maybe<MembershipBoughtEventWhereInput>
+  membershipboughteventreferrer_some?: Maybe<MembershipBoughtEventWhereInput>
+  membershipboughteventreferrer_every?: Maybe<MembershipBoughtEventWhereInput>
+  stakingaccountaddedeventmember_none?: Maybe<StakingAccountAddedEventWhereInput>
+  stakingaccountaddedeventmember_some?: Maybe<StakingAccountAddedEventWhereInput>
+  stakingaccountaddedeventmember_every?: Maybe<StakingAccountAddedEventWhereInput>
+  stakingaccountconfirmedeventmember_none?: Maybe<StakingAccountConfirmedEventWhereInput>
+  stakingaccountconfirmedeventmember_some?: Maybe<StakingAccountConfirmedEventWhereInput>
+  stakingaccountconfirmedeventmember_every?: Maybe<StakingAccountConfirmedEventWhereInput>
+  stakingaccountremovedeventmember_none?: Maybe<StakingAccountRemovedEventWhereInput>
+  stakingaccountremovedeventmember_some?: Maybe<StakingAccountRemovedEventWhereInput>
+  stakingaccountremovedeventmember_every?: Maybe<StakingAccountRemovedEventWhereInput>
+  workinggroupapplicationapplicant_none?: Maybe<WorkingGroupApplicationWhereInput>
+  workinggroupapplicationapplicant_some?: Maybe<WorkingGroupApplicationWhereInput>
+  workinggroupapplicationapplicant_every?: Maybe<WorkingGroupApplicationWhereInput>
+  AND?: Maybe<Array<MembershipWhereInput>>
+  OR?: Maybe<Array<MembershipWhereInput>>
+}
+
+export type MembershipWhereUniqueInput = {
+  id?: Maybe<Scalars['ID']>
+  handle?: Maybe<Scalars['String']>
+}
+
+export type MemberVerificationStatusUpdatedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  member: Membership
+  memberId: Scalars['String']
+  worker: Worker
+  workerId: Scalars['String']
+  /** New status. */
+  isVerified: Scalars['Boolean']
+}
+
+export type MemberVerificationStatusUpdatedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<MemberVerificationStatusUpdatedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type MemberVerificationStatusUpdatedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  member: Scalars['ID']
+  worker: Scalars['ID']
+  isVerified: Scalars['Boolean']
+}
+
+export type MemberVerificationStatusUpdatedEventEdge = {
+  node: MemberVerificationStatusUpdatedEvent
+  cursor: Scalars['String']
+}
+
+export enum MemberVerificationStatusUpdatedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  MemberAsc = 'member_ASC',
+  MemberDesc = 'member_DESC',
+  WorkerAsc = 'worker_ASC',
+  WorkerDesc = 'worker_DESC',
+  IsVerifiedAsc = 'isVerified_ASC',
+  IsVerifiedDesc = 'isVerified_DESC',
+}
+
+export type MemberVerificationStatusUpdatedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  member?: Maybe<Scalars['ID']>
+  worker?: Maybe<Scalars['ID']>
+  isVerified?: Maybe<Scalars['Boolean']>
+}
+
+export type MemberVerificationStatusUpdatedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  member_eq?: Maybe<Scalars['ID']>
+  member_in?: Maybe<Array<Scalars['ID']>>
+  worker_eq?: Maybe<Scalars['ID']>
+  worker_in?: Maybe<Array<Scalars['ID']>>
+  isVerified_eq?: Maybe<Scalars['Boolean']>
+  isVerified_in?: Maybe<Array<Scalars['Boolean']>>
+  member?: Maybe<MembershipWhereInput>
+  worker?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<MemberVerificationStatusUpdatedEventWhereInput>>
+  OR?: Maybe<Array<MemberVerificationStatusUpdatedEventWhereInput>>
+}
+
+export type MemberVerificationStatusUpdatedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export enum Network {
+  Babylon = 'BABYLON',
+  Alexandria = 'ALEXANDRIA',
+  Rome = 'ROME',
+  Olympia = 'OLYMPIA',
+}
+
+export type NewMissedRewardLevelReachedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  worker: Worker
+  workerId: Scalars['String']
+  /** New missed reward amount */
+  newMissedRewardAmount: Scalars['BigInt']
+}
+
+export type NewMissedRewardLevelReachedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<NewMissedRewardLevelReachedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type NewMissedRewardLevelReachedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  worker: Scalars['ID']
+  newMissedRewardAmount: Scalars['BigInt']
+}
+
+export type NewMissedRewardLevelReachedEventEdge = {
+  node: NewMissedRewardLevelReachedEvent
+  cursor: Scalars['String']
+}
+
+export enum NewMissedRewardLevelReachedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  WorkerAsc = 'worker_ASC',
+  WorkerDesc = 'worker_DESC',
+  NewMissedRewardAmountAsc = 'newMissedRewardAmount_ASC',
+  NewMissedRewardAmountDesc = 'newMissedRewardAmount_DESC',
+}
+
+export type NewMissedRewardLevelReachedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  worker?: Maybe<Scalars['ID']>
+  newMissedRewardAmount?: Maybe<Scalars['BigInt']>
+}
+
+export type NewMissedRewardLevelReachedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  worker_eq?: Maybe<Scalars['ID']>
+  worker_in?: Maybe<Array<Scalars['ID']>>
+  newMissedRewardAmount_eq?: Maybe<Scalars['BigInt']>
+  newMissedRewardAmount_gt?: Maybe<Scalars['BigInt']>
+  newMissedRewardAmount_gte?: Maybe<Scalars['BigInt']>
+  newMissedRewardAmount_lt?: Maybe<Scalars['BigInt']>
+  newMissedRewardAmount_lte?: Maybe<Scalars['BigInt']>
+  newMissedRewardAmount_in?: Maybe<Array<Scalars['BigInt']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  worker?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<NewMissedRewardLevelReachedEventWhereInput>>
+  OR?: Maybe<Array<NewMissedRewardLevelReachedEventWhereInput>>
+}
+
+export type NewMissedRewardLevelReachedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type OpeningAddedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  opening: WorkingGroupOpening
+  openingId: Scalars['String']
+}
+
+export type OpeningAddedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<OpeningAddedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type OpeningAddedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  opening: Scalars['ID']
+}
+
+export type OpeningAddedEventEdge = {
+  node: OpeningAddedEvent
+  cursor: Scalars['String']
+}
+
+export enum OpeningAddedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  OpeningAsc = 'opening_ASC',
+  OpeningDesc = 'opening_DESC',
+}
+
+export type OpeningAddedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  opening?: Maybe<Scalars['ID']>
+}
+
+export type OpeningAddedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  opening_eq?: Maybe<Scalars['ID']>
+  opening_in?: Maybe<Array<Scalars['ID']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  opening?: Maybe<WorkingGroupOpeningWhereInput>
+  AND?: Maybe<Array<OpeningAddedEventWhereInput>>
+  OR?: Maybe<Array<OpeningAddedEventWhereInput>>
+}
+
+export type OpeningAddedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type OpeningCanceledEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  opening: WorkingGroupOpening
+  openingId: Scalars['String']
+}
+
+export type OpeningCanceledEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<OpeningCanceledEventEdge>
+  pageInfo: PageInfo
+}
+
+export type OpeningCanceledEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  opening: Scalars['ID']
+}
+
+export type OpeningCanceledEventEdge = {
+  node: OpeningCanceledEvent
+  cursor: Scalars['String']
+}
+
+export enum OpeningCanceledEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  OpeningAsc = 'opening_ASC',
+  OpeningDesc = 'opening_DESC',
+}
+
+export type OpeningCanceledEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  opening?: Maybe<Scalars['ID']>
+}
+
+export type OpeningCanceledEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  opening_eq?: Maybe<Scalars['ID']>
+  opening_in?: Maybe<Array<Scalars['ID']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  opening?: Maybe<WorkingGroupOpeningWhereInput>
+  AND?: Maybe<Array<OpeningCanceledEventWhereInput>>
+  OR?: Maybe<Array<OpeningCanceledEventWhereInput>>
+}
+
+export type OpeningCanceledEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type OpeningFilledEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  opening: WorkingGroupOpening
+  openingId: Scalars['String']
+  workersHired: Array<Worker>
+}
+
+export type OpeningFilledEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<OpeningFilledEventEdge>
+  pageInfo: PageInfo
+}
+
+export type OpeningFilledEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  opening: Scalars['ID']
+}
+
+export type OpeningFilledEventEdge = {
+  node: OpeningFilledEvent
+  cursor: Scalars['String']
+}
+
+export enum OpeningFilledEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  OpeningAsc = 'opening_ASC',
+  OpeningDesc = 'opening_DESC',
+}
+
+export type OpeningFilledEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  opening?: Maybe<Scalars['ID']>
+}
+
+export type OpeningFilledEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  opening_eq?: Maybe<Scalars['ID']>
+  opening_in?: Maybe<Array<Scalars['ID']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  opening?: Maybe<WorkingGroupOpeningWhereInput>
+  workersHired_none?: Maybe<WorkerWhereInput>
+  workersHired_some?: Maybe<WorkerWhereInput>
+  workersHired_every?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<OpeningFilledEventWhereInput>>
+  OR?: Maybe<Array<OpeningFilledEventWhereInput>>
+}
+
+export type OpeningFilledEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type OpeningStatusCancelled = {
+  /** Related event emitted on opening cancellation */
+  openingCanceledEvent?: Maybe<OpeningCanceledEvent>
+}
+
+export type OpeningStatusFilled = {
+  /** Related event emitted after filling the opening */
+  openingFilledEvent?: Maybe<OpeningFilledEvent>
+}
+
+export type OpeningStatusOpen = {
+  phantom?: Maybe<Scalars['Int']>
+}
+
+export type OpeningStatusOpenCreateInput = {
+  phantom?: Maybe<Scalars['Float']>
+}
+
+export type OpeningStatusOpenUpdateInput = {
+  phantom?: Maybe<Scalars['Float']>
+}
+
+export type OpeningStatusOpenWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  phantom_eq?: Maybe<Scalars['Int']>
+  phantom_gt?: Maybe<Scalars['Int']>
+  phantom_gte?: Maybe<Scalars['Int']>
+  phantom_lt?: Maybe<Scalars['Int']>
+  phantom_lte?: Maybe<Scalars['Int']>
+  phantom_in?: Maybe<Array<Scalars['Int']>>
+  AND?: Maybe<Array<OpeningStatusOpenWhereInput>>
+  OR?: Maybe<Array<OpeningStatusOpenWhereInput>>
+}
+
+export type OpeningStatusOpenWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type PageInfo = {
+  hasNextPage: Scalars['Boolean']
+  hasPreviousPage: Scalars['Boolean']
+  startCursor?: Maybe<Scalars['String']>
+  endCursor?: Maybe<Scalars['String']>
+}
+
+export type ProcessorState = {
+  lastCompleteBlock: Scalars['Float']
+  lastProcessedEvent: Scalars['String']
+  indexerHead: Scalars['Float']
+  chainHead: Scalars['Float']
+}
+
+export type Query = {
+  applicationFormQuestionAnswers: Array<ApplicationFormQuestionAnswer>
+  applicationFormQuestionAnswerByUniqueInput?: Maybe<ApplicationFormQuestionAnswer>
+  applicationFormQuestionAnswersConnection: ApplicationFormQuestionAnswerConnection
+  applicationFormQuestions: Array<ApplicationFormQuestion>
+  applicationFormQuestionByUniqueInput?: Maybe<ApplicationFormQuestion>
+  applicationFormQuestionsConnection: ApplicationFormQuestionConnection
+  applicationWithdrawnEvents: Array<ApplicationWithdrawnEvent>
+  applicationWithdrawnEventByUniqueInput?: Maybe<ApplicationWithdrawnEvent>
+  applicationWithdrawnEventsConnection: ApplicationWithdrawnEventConnection
+  appliedOnOpeningEvents: Array<AppliedOnOpeningEvent>
+  appliedOnOpeningEventByUniqueInput?: Maybe<AppliedOnOpeningEvent>
+  appliedOnOpeningEventsConnection: AppliedOnOpeningEventConnection
+  budgetSetEvents: Array<BudgetSetEvent>
+  budgetSetEventByUniqueInput?: Maybe<BudgetSetEvent>
+  budgetSetEventsConnection: BudgetSetEventConnection
+  budgetSpendingEvents: Array<BudgetSpendingEvent>
+  budgetSpendingEventByUniqueInput?: Maybe<BudgetSpendingEvent>
+  budgetSpendingEventsConnection: BudgetSpendingEventConnection
+  dataObjects: Array<DataObject>
+  dataObjectByUniqueInput?: Maybe<DataObject>
+  dataObjectsConnection: DataObjectConnection
+  events: Array<Event>
+  initialInvitationBalanceUpdatedEvents: Array<InitialInvitationBalanceUpdatedEvent>
+  initialInvitationBalanceUpdatedEventByUniqueInput?: Maybe<InitialInvitationBalanceUpdatedEvent>
+  initialInvitationBalanceUpdatedEventsConnection: InitialInvitationBalanceUpdatedEventConnection
+  initialInvitationCountUpdatedEvents: Array<InitialInvitationCountUpdatedEvent>
+  initialInvitationCountUpdatedEventByUniqueInput?: Maybe<InitialInvitationCountUpdatedEvent>
+  initialInvitationCountUpdatedEventsConnection: InitialInvitationCountUpdatedEventConnection
+  invitesTransferredEvents: Array<InvitesTransferredEvent>
+  invitesTransferredEventByUniqueInput?: Maybe<InvitesTransferredEvent>
+  invitesTransferredEventsConnection: InvitesTransferredEventConnection
+  leaderInvitationQuotaUpdatedEvents: Array<LeaderInvitationQuotaUpdatedEvent>
+  leaderInvitationQuotaUpdatedEventByUniqueInput?: Maybe<LeaderInvitationQuotaUpdatedEvent>
+  leaderInvitationQuotaUpdatedEventsConnection: LeaderInvitationQuotaUpdatedEventConnection
+  leaderSetEvents: Array<LeaderSetEvent>
+  leaderSetEventByUniqueInput?: Maybe<LeaderSetEvent>
+  leaderSetEventsConnection: LeaderSetEventConnection
+  leaderUnsetEvents: Array<LeaderUnsetEvent>
+  leaderUnsetEventByUniqueInput?: Maybe<LeaderUnsetEvent>
+  leaderUnsetEventsConnection: LeaderUnsetEventConnection
+  memberAccountsUpdatedEvents: Array<MemberAccountsUpdatedEvent>
+  memberAccountsUpdatedEventByUniqueInput?: Maybe<MemberAccountsUpdatedEvent>
+  memberAccountsUpdatedEventsConnection: MemberAccountsUpdatedEventConnection
+  memberInvitedEvents: Array<MemberInvitedEvent>
+  memberInvitedEventByUniqueInput?: Maybe<MemberInvitedEvent>
+  memberInvitedEventsConnection: MemberInvitedEventConnection
+  memberMetadata: Array<MemberMetadata>
+  memberMetadataByUniqueInput?: Maybe<MemberMetadata>
+  memberMetadataConnection: MemberMetadataConnection
+  memberProfileUpdatedEvents: Array<MemberProfileUpdatedEvent>
+  memberProfileUpdatedEventByUniqueInput?: Maybe<MemberProfileUpdatedEvent>
+  memberProfileUpdatedEventsConnection: MemberProfileUpdatedEventConnection
+  memberVerificationStatusUpdatedEvents: Array<MemberVerificationStatusUpdatedEvent>
+  memberVerificationStatusUpdatedEventByUniqueInput?: Maybe<MemberVerificationStatusUpdatedEvent>
+  memberVerificationStatusUpdatedEventsConnection: MemberVerificationStatusUpdatedEventConnection
+  membershipBoughtEvents: Array<MembershipBoughtEvent>
+  membershipBoughtEventByUniqueInput?: Maybe<MembershipBoughtEvent>
+  membershipBoughtEventsConnection: MembershipBoughtEventConnection
+  membershipPriceUpdatedEvents: Array<MembershipPriceUpdatedEvent>
+  membershipPriceUpdatedEventByUniqueInput?: Maybe<MembershipPriceUpdatedEvent>
+  membershipPriceUpdatedEventsConnection: MembershipPriceUpdatedEventConnection
+  membershipSystemSnapshots: Array<MembershipSystemSnapshot>
+  membershipSystemSnapshotByUniqueInput?: Maybe<MembershipSystemSnapshot>
+  membershipSystemSnapshotsConnection: MembershipSystemSnapshotConnection
+  memberships: Array<Membership>
+  membershipByUniqueInput?: Maybe<Membership>
+  membershipsConnection: MembershipConnection
+  newMissedRewardLevelReachedEvents: Array<NewMissedRewardLevelReachedEvent>
+  newMissedRewardLevelReachedEventByUniqueInput?: Maybe<NewMissedRewardLevelReachedEvent>
+  newMissedRewardLevelReachedEventsConnection: NewMissedRewardLevelReachedEventConnection
+  openingAddedEvents: Array<OpeningAddedEvent>
+  openingAddedEventByUniqueInput?: Maybe<OpeningAddedEvent>
+  openingAddedEventsConnection: OpeningAddedEventConnection
+  openingCanceledEvents: Array<OpeningCanceledEvent>
+  openingCanceledEventByUniqueInput?: Maybe<OpeningCanceledEvent>
+  openingCanceledEventsConnection: OpeningCanceledEventConnection
+  openingFilledEvents: Array<OpeningFilledEvent>
+  openingFilledEventByUniqueInput?: Maybe<OpeningFilledEvent>
+  openingFilledEventsConnection: OpeningFilledEventConnection
+  membersByHandle: Array<MembersByHandleFtsOutput>
+  referralCutUpdatedEvents: Array<ReferralCutUpdatedEvent>
+  referralCutUpdatedEventByUniqueInput?: Maybe<ReferralCutUpdatedEvent>
+  referralCutUpdatedEventsConnection: ReferralCutUpdatedEventConnection
+  rewardPaidEvents: Array<RewardPaidEvent>
+  rewardPaidEventByUniqueInput?: Maybe<RewardPaidEvent>
+  rewardPaidEventsConnection: RewardPaidEventConnection
+  stakeDecreasedEvents: Array<StakeDecreasedEvent>
+  stakeDecreasedEventByUniqueInput?: Maybe<StakeDecreasedEvent>
+  stakeDecreasedEventsConnection: StakeDecreasedEventConnection
+  stakeIncreasedEvents: Array<StakeIncreasedEvent>
+  stakeIncreasedEventByUniqueInput?: Maybe<StakeIncreasedEvent>
+  stakeIncreasedEventsConnection: StakeIncreasedEventConnection
+  stakeSlashedEvents: Array<StakeSlashedEvent>
+  stakeSlashedEventByUniqueInput?: Maybe<StakeSlashedEvent>
+  stakeSlashedEventsConnection: StakeSlashedEventConnection
+  stakingAccountAddedEvents: Array<StakingAccountAddedEvent>
+  stakingAccountAddedEventByUniqueInput?: Maybe<StakingAccountAddedEvent>
+  stakingAccountAddedEventsConnection: StakingAccountAddedEventConnection
+  stakingAccountConfirmedEvents: Array<StakingAccountConfirmedEvent>
+  stakingAccountConfirmedEventByUniqueInput?: Maybe<StakingAccountConfirmedEvent>
+  stakingAccountConfirmedEventsConnection: StakingAccountConfirmedEventConnection
+  stakingAccountRemovedEvents: Array<StakingAccountRemovedEvent>
+  stakingAccountRemovedEventByUniqueInput?: Maybe<StakingAccountRemovedEvent>
+  stakingAccountRemovedEventsConnection: StakingAccountRemovedEventConnection
+  statusTextChangedEvents: Array<StatusTextChangedEvent>
+  statusTextChangedEventByUniqueInput?: Maybe<StatusTextChangedEvent>
+  statusTextChangedEventsConnection: StatusTextChangedEventConnection
+  terminatedLeaderEvents: Array<TerminatedLeaderEvent>
+  terminatedLeaderEventByUniqueInput?: Maybe<TerminatedLeaderEvent>
+  terminatedLeaderEventsConnection: TerminatedLeaderEventConnection
+  terminatedWorkerEvents: Array<TerminatedWorkerEvent>
+  terminatedWorkerEventByUniqueInput?: Maybe<TerminatedWorkerEvent>
+  terminatedWorkerEventsConnection: TerminatedWorkerEventConnection
+  upcomingWorkingGroupOpenings: Array<UpcomingWorkingGroupOpening>
+  upcomingWorkingGroupOpeningByUniqueInput?: Maybe<UpcomingWorkingGroupOpening>
+  upcomingWorkingGroupOpeningsConnection: UpcomingWorkingGroupOpeningConnection
+  workerExitedEvents: Array<WorkerExitedEvent>
+  workerExitedEventByUniqueInput?: Maybe<WorkerExitedEvent>
+  workerExitedEventsConnection: WorkerExitedEventConnection
+  workerRewardAccountUpdatedEvents: Array<WorkerRewardAccountUpdatedEvent>
+  workerRewardAccountUpdatedEventByUniqueInput?: Maybe<WorkerRewardAccountUpdatedEvent>
+  workerRewardAccountUpdatedEventsConnection: WorkerRewardAccountUpdatedEventConnection
+  workerRewardAmountUpdatedEvents: Array<WorkerRewardAmountUpdatedEvent>
+  workerRewardAmountUpdatedEventByUniqueInput?: Maybe<WorkerRewardAmountUpdatedEvent>
+  workerRewardAmountUpdatedEventsConnection: WorkerRewardAmountUpdatedEventConnection
+  workerRoleAccountUpdatedEvents: Array<WorkerRoleAccountUpdatedEvent>
+  workerRoleAccountUpdatedEventByUniqueInput?: Maybe<WorkerRoleAccountUpdatedEvent>
+  workerRoleAccountUpdatedEventsConnection: WorkerRoleAccountUpdatedEventConnection
+  workerStartedLeavingEvents: Array<WorkerStartedLeavingEvent>
+  workerStartedLeavingEventByUniqueInput?: Maybe<WorkerStartedLeavingEvent>
+  workerStartedLeavingEventsConnection: WorkerStartedLeavingEventConnection
+  workers: Array<Worker>
+  workerByUniqueInput?: Maybe<Worker>
+  workersConnection: WorkerConnection
+  workingGroupApplications: Array<WorkingGroupApplication>
+  workingGroupApplicationByUniqueInput?: Maybe<WorkingGroupApplication>
+  workingGroupApplicationsConnection: WorkingGroupApplicationConnection
+  workingGroupMetadata: Array<WorkingGroupMetadata>
+  workingGroupMetadataByUniqueInput?: Maybe<WorkingGroupMetadata>
+  workingGroupMetadataConnection: WorkingGroupMetadataConnection
+  workingGroupOpeningMetadata: Array<WorkingGroupOpeningMetadata>
+  workingGroupOpeningMetadataByUniqueInput?: Maybe<WorkingGroupOpeningMetadata>
+  workingGroupOpeningMetadataConnection: WorkingGroupOpeningMetadataConnection
+  workingGroupOpenings: Array<WorkingGroupOpening>
+  workingGroupOpeningByUniqueInput?: Maybe<WorkingGroupOpening>
+  workingGroupOpeningsConnection: WorkingGroupOpeningConnection
+  workingGroups: Array<WorkingGroup>
+  workingGroupByUniqueInput?: Maybe<WorkingGroup>
+  workingGroupsConnection: WorkingGroupConnection
+}
+
+export type QueryApplicationFormQuestionAnswersArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<ApplicationFormQuestionAnswerWhereInput>
+  orderBy?: Maybe<Array<ApplicationFormQuestionAnswerOrderByInput>>
+}
+
+export type QueryApplicationFormQuestionAnswerByUniqueInputArgs = {
+  where: ApplicationFormQuestionAnswerWhereUniqueInput
+}
+
+export type QueryApplicationFormQuestionAnswersConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<ApplicationFormQuestionAnswerWhereInput>
+  orderBy?: Maybe<Array<ApplicationFormQuestionAnswerOrderByInput>>
+}
+
+export type QueryApplicationFormQuestionsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<ApplicationFormQuestionWhereInput>
+  orderBy?: Maybe<Array<ApplicationFormQuestionOrderByInput>>
+}
+
+export type QueryApplicationFormQuestionByUniqueInputArgs = {
+  where: ApplicationFormQuestionWhereUniqueInput
+}
+
+export type QueryApplicationFormQuestionsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<ApplicationFormQuestionWhereInput>
+  orderBy?: Maybe<Array<ApplicationFormQuestionOrderByInput>>
+}
+
+export type QueryApplicationWithdrawnEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<ApplicationWithdrawnEventWhereInput>
+  orderBy?: Maybe<Array<ApplicationWithdrawnEventOrderByInput>>
+}
+
+export type QueryApplicationWithdrawnEventByUniqueInputArgs = {
+  where: ApplicationWithdrawnEventWhereUniqueInput
+}
+
+export type QueryApplicationWithdrawnEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<ApplicationWithdrawnEventWhereInput>
+  orderBy?: Maybe<Array<ApplicationWithdrawnEventOrderByInput>>
+}
+
+export type QueryAppliedOnOpeningEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<AppliedOnOpeningEventWhereInput>
+  orderBy?: Maybe<Array<AppliedOnOpeningEventOrderByInput>>
+}
+
+export type QueryAppliedOnOpeningEventByUniqueInputArgs = {
+  where: AppliedOnOpeningEventWhereUniqueInput
+}
+
+export type QueryAppliedOnOpeningEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<AppliedOnOpeningEventWhereInput>
+  orderBy?: Maybe<Array<AppliedOnOpeningEventOrderByInput>>
+}
+
+export type QueryBudgetSetEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<BudgetSetEventWhereInput>
+  orderBy?: Maybe<Array<BudgetSetEventOrderByInput>>
+}
+
+export type QueryBudgetSetEventByUniqueInputArgs = {
+  where: BudgetSetEventWhereUniqueInput
+}
+
+export type QueryBudgetSetEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<BudgetSetEventWhereInput>
+  orderBy?: Maybe<Array<BudgetSetEventOrderByInput>>
+}
+
+export type QueryBudgetSpendingEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<BudgetSpendingEventWhereInput>
+  orderBy?: Maybe<Array<BudgetSpendingEventOrderByInput>>
+}
+
+export type QueryBudgetSpendingEventByUniqueInputArgs = {
+  where: BudgetSpendingEventWhereUniqueInput
+}
+
+export type QueryBudgetSpendingEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<BudgetSpendingEventWhereInput>
+  orderBy?: Maybe<Array<BudgetSpendingEventOrderByInput>>
+}
+
+export type QueryDataObjectsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<DataObjectWhereInput>
+  orderBy?: Maybe<Array<DataObjectOrderByInput>>
+}
+
+export type QueryDataObjectByUniqueInputArgs = {
+  where: DataObjectWhereUniqueInput
+}
+
+export type QueryDataObjectsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<DataObjectWhereInput>
+  orderBy?: Maybe<Array<DataObjectOrderByInput>>
+}
+
+export type QueryEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<EventWhereInput>
+  orderBy?: Maybe<Array<EventOrderByInput>>
+}
+
+export type QueryInitialInvitationBalanceUpdatedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<InitialInvitationBalanceUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<InitialInvitationBalanceUpdatedEventOrderByInput>>
+}
+
+export type QueryInitialInvitationBalanceUpdatedEventByUniqueInputArgs = {
+  where: InitialInvitationBalanceUpdatedEventWhereUniqueInput
+}
+
+export type QueryInitialInvitationBalanceUpdatedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<InitialInvitationBalanceUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<InitialInvitationBalanceUpdatedEventOrderByInput>>
+}
+
+export type QueryInitialInvitationCountUpdatedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<InitialInvitationCountUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<InitialInvitationCountUpdatedEventOrderByInput>>
+}
+
+export type QueryInitialInvitationCountUpdatedEventByUniqueInputArgs = {
+  where: InitialInvitationCountUpdatedEventWhereUniqueInput
+}
+
+export type QueryInitialInvitationCountUpdatedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<InitialInvitationCountUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<InitialInvitationCountUpdatedEventOrderByInput>>
+}
+
+export type QueryInvitesTransferredEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<InvitesTransferredEventWhereInput>
+  orderBy?: Maybe<Array<InvitesTransferredEventOrderByInput>>
+}
+
+export type QueryInvitesTransferredEventByUniqueInputArgs = {
+  where: InvitesTransferredEventWhereUniqueInput
+}
+
+export type QueryInvitesTransferredEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<InvitesTransferredEventWhereInput>
+  orderBy?: Maybe<Array<InvitesTransferredEventOrderByInput>>
+}
+
+export type QueryLeaderInvitationQuotaUpdatedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<LeaderInvitationQuotaUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<LeaderInvitationQuotaUpdatedEventOrderByInput>>
+}
+
+export type QueryLeaderInvitationQuotaUpdatedEventByUniqueInputArgs = {
+  where: LeaderInvitationQuotaUpdatedEventWhereUniqueInput
+}
+
+export type QueryLeaderInvitationQuotaUpdatedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<LeaderInvitationQuotaUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<LeaderInvitationQuotaUpdatedEventOrderByInput>>
+}
+
+export type QueryLeaderSetEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<LeaderSetEventWhereInput>
+  orderBy?: Maybe<Array<LeaderSetEventOrderByInput>>
+}
+
+export type QueryLeaderSetEventByUniqueInputArgs = {
+  where: LeaderSetEventWhereUniqueInput
+}
+
+export type QueryLeaderSetEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<LeaderSetEventWhereInput>
+  orderBy?: Maybe<Array<LeaderSetEventOrderByInput>>
+}
+
+export type QueryLeaderUnsetEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<LeaderUnsetEventWhereInput>
+  orderBy?: Maybe<Array<LeaderUnsetEventOrderByInput>>
+}
+
+export type QueryLeaderUnsetEventByUniqueInputArgs = {
+  where: LeaderUnsetEventWhereUniqueInput
+}
+
+export type QueryLeaderUnsetEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<LeaderUnsetEventWhereInput>
+  orderBy?: Maybe<Array<LeaderUnsetEventOrderByInput>>
+}
+
+export type QueryMemberAccountsUpdatedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<MemberAccountsUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<MemberAccountsUpdatedEventOrderByInput>>
+}
+
+export type QueryMemberAccountsUpdatedEventByUniqueInputArgs = {
+  where: MemberAccountsUpdatedEventWhereUniqueInput
+}
+
+export type QueryMemberAccountsUpdatedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<MemberAccountsUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<MemberAccountsUpdatedEventOrderByInput>>
+}
+
+export type QueryMemberInvitedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<MemberInvitedEventWhereInput>
+  orderBy?: Maybe<Array<MemberInvitedEventOrderByInput>>
+}
+
+export type QueryMemberInvitedEventByUniqueInputArgs = {
+  where: MemberInvitedEventWhereUniqueInput
+}
+
+export type QueryMemberInvitedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<MemberInvitedEventWhereInput>
+  orderBy?: Maybe<Array<MemberInvitedEventOrderByInput>>
+}
+
+export type QueryMemberMetadataArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<MemberMetadataWhereInput>
+  orderBy?: Maybe<Array<MemberMetadataOrderByInput>>
+}
+
+export type QueryMemberMetadataByUniqueInputArgs = {
+  where: MemberMetadataWhereUniqueInput
+}
+
+export type QueryMemberMetadataConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<MemberMetadataWhereInput>
+  orderBy?: Maybe<Array<MemberMetadataOrderByInput>>
+}
+
+export type QueryMemberProfileUpdatedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<MemberProfileUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<MemberProfileUpdatedEventOrderByInput>>
+}
+
+export type QueryMemberProfileUpdatedEventByUniqueInputArgs = {
+  where: MemberProfileUpdatedEventWhereUniqueInput
+}
+
+export type QueryMemberProfileUpdatedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<MemberProfileUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<MemberProfileUpdatedEventOrderByInput>>
+}
+
+export type QueryMemberVerificationStatusUpdatedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<MemberVerificationStatusUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<MemberVerificationStatusUpdatedEventOrderByInput>>
+}
+
+export type QueryMemberVerificationStatusUpdatedEventByUniqueInputArgs = {
+  where: MemberVerificationStatusUpdatedEventWhereUniqueInput
+}
+
+export type QueryMemberVerificationStatusUpdatedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<MemberVerificationStatusUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<MemberVerificationStatusUpdatedEventOrderByInput>>
+}
+
+export type QueryMembershipBoughtEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<MembershipBoughtEventWhereInput>
+  orderBy?: Maybe<Array<MembershipBoughtEventOrderByInput>>
+}
+
+export type QueryMembershipBoughtEventByUniqueInputArgs = {
+  where: MembershipBoughtEventWhereUniqueInput
+}
+
+export type QueryMembershipBoughtEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<MembershipBoughtEventWhereInput>
+  orderBy?: Maybe<Array<MembershipBoughtEventOrderByInput>>
+}
+
+export type QueryMembershipPriceUpdatedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<MembershipPriceUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<MembershipPriceUpdatedEventOrderByInput>>
+}
+
+export type QueryMembershipPriceUpdatedEventByUniqueInputArgs = {
+  where: MembershipPriceUpdatedEventWhereUniqueInput
+}
+
+export type QueryMembershipPriceUpdatedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<MembershipPriceUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<MembershipPriceUpdatedEventOrderByInput>>
+}
+
+export type QueryMembershipSystemSnapshotsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<MembershipSystemSnapshotWhereInput>
+  orderBy?: Maybe<Array<MembershipSystemSnapshotOrderByInput>>
+}
+
+export type QueryMembershipSystemSnapshotByUniqueInputArgs = {
+  where: MembershipSystemSnapshotWhereUniqueInput
+}
+
+export type QueryMembershipSystemSnapshotsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<MembershipSystemSnapshotWhereInput>
+  orderBy?: Maybe<Array<MembershipSystemSnapshotOrderByInput>>
+}
+
+export type QueryMembershipsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<MembershipWhereInput>
+  orderBy?: Maybe<Array<MembershipOrderByInput>>
+}
+
+export type QueryMembershipByUniqueInputArgs = {
+  where: MembershipWhereUniqueInput
+}
+
+export type QueryMembershipsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<MembershipWhereInput>
+  orderBy?: Maybe<Array<MembershipOrderByInput>>
+}
+
+export type QueryNewMissedRewardLevelReachedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<NewMissedRewardLevelReachedEventWhereInput>
+  orderBy?: Maybe<Array<NewMissedRewardLevelReachedEventOrderByInput>>
+}
+
+export type QueryNewMissedRewardLevelReachedEventByUniqueInputArgs = {
+  where: NewMissedRewardLevelReachedEventWhereUniqueInput
+}
+
+export type QueryNewMissedRewardLevelReachedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<NewMissedRewardLevelReachedEventWhereInput>
+  orderBy?: Maybe<Array<NewMissedRewardLevelReachedEventOrderByInput>>
+}
+
+export type QueryOpeningAddedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<OpeningAddedEventWhereInput>
+  orderBy?: Maybe<Array<OpeningAddedEventOrderByInput>>
+}
+
+export type QueryOpeningAddedEventByUniqueInputArgs = {
+  where: OpeningAddedEventWhereUniqueInput
+}
+
+export type QueryOpeningAddedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<OpeningAddedEventWhereInput>
+  orderBy?: Maybe<Array<OpeningAddedEventOrderByInput>>
+}
+
+export type QueryOpeningCanceledEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<OpeningCanceledEventWhereInput>
+  orderBy?: Maybe<Array<OpeningCanceledEventOrderByInput>>
+}
+
+export type QueryOpeningCanceledEventByUniqueInputArgs = {
+  where: OpeningCanceledEventWhereUniqueInput
+}
+
+export type QueryOpeningCanceledEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<OpeningCanceledEventWhereInput>
+  orderBy?: Maybe<Array<OpeningCanceledEventOrderByInput>>
+}
+
+export type QueryOpeningFilledEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<OpeningFilledEventWhereInput>
+  orderBy?: Maybe<Array<OpeningFilledEventOrderByInput>>
+}
+
+export type QueryOpeningFilledEventByUniqueInputArgs = {
+  where: OpeningFilledEventWhereUniqueInput
+}
+
+export type QueryOpeningFilledEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<OpeningFilledEventWhereInput>
+  orderBy?: Maybe<Array<OpeningFilledEventOrderByInput>>
+}
+
+export type QueryMembersByHandleArgs = {
+  whereMembership?: Maybe<MembershipWhereInput>
+  skip?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  text: Scalars['String']
+}
+
+export type QueryReferralCutUpdatedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<ReferralCutUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<ReferralCutUpdatedEventOrderByInput>>
+}
+
+export type QueryReferralCutUpdatedEventByUniqueInputArgs = {
+  where: ReferralCutUpdatedEventWhereUniqueInput
+}
+
+export type QueryReferralCutUpdatedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<ReferralCutUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<ReferralCutUpdatedEventOrderByInput>>
+}
+
+export type QueryRewardPaidEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<RewardPaidEventWhereInput>
+  orderBy?: Maybe<Array<RewardPaidEventOrderByInput>>
+}
+
+export type QueryRewardPaidEventByUniqueInputArgs = {
+  where: RewardPaidEventWhereUniqueInput
+}
+
+export type QueryRewardPaidEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<RewardPaidEventWhereInput>
+  orderBy?: Maybe<Array<RewardPaidEventOrderByInput>>
+}
+
+export type QueryStakeDecreasedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<StakeDecreasedEventWhereInput>
+  orderBy?: Maybe<Array<StakeDecreasedEventOrderByInput>>
+}
+
+export type QueryStakeDecreasedEventByUniqueInputArgs = {
+  where: StakeDecreasedEventWhereUniqueInput
+}
+
+export type QueryStakeDecreasedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<StakeDecreasedEventWhereInput>
+  orderBy?: Maybe<Array<StakeDecreasedEventOrderByInput>>
+}
+
+export type QueryStakeIncreasedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<StakeIncreasedEventWhereInput>
+  orderBy?: Maybe<Array<StakeIncreasedEventOrderByInput>>
+}
+
+export type QueryStakeIncreasedEventByUniqueInputArgs = {
+  where: StakeIncreasedEventWhereUniqueInput
+}
+
+export type QueryStakeIncreasedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<StakeIncreasedEventWhereInput>
+  orderBy?: Maybe<Array<StakeIncreasedEventOrderByInput>>
+}
+
+export type QueryStakeSlashedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<StakeSlashedEventWhereInput>
+  orderBy?: Maybe<Array<StakeSlashedEventOrderByInput>>
+}
+
+export type QueryStakeSlashedEventByUniqueInputArgs = {
+  where: StakeSlashedEventWhereUniqueInput
+}
+
+export type QueryStakeSlashedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<StakeSlashedEventWhereInput>
+  orderBy?: Maybe<Array<StakeSlashedEventOrderByInput>>
+}
+
+export type QueryStakingAccountAddedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<StakingAccountAddedEventWhereInput>
+  orderBy?: Maybe<Array<StakingAccountAddedEventOrderByInput>>
+}
+
+export type QueryStakingAccountAddedEventByUniqueInputArgs = {
+  where: StakingAccountAddedEventWhereUniqueInput
+}
+
+export type QueryStakingAccountAddedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<StakingAccountAddedEventWhereInput>
+  orderBy?: Maybe<Array<StakingAccountAddedEventOrderByInput>>
+}
+
+export type QueryStakingAccountConfirmedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<StakingAccountConfirmedEventWhereInput>
+  orderBy?: Maybe<Array<StakingAccountConfirmedEventOrderByInput>>
+}
+
+export type QueryStakingAccountConfirmedEventByUniqueInputArgs = {
+  where: StakingAccountConfirmedEventWhereUniqueInput
+}
+
+export type QueryStakingAccountConfirmedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<StakingAccountConfirmedEventWhereInput>
+  orderBy?: Maybe<Array<StakingAccountConfirmedEventOrderByInput>>
+}
+
+export type QueryStakingAccountRemovedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<StakingAccountRemovedEventWhereInput>
+  orderBy?: Maybe<Array<StakingAccountRemovedEventOrderByInput>>
+}
+
+export type QueryStakingAccountRemovedEventByUniqueInputArgs = {
+  where: StakingAccountRemovedEventWhereUniqueInput
+}
+
+export type QueryStakingAccountRemovedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<StakingAccountRemovedEventWhereInput>
+  orderBy?: Maybe<Array<StakingAccountRemovedEventOrderByInput>>
+}
+
+export type QueryStatusTextChangedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<StatusTextChangedEventWhereInput>
+  orderBy?: Maybe<Array<StatusTextChangedEventOrderByInput>>
+}
+
+export type QueryStatusTextChangedEventByUniqueInputArgs = {
+  where: StatusTextChangedEventWhereUniqueInput
+}
+
+export type QueryStatusTextChangedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<StatusTextChangedEventWhereInput>
+  orderBy?: Maybe<Array<StatusTextChangedEventOrderByInput>>
+}
+
+export type QueryTerminatedLeaderEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<TerminatedLeaderEventWhereInput>
+  orderBy?: Maybe<Array<TerminatedLeaderEventOrderByInput>>
+}
+
+export type QueryTerminatedLeaderEventByUniqueInputArgs = {
+  where: TerminatedLeaderEventWhereUniqueInput
+}
+
+export type QueryTerminatedLeaderEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<TerminatedLeaderEventWhereInput>
+  orderBy?: Maybe<Array<TerminatedLeaderEventOrderByInput>>
+}
+
+export type QueryTerminatedWorkerEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<TerminatedWorkerEventWhereInput>
+  orderBy?: Maybe<Array<TerminatedWorkerEventOrderByInput>>
+}
+
+export type QueryTerminatedWorkerEventByUniqueInputArgs = {
+  where: TerminatedWorkerEventWhereUniqueInput
+}
+
+export type QueryTerminatedWorkerEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<TerminatedWorkerEventWhereInput>
+  orderBy?: Maybe<Array<TerminatedWorkerEventOrderByInput>>
+}
+
+export type QueryUpcomingWorkingGroupOpeningsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<UpcomingWorkingGroupOpeningWhereInput>
+  orderBy?: Maybe<Array<UpcomingWorkingGroupOpeningOrderByInput>>
+}
+
+export type QueryUpcomingWorkingGroupOpeningByUniqueInputArgs = {
+  where: UpcomingWorkingGroupOpeningWhereUniqueInput
+}
+
+export type QueryUpcomingWorkingGroupOpeningsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<UpcomingWorkingGroupOpeningWhereInput>
+  orderBy?: Maybe<Array<UpcomingWorkingGroupOpeningOrderByInput>>
+}
+
+export type QueryWorkerExitedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<WorkerExitedEventWhereInput>
+  orderBy?: Maybe<Array<WorkerExitedEventOrderByInput>>
+}
+
+export type QueryWorkerExitedEventByUniqueInputArgs = {
+  where: WorkerExitedEventWhereUniqueInput
+}
+
+export type QueryWorkerExitedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<WorkerExitedEventWhereInput>
+  orderBy?: Maybe<Array<WorkerExitedEventOrderByInput>>
+}
+
+export type QueryWorkerRewardAccountUpdatedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<WorkerRewardAccountUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<WorkerRewardAccountUpdatedEventOrderByInput>>
+}
+
+export type QueryWorkerRewardAccountUpdatedEventByUniqueInputArgs = {
+  where: WorkerRewardAccountUpdatedEventWhereUniqueInput
+}
+
+export type QueryWorkerRewardAccountUpdatedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<WorkerRewardAccountUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<WorkerRewardAccountUpdatedEventOrderByInput>>
+}
+
+export type QueryWorkerRewardAmountUpdatedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<WorkerRewardAmountUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<WorkerRewardAmountUpdatedEventOrderByInput>>
+}
+
+export type QueryWorkerRewardAmountUpdatedEventByUniqueInputArgs = {
+  where: WorkerRewardAmountUpdatedEventWhereUniqueInput
+}
+
+export type QueryWorkerRewardAmountUpdatedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<WorkerRewardAmountUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<WorkerRewardAmountUpdatedEventOrderByInput>>
+}
+
+export type QueryWorkerRoleAccountUpdatedEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<WorkerRoleAccountUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<WorkerRoleAccountUpdatedEventOrderByInput>>
+}
+
+export type QueryWorkerRoleAccountUpdatedEventByUniqueInputArgs = {
+  where: WorkerRoleAccountUpdatedEventWhereUniqueInput
+}
+
+export type QueryWorkerRoleAccountUpdatedEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<WorkerRoleAccountUpdatedEventWhereInput>
+  orderBy?: Maybe<Array<WorkerRoleAccountUpdatedEventOrderByInput>>
+}
+
+export type QueryWorkerStartedLeavingEventsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<WorkerStartedLeavingEventWhereInput>
+  orderBy?: Maybe<Array<WorkerStartedLeavingEventOrderByInput>>
+}
+
+export type QueryWorkerStartedLeavingEventByUniqueInputArgs = {
+  where: WorkerStartedLeavingEventWhereUniqueInput
+}
+
+export type QueryWorkerStartedLeavingEventsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<WorkerStartedLeavingEventWhereInput>
+  orderBy?: Maybe<Array<WorkerStartedLeavingEventOrderByInput>>
+}
+
+export type QueryWorkersArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<WorkerWhereInput>
+  orderBy?: Maybe<Array<WorkerOrderByInput>>
+}
+
+export type QueryWorkerByUniqueInputArgs = {
+  where: WorkerWhereUniqueInput
+}
+
+export type QueryWorkersConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<WorkerWhereInput>
+  orderBy?: Maybe<Array<WorkerOrderByInput>>
+}
+
+export type QueryWorkingGroupApplicationsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<WorkingGroupApplicationWhereInput>
+  orderBy?: Maybe<Array<WorkingGroupApplicationOrderByInput>>
+}
+
+export type QueryWorkingGroupApplicationByUniqueInputArgs = {
+  where: WorkingGroupApplicationWhereUniqueInput
+}
+
+export type QueryWorkingGroupApplicationsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<WorkingGroupApplicationWhereInput>
+  orderBy?: Maybe<Array<WorkingGroupApplicationOrderByInput>>
+}
+
+export type QueryWorkingGroupMetadataArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<WorkingGroupMetadataWhereInput>
+  orderBy?: Maybe<Array<WorkingGroupMetadataOrderByInput>>
+}
+
+export type QueryWorkingGroupMetadataByUniqueInputArgs = {
+  where: WorkingGroupMetadataWhereUniqueInput
+}
+
+export type QueryWorkingGroupMetadataConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<WorkingGroupMetadataWhereInput>
+  orderBy?: Maybe<Array<WorkingGroupMetadataOrderByInput>>
+}
+
+export type QueryWorkingGroupOpeningMetadataArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<WorkingGroupOpeningMetadataWhereInput>
+  orderBy?: Maybe<Array<WorkingGroupOpeningMetadataOrderByInput>>
+}
+
+export type QueryWorkingGroupOpeningMetadataByUniqueInputArgs = {
+  where: WorkingGroupOpeningMetadataWhereUniqueInput
+}
+
+export type QueryWorkingGroupOpeningMetadataConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<WorkingGroupOpeningMetadataWhereInput>
+  orderBy?: Maybe<Array<WorkingGroupOpeningMetadataOrderByInput>>
+}
+
+export type QueryWorkingGroupOpeningsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<WorkingGroupOpeningWhereInput>
+  orderBy?: Maybe<Array<WorkingGroupOpeningOrderByInput>>
+}
+
+export type QueryWorkingGroupOpeningByUniqueInputArgs = {
+  where: WorkingGroupOpeningWhereUniqueInput
+}
+
+export type QueryWorkingGroupOpeningsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<WorkingGroupOpeningWhereInput>
+  orderBy?: Maybe<Array<WorkingGroupOpeningOrderByInput>>
+}
+
+export type QueryWorkingGroupsArgs = {
+  offset?: Maybe<Scalars['Int']>
+  limit?: Maybe<Scalars['Int']>
+  where?: Maybe<WorkingGroupWhereInput>
+  orderBy?: Maybe<Array<WorkingGroupOrderByInput>>
+}
+
+export type QueryWorkingGroupByUniqueInputArgs = {
+  where: WorkingGroupWhereUniqueInput
+}
+
+export type QueryWorkingGroupsConnectionArgs = {
+  first?: Maybe<Scalars['Int']>
+  after?: Maybe<Scalars['String']>
+  last?: Maybe<Scalars['Int']>
+  before?: Maybe<Scalars['String']>
+  where?: Maybe<WorkingGroupWhereInput>
+  orderBy?: Maybe<Array<WorkingGroupOrderByInput>>
+}
+
+export type ReferralCutUpdatedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  /** New cut value. */
+  newValue: Scalars['Int']
+}
+
+export type ReferralCutUpdatedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<ReferralCutUpdatedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type ReferralCutUpdatedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  newValue: Scalars['Float']
+}
+
+export type ReferralCutUpdatedEventEdge = {
+  node: ReferralCutUpdatedEvent
+  cursor: Scalars['String']
+}
+
+export enum ReferralCutUpdatedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  NewValueAsc = 'newValue_ASC',
+  NewValueDesc = 'newValue_DESC',
+}
+
+export type ReferralCutUpdatedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  newValue?: Maybe<Scalars['Float']>
+}
+
+export type ReferralCutUpdatedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  newValue_eq?: Maybe<Scalars['Int']>
+  newValue_gt?: Maybe<Scalars['Int']>
+  newValue_gte?: Maybe<Scalars['Int']>
+  newValue_lt?: Maybe<Scalars['Int']>
+  newValue_lte?: Maybe<Scalars['Int']>
+  newValue_in?: Maybe<Array<Scalars['Int']>>
+  AND?: Maybe<Array<ReferralCutUpdatedEventWhereInput>>
+  OR?: Maybe<Array<ReferralCutUpdatedEventWhereInput>>
+}
+
+export type ReferralCutUpdatedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type RewardPaidEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  worker: Worker
+  workerId: Scalars['String']
+  /** The account that recieved the reward */
+  rewardAccount: Scalars['String']
+  /** Amount recieved */
+  amount: Scalars['BigInt']
+  /** Type of the payment (REGULAR/MISSED) */
+  type: RewardPaymentType
+}
+
+export type RewardPaidEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<RewardPaidEventEdge>
+  pageInfo: PageInfo
+}
+
+export type RewardPaidEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  worker: Scalars['ID']
+  rewardAccount: Scalars['String']
+  amount: Scalars['BigInt']
+  type: RewardPaymentType
+}
+
+export type RewardPaidEventEdge = {
+  node: RewardPaidEvent
+  cursor: Scalars['String']
+}
+
+export enum RewardPaidEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  WorkerAsc = 'worker_ASC',
+  WorkerDesc = 'worker_DESC',
+  RewardAccountAsc = 'rewardAccount_ASC',
+  RewardAccountDesc = 'rewardAccount_DESC',
+  AmountAsc = 'amount_ASC',
+  AmountDesc = 'amount_DESC',
+  TypeAsc = 'type_ASC',
+  TypeDesc = 'type_DESC',
+}
+
+export type RewardPaidEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  worker?: Maybe<Scalars['ID']>
+  rewardAccount?: Maybe<Scalars['String']>
+  amount?: Maybe<Scalars['BigInt']>
+  type?: Maybe<RewardPaymentType>
+}
+
+export type RewardPaidEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  worker_eq?: Maybe<Scalars['ID']>
+  worker_in?: Maybe<Array<Scalars['ID']>>
+  rewardAccount_eq?: Maybe<Scalars['String']>
+  rewardAccount_contains?: Maybe<Scalars['String']>
+  rewardAccount_startsWith?: Maybe<Scalars['String']>
+  rewardAccount_endsWith?: Maybe<Scalars['String']>
+  rewardAccount_in?: Maybe<Array<Scalars['String']>>
+  amount_eq?: Maybe<Scalars['BigInt']>
+  amount_gt?: Maybe<Scalars['BigInt']>
+  amount_gte?: Maybe<Scalars['BigInt']>
+  amount_lt?: Maybe<Scalars['BigInt']>
+  amount_lte?: Maybe<Scalars['BigInt']>
+  amount_in?: Maybe<Array<Scalars['BigInt']>>
+  type_eq?: Maybe<RewardPaymentType>
+  type_in?: Maybe<Array<RewardPaymentType>>
+  group?: Maybe<WorkingGroupWhereInput>
+  worker?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<RewardPaidEventWhereInput>>
+  OR?: Maybe<Array<RewardPaidEventWhereInput>>
+}
+
+export type RewardPaidEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export enum RewardPaymentType {
+  Regular = 'REGULAR',
+  Missed = 'MISSED',
+}
+
+export type StakeDecreasedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  worker: Worker
+  workerId: Scalars['String']
+  /** The amount of JOY the stake was decreased by */
+  amount: Scalars['BigInt']
+}
+
+export type StakeDecreasedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<StakeDecreasedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type StakeDecreasedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  worker: Scalars['ID']
+  amount: Scalars['BigInt']
+}
+
+export type StakeDecreasedEventEdge = {
+  node: StakeDecreasedEvent
+  cursor: Scalars['String']
+}
+
+export enum StakeDecreasedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  WorkerAsc = 'worker_ASC',
+  WorkerDesc = 'worker_DESC',
+  AmountAsc = 'amount_ASC',
+  AmountDesc = 'amount_DESC',
+}
+
+export type StakeDecreasedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  worker?: Maybe<Scalars['ID']>
+  amount?: Maybe<Scalars['BigInt']>
+}
+
+export type StakeDecreasedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  worker_eq?: Maybe<Scalars['ID']>
+  worker_in?: Maybe<Array<Scalars['ID']>>
+  amount_eq?: Maybe<Scalars['BigInt']>
+  amount_gt?: Maybe<Scalars['BigInt']>
+  amount_gte?: Maybe<Scalars['BigInt']>
+  amount_lt?: Maybe<Scalars['BigInt']>
+  amount_lte?: Maybe<Scalars['BigInt']>
+  amount_in?: Maybe<Array<Scalars['BigInt']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  worker?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<StakeDecreasedEventWhereInput>>
+  OR?: Maybe<Array<StakeDecreasedEventWhereInput>>
+}
+
+export type StakeDecreasedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type StakeIncreasedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  worker: Worker
+  workerId: Scalars['String']
+  /** The amount of JOY the stake was increased by */
+  amount: Scalars['BigInt']
+}
+
+export type StakeIncreasedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<StakeIncreasedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type StakeIncreasedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  worker: Scalars['ID']
+  amount: Scalars['BigInt']
+}
+
+export type StakeIncreasedEventEdge = {
+  node: StakeIncreasedEvent
+  cursor: Scalars['String']
+}
+
+export enum StakeIncreasedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  WorkerAsc = 'worker_ASC',
+  WorkerDesc = 'worker_DESC',
+  AmountAsc = 'amount_ASC',
+  AmountDesc = 'amount_DESC',
+}
+
+export type StakeIncreasedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  worker?: Maybe<Scalars['ID']>
+  amount?: Maybe<Scalars['BigInt']>
+}
+
+export type StakeIncreasedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  worker_eq?: Maybe<Scalars['ID']>
+  worker_in?: Maybe<Array<Scalars['ID']>>
+  amount_eq?: Maybe<Scalars['BigInt']>
+  amount_gt?: Maybe<Scalars['BigInt']>
+  amount_gte?: Maybe<Scalars['BigInt']>
+  amount_lt?: Maybe<Scalars['BigInt']>
+  amount_lte?: Maybe<Scalars['BigInt']>
+  amount_in?: Maybe<Array<Scalars['BigInt']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  worker?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<StakeIncreasedEventWhereInput>>
+  OR?: Maybe<Array<StakeIncreasedEventWhereInput>>
+}
+
+export type StakeIncreasedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type StakeSlashedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  worker: Worker
+  workerId: Scalars['String']
+  /** Balance that was requested to be slashed */
+  requestedAmount: Scalars['BigInt']
+  /** Balance that was actually slashed */
+  slashedAmount: Scalars['BigInt']
+  /** Optional rationale */
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type StakeSlashedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<StakeSlashedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type StakeSlashedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  worker: Scalars['ID']
+  requestedAmount: Scalars['BigInt']
+  slashedAmount: Scalars['BigInt']
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type StakeSlashedEventEdge = {
+  node: StakeSlashedEvent
+  cursor: Scalars['String']
+}
+
+export enum StakeSlashedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  WorkerAsc = 'worker_ASC',
+  WorkerDesc = 'worker_DESC',
+  RequestedAmountAsc = 'requestedAmount_ASC',
+  RequestedAmountDesc = 'requestedAmount_DESC',
+  SlashedAmountAsc = 'slashedAmount_ASC',
+  SlashedAmountDesc = 'slashedAmount_DESC',
+  RationaleAsc = 'rationale_ASC',
+  RationaleDesc = 'rationale_DESC',
+}
+
+export type StakeSlashedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  worker?: Maybe<Scalars['ID']>
+  requestedAmount?: Maybe<Scalars['BigInt']>
+  slashedAmount?: Maybe<Scalars['BigInt']>
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type StakeSlashedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  worker_eq?: Maybe<Scalars['ID']>
+  worker_in?: Maybe<Array<Scalars['ID']>>
+  requestedAmount_eq?: Maybe<Scalars['BigInt']>
+  requestedAmount_gt?: Maybe<Scalars['BigInt']>
+  requestedAmount_gte?: Maybe<Scalars['BigInt']>
+  requestedAmount_lt?: Maybe<Scalars['BigInt']>
+  requestedAmount_lte?: Maybe<Scalars['BigInt']>
+  requestedAmount_in?: Maybe<Array<Scalars['BigInt']>>
+  slashedAmount_eq?: Maybe<Scalars['BigInt']>
+  slashedAmount_gt?: Maybe<Scalars['BigInt']>
+  slashedAmount_gte?: Maybe<Scalars['BigInt']>
+  slashedAmount_lt?: Maybe<Scalars['BigInt']>
+  slashedAmount_lte?: Maybe<Scalars['BigInt']>
+  slashedAmount_in?: Maybe<Array<Scalars['BigInt']>>
+  rationale_eq?: Maybe<Scalars['String']>
+  rationale_contains?: Maybe<Scalars['String']>
+  rationale_startsWith?: Maybe<Scalars['String']>
+  rationale_endsWith?: Maybe<Scalars['String']>
+  rationale_in?: Maybe<Array<Scalars['String']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  worker?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<StakeSlashedEventWhereInput>>
+  OR?: Maybe<Array<StakeSlashedEventWhereInput>>
+}
+
+export type StakeSlashedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type StakingAccountAddedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  member: Membership
+  memberId: Scalars['String']
+  /** New staking account in SS58 encoding. */
+  account: Scalars['String']
+}
+
+export type StakingAccountAddedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<StakingAccountAddedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type StakingAccountAddedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  member: Scalars['ID']
+  account: Scalars['String']
+}
+
+export type StakingAccountAddedEventEdge = {
+  node: StakingAccountAddedEvent
+  cursor: Scalars['String']
+}
+
+export enum StakingAccountAddedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  MemberAsc = 'member_ASC',
+  MemberDesc = 'member_DESC',
+  AccountAsc = 'account_ASC',
+  AccountDesc = 'account_DESC',
+}
+
+export type StakingAccountAddedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  member?: Maybe<Scalars['ID']>
+  account?: Maybe<Scalars['String']>
+}
+
+export type StakingAccountAddedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  member_eq?: Maybe<Scalars['ID']>
+  member_in?: Maybe<Array<Scalars['ID']>>
+  account_eq?: Maybe<Scalars['String']>
+  account_contains?: Maybe<Scalars['String']>
+  account_startsWith?: Maybe<Scalars['String']>
+  account_endsWith?: Maybe<Scalars['String']>
+  account_in?: Maybe<Array<Scalars['String']>>
+  member?: Maybe<MembershipWhereInput>
+  AND?: Maybe<Array<StakingAccountAddedEventWhereInput>>
+  OR?: Maybe<Array<StakingAccountAddedEventWhereInput>>
+}
+
+export type StakingAccountAddedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type StakingAccountConfirmedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  member: Membership
+  memberId: Scalars['String']
+  /** New staking account in SS58 encoding. */
+  account: Scalars['String']
+}
+
+export type StakingAccountConfirmedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<StakingAccountConfirmedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type StakingAccountConfirmedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  member: Scalars['ID']
+  account: Scalars['String']
+}
+
+export type StakingAccountConfirmedEventEdge = {
+  node: StakingAccountConfirmedEvent
+  cursor: Scalars['String']
+}
+
+export enum StakingAccountConfirmedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  MemberAsc = 'member_ASC',
+  MemberDesc = 'member_DESC',
+  AccountAsc = 'account_ASC',
+  AccountDesc = 'account_DESC',
+}
+
+export type StakingAccountConfirmedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  member?: Maybe<Scalars['ID']>
+  account?: Maybe<Scalars['String']>
+}
+
+export type StakingAccountConfirmedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  member_eq?: Maybe<Scalars['ID']>
+  member_in?: Maybe<Array<Scalars['ID']>>
+  account_eq?: Maybe<Scalars['String']>
+  account_contains?: Maybe<Scalars['String']>
+  account_startsWith?: Maybe<Scalars['String']>
+  account_endsWith?: Maybe<Scalars['String']>
+  account_in?: Maybe<Array<Scalars['String']>>
+  member?: Maybe<MembershipWhereInput>
+  AND?: Maybe<Array<StakingAccountConfirmedEventWhereInput>>
+  OR?: Maybe<Array<StakingAccountConfirmedEventWhereInput>>
+}
+
+export type StakingAccountConfirmedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type StakingAccountRemovedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  member: Membership
+  memberId: Scalars['String']
+  /** New staking account in SS58 encoding. */
+  account: Scalars['String']
+}
+
+export type StakingAccountRemovedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<StakingAccountRemovedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type StakingAccountRemovedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  member: Scalars['ID']
+  account: Scalars['String']
+}
+
+export type StakingAccountRemovedEventEdge = {
+  node: StakingAccountRemovedEvent
+  cursor: Scalars['String']
+}
+
+export enum StakingAccountRemovedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  MemberAsc = 'member_ASC',
+  MemberDesc = 'member_DESC',
+  AccountAsc = 'account_ASC',
+  AccountDesc = 'account_DESC',
+}
+
+export type StakingAccountRemovedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  member?: Maybe<Scalars['ID']>
+  account?: Maybe<Scalars['String']>
+}
+
+export type StakingAccountRemovedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  member_eq?: Maybe<Scalars['ID']>
+  member_in?: Maybe<Array<Scalars['ID']>>
+  account_eq?: Maybe<Scalars['String']>
+  account_contains?: Maybe<Scalars['String']>
+  account_startsWith?: Maybe<Scalars['String']>
+  account_endsWith?: Maybe<Scalars['String']>
+  account_in?: Maybe<Array<Scalars['String']>>
+  member?: Maybe<MembershipWhereInput>
+  AND?: Maybe<Array<StakingAccountRemovedEventWhereInput>>
+  OR?: Maybe<Array<StakingAccountRemovedEventWhereInput>>
+}
+
+export type StakingAccountRemovedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type StandardDeleteResponse = {
+  id: Scalars['ID']
+}
+
+export type StatusTextChangedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  /** Original action metadata as hex string */
+  metadata?: Maybe<Scalars['String']>
+  /** Event result depeding on the metadata action type */
+  result: WorkingGroupMetadataActionResult
+  upcomingworkinggroupopeningcreatedInEvent?: Maybe<Array<UpcomingWorkingGroupOpening>>
+  workinggroupmetadatasetInEvent?: Maybe<Array<WorkingGroupMetadata>>
+}
+
+export type StatusTextChangedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<StatusTextChangedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type StatusTextChangedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  metadata?: Maybe<Scalars['String']>
+  result: Scalars['JSONObject']
+}
+
+export type StatusTextChangedEventEdge = {
+  node: StatusTextChangedEvent
+  cursor: Scalars['String']
+}
+
+export enum StatusTextChangedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  MetadataAsc = 'metadata_ASC',
+  MetadataDesc = 'metadata_DESC',
+}
+
+export type StatusTextChangedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  metadata?: Maybe<Scalars['String']>
+  result?: Maybe<Scalars['JSONObject']>
+}
+
+export type StatusTextChangedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  metadata_eq?: Maybe<Scalars['String']>
+  metadata_contains?: Maybe<Scalars['String']>
+  metadata_startsWith?: Maybe<Scalars['String']>
+  metadata_endsWith?: Maybe<Scalars['String']>
+  metadata_in?: Maybe<Array<Scalars['String']>>
+  result_json?: Maybe<Scalars['JSONObject']>
+  group?: Maybe<WorkingGroupWhereInput>
+  upcomingworkinggroupopeningcreatedInEvent_none?: Maybe<UpcomingWorkingGroupOpeningWhereInput>
+  upcomingworkinggroupopeningcreatedInEvent_some?: Maybe<UpcomingWorkingGroupOpeningWhereInput>
+  upcomingworkinggroupopeningcreatedInEvent_every?: Maybe<UpcomingWorkingGroupOpeningWhereInput>
+  workinggroupmetadatasetInEvent_none?: Maybe<WorkingGroupMetadataWhereInput>
+  workinggroupmetadatasetInEvent_some?: Maybe<WorkingGroupMetadataWhereInput>
+  workinggroupmetadatasetInEvent_every?: Maybe<WorkingGroupMetadataWhereInput>
+  AND?: Maybe<Array<StatusTextChangedEventWhereInput>>
+  OR?: Maybe<Array<StatusTextChangedEventWhereInput>>
+}
+
+export type StatusTextChangedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type Subscription = {
+  stateSubscription: ProcessorState
+}
+
+export type TerminatedLeaderEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  worker: Worker
+  workerId: Scalars['String']
+  /** Slash amount (if any) */
+  penalty?: Maybe<Scalars['BigInt']>
+  /** Optional rationale */
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type TerminatedLeaderEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<TerminatedLeaderEventEdge>
+  pageInfo: PageInfo
+}
+
+export type TerminatedLeaderEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  worker: Scalars['ID']
+  penalty?: Maybe<Scalars['BigInt']>
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type TerminatedLeaderEventEdge = {
+  node: TerminatedLeaderEvent
+  cursor: Scalars['String']
+}
+
+export enum TerminatedLeaderEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  WorkerAsc = 'worker_ASC',
+  WorkerDesc = 'worker_DESC',
+  PenaltyAsc = 'penalty_ASC',
+  PenaltyDesc = 'penalty_DESC',
+  RationaleAsc = 'rationale_ASC',
+  RationaleDesc = 'rationale_DESC',
+}
+
+export type TerminatedLeaderEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  worker?: Maybe<Scalars['ID']>
+  penalty?: Maybe<Scalars['BigInt']>
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type TerminatedLeaderEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  worker_eq?: Maybe<Scalars['ID']>
+  worker_in?: Maybe<Array<Scalars['ID']>>
+  penalty_eq?: Maybe<Scalars['BigInt']>
+  penalty_gt?: Maybe<Scalars['BigInt']>
+  penalty_gte?: Maybe<Scalars['BigInt']>
+  penalty_lt?: Maybe<Scalars['BigInt']>
+  penalty_lte?: Maybe<Scalars['BigInt']>
+  penalty_in?: Maybe<Array<Scalars['BigInt']>>
+  rationale_eq?: Maybe<Scalars['String']>
+  rationale_contains?: Maybe<Scalars['String']>
+  rationale_startsWith?: Maybe<Scalars['String']>
+  rationale_endsWith?: Maybe<Scalars['String']>
+  rationale_in?: Maybe<Array<Scalars['String']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  worker?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<TerminatedLeaderEventWhereInput>>
+  OR?: Maybe<Array<TerminatedLeaderEventWhereInput>>
+}
+
+export type TerminatedLeaderEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type TerminatedWorkerEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  worker: Worker
+  workerId: Scalars['String']
+  /** Slash amount (if any) */
+  penalty?: Maybe<Scalars['BigInt']>
+  /** Optional rationale */
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type TerminatedWorkerEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<TerminatedWorkerEventEdge>
+  pageInfo: PageInfo
+}
+
+export type TerminatedWorkerEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  worker: Scalars['ID']
+  penalty?: Maybe<Scalars['BigInt']>
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type TerminatedWorkerEventEdge = {
+  node: TerminatedWorkerEvent
+  cursor: Scalars['String']
+}
+
+export enum TerminatedWorkerEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  WorkerAsc = 'worker_ASC',
+  WorkerDesc = 'worker_DESC',
+  PenaltyAsc = 'penalty_ASC',
+  PenaltyDesc = 'penalty_DESC',
+  RationaleAsc = 'rationale_ASC',
+  RationaleDesc = 'rationale_DESC',
+}
+
+export type TerminatedWorkerEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  worker?: Maybe<Scalars['ID']>
+  penalty?: Maybe<Scalars['BigInt']>
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type TerminatedWorkerEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  worker_eq?: Maybe<Scalars['ID']>
+  worker_in?: Maybe<Array<Scalars['ID']>>
+  penalty_eq?: Maybe<Scalars['BigInt']>
+  penalty_gt?: Maybe<Scalars['BigInt']>
+  penalty_gte?: Maybe<Scalars['BigInt']>
+  penalty_lt?: Maybe<Scalars['BigInt']>
+  penalty_lte?: Maybe<Scalars['BigInt']>
+  penalty_in?: Maybe<Array<Scalars['BigInt']>>
+  rationale_eq?: Maybe<Scalars['String']>
+  rationale_contains?: Maybe<Scalars['String']>
+  rationale_startsWith?: Maybe<Scalars['String']>
+  rationale_endsWith?: Maybe<Scalars['String']>
+  rationale_in?: Maybe<Array<Scalars['String']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  worker?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<TerminatedWorkerEventWhereInput>>
+  OR?: Maybe<Array<TerminatedWorkerEventWhereInput>>
+}
+
+export type TerminatedWorkerEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type UpcomingOpeningAdded = {
+  upcomingOpeningId: Scalars['String']
+}
+
+export type UpcomingOpeningAddedCreateInput = {
+  upcomingOpeningId: Scalars['String']
+}
+
+export type UpcomingOpeningAddedUpdateInput = {
+  upcomingOpeningId?: Maybe<Scalars['String']>
+}
+
+export type UpcomingOpeningAddedWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  upcomingOpeningId_eq?: Maybe<Scalars['String']>
+  upcomingOpeningId_contains?: Maybe<Scalars['String']>
+  upcomingOpeningId_startsWith?: Maybe<Scalars['String']>
+  upcomingOpeningId_endsWith?: Maybe<Scalars['String']>
+  upcomingOpeningId_in?: Maybe<Array<Scalars['String']>>
+  AND?: Maybe<Array<UpcomingOpeningAddedWhereInput>>
+  OR?: Maybe<Array<UpcomingOpeningAddedWhereInput>>
+}
+
+export type UpcomingOpeningAddedWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type UpcomingOpeningRemoved = {
+  upcomingOpeningId: Scalars['String']
+}
+
+export type UpcomingOpeningRemovedCreateInput = {
+  upcomingOpeningId: Scalars['String']
+}
+
+export type UpcomingOpeningRemovedUpdateInput = {
+  upcomingOpeningId?: Maybe<Scalars['String']>
+}
+
+export type UpcomingOpeningRemovedWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  upcomingOpeningId_eq?: Maybe<Scalars['String']>
+  upcomingOpeningId_contains?: Maybe<Scalars['String']>
+  upcomingOpeningId_startsWith?: Maybe<Scalars['String']>
+  upcomingOpeningId_endsWith?: Maybe<Scalars['String']>
+  upcomingOpeningId_in?: Maybe<Array<Scalars['String']>>
+  AND?: Maybe<Array<UpcomingOpeningRemovedWhereInput>>
+  OR?: Maybe<Array<UpcomingOpeningRemovedWhereInput>>
+}
+
+export type UpcomingOpeningRemovedWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type UpcomingWorkingGroupOpening = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  createdInEvent: StatusTextChangedEvent
+  createdInEventId: Scalars['String']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  /** Expected opening start time */
+  expectedStart?: Maybe<Scalars['DateTime']>
+  /** Expected min. application/role stake amount */
+  stakeAmount?: Maybe<Scalars['BigInt']>
+  /** Expected reward per block */
+  rewardPerBlock?: Maybe<Scalars['BigInt']>
+  metadata: WorkingGroupOpeningMetadata
+  metadataId: Scalars['String']
+}
+
+export type UpcomingWorkingGroupOpeningConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<UpcomingWorkingGroupOpeningEdge>
+  pageInfo: PageInfo
+}
+
+export type UpcomingWorkingGroupOpeningCreateInput = {
+  createdInEvent: Scalars['ID']
+  group: Scalars['ID']
+  expectedStart?: Maybe<Scalars['DateTime']>
+  stakeAmount?: Maybe<Scalars['BigInt']>
+  rewardPerBlock?: Maybe<Scalars['BigInt']>
+  metadata: Scalars['ID']
+}
+
+export type UpcomingWorkingGroupOpeningEdge = {
+  node: UpcomingWorkingGroupOpening
+  cursor: Scalars['String']
+}
+
+export enum UpcomingWorkingGroupOpeningOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  CreatedInEventAsc = 'createdInEvent_ASC',
+  CreatedInEventDesc = 'createdInEvent_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  ExpectedStartAsc = 'expectedStart_ASC',
+  ExpectedStartDesc = 'expectedStart_DESC',
+  StakeAmountAsc = 'stakeAmount_ASC',
+  StakeAmountDesc = 'stakeAmount_DESC',
+  RewardPerBlockAsc = 'rewardPerBlock_ASC',
+  RewardPerBlockDesc = 'rewardPerBlock_DESC',
+  MetadataAsc = 'metadata_ASC',
+  MetadataDesc = 'metadata_DESC',
+}
+
+export type UpcomingWorkingGroupOpeningUpdateInput = {
+  createdInEvent?: Maybe<Scalars['ID']>
+  group?: Maybe<Scalars['ID']>
+  expectedStart?: Maybe<Scalars['DateTime']>
+  stakeAmount?: Maybe<Scalars['BigInt']>
+  rewardPerBlock?: Maybe<Scalars['BigInt']>
+  metadata?: Maybe<Scalars['ID']>
+}
+
+export type UpcomingWorkingGroupOpeningWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  createdInEvent_eq?: Maybe<Scalars['ID']>
+  createdInEvent_in?: Maybe<Array<Scalars['ID']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  expectedStart_eq?: Maybe<Scalars['DateTime']>
+  expectedStart_lt?: Maybe<Scalars['DateTime']>
+  expectedStart_lte?: Maybe<Scalars['DateTime']>
+  expectedStart_gt?: Maybe<Scalars['DateTime']>
+  expectedStart_gte?: Maybe<Scalars['DateTime']>
+  stakeAmount_eq?: Maybe<Scalars['BigInt']>
+  stakeAmount_gt?: Maybe<Scalars['BigInt']>
+  stakeAmount_gte?: Maybe<Scalars['BigInt']>
+  stakeAmount_lt?: Maybe<Scalars['BigInt']>
+  stakeAmount_lte?: Maybe<Scalars['BigInt']>
+  stakeAmount_in?: Maybe<Array<Scalars['BigInt']>>
+  rewardPerBlock_eq?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_gt?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_gte?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_lt?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_lte?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_in?: Maybe<Array<Scalars['BigInt']>>
+  metadata_eq?: Maybe<Scalars['ID']>
+  metadata_in?: Maybe<Array<Scalars['ID']>>
+  createdInEvent?: Maybe<StatusTextChangedEventWhereInput>
+  group?: Maybe<WorkingGroupWhereInput>
+  metadata?: Maybe<WorkingGroupOpeningMetadataWhereInput>
+  AND?: Maybe<Array<UpcomingWorkingGroupOpeningWhereInput>>
+  OR?: Maybe<Array<UpcomingWorkingGroupOpeningWhereInput>>
+}
+
+export type UpcomingWorkingGroupOpeningWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type Worker = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** WorkerId in specific working group module */
+  runtimeId: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  membership: Membership
+  membershipId: Scalars['String']
+  /** Worker's role account */
+  roleAccount: Scalars['String']
+  /** Worker's reward account */
+  rewardAccount: Scalars['String']
+  /** Worker's staking account */
+  stakeAccount: Scalars['String']
+  /** Current worker status */
+  status: WorkerStatus
+  /** Whether the worker is also the working group lead */
+  isLead: Scalars['Boolean']
+  /** Current role stake (in JOY) */
+  stake: Scalars['BigInt']
+  /** Current reward per block */
+  rewardPerBlock: Scalars['BigInt']
+  /** The reward amount the worker is currently missing (due to empty working group budget) */
+  missingRewardAmount?: Maybe<Scalars['BigInt']>
+  payouts: Array<RewardPaidEvent>
+  slashes: Array<StakeSlashedEvent>
+  entry: OpeningFilledEvent
+  entryId: Scalars['String']
+  application: WorkingGroupApplication
+  applicationId: Scalars['String']
+  /** Worker's storage data */
+  storage?: Maybe<Scalars['String']>
+  leaderseteventworker?: Maybe<Array<LeaderSetEvent>>
+  leaderunseteventleader?: Maybe<Array<LeaderUnsetEvent>>
+  memberverificationstatusupdatedeventworker?: Maybe<Array<MemberVerificationStatusUpdatedEvent>>
+  newmissedrewardlevelreachedeventworker?: Maybe<Array<NewMissedRewardLevelReachedEvent>>
+  stakedecreasedeventworker?: Maybe<Array<StakeDecreasedEvent>>
+  stakeincreasedeventworker?: Maybe<Array<StakeIncreasedEvent>>
+  terminatedleadereventworker?: Maybe<Array<TerminatedLeaderEvent>>
+  terminatedworkereventworker?: Maybe<Array<TerminatedWorkerEvent>>
+  workerexitedeventworker?: Maybe<Array<WorkerExitedEvent>>
+  workerrewardaccountupdatedeventworker?: Maybe<Array<WorkerRewardAccountUpdatedEvent>>
+  workerrewardamountupdatedeventworker?: Maybe<Array<WorkerRewardAmountUpdatedEvent>>
+  workerroleaccountupdatedeventworker?: Maybe<Array<WorkerRoleAccountUpdatedEvent>>
+  workerstartedleavingeventworker?: Maybe<Array<WorkerStartedLeavingEvent>>
+  workinggroupleader?: Maybe<Array<WorkingGroup>>
+}
+
+export type WorkerConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<WorkerEdge>
+  pageInfo: PageInfo
+}
+
+export type WorkerCreateInput = {
+  runtimeId: Scalars['Float']
+  group: Scalars['ID']
+  membership: Scalars['ID']
+  roleAccount: Scalars['String']
+  rewardAccount: Scalars['String']
+  stakeAccount: Scalars['String']
+  status: Scalars['JSONObject']
+  isLead: Scalars['Boolean']
+  stake: Scalars['BigInt']
+  rewardPerBlock: Scalars['BigInt']
+  missingRewardAmount?: Maybe<Scalars['BigInt']>
+  entry: Scalars['ID']
+  application: Scalars['ID']
+  storage?: Maybe<Scalars['String']>
+}
+
+export type WorkerEdge = {
+  node: Worker
+  cursor: Scalars['String']
+}
+
+export type WorkerExitedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  worker: Worker
+  workerId: Scalars['String']
+}
+
+export type WorkerExitedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<WorkerExitedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type WorkerExitedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  worker: Scalars['ID']
+}
+
+export type WorkerExitedEventEdge = {
+  node: WorkerExitedEvent
+  cursor: Scalars['String']
+}
+
+export enum WorkerExitedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  WorkerAsc = 'worker_ASC',
+  WorkerDesc = 'worker_DESC',
+}
+
+export type WorkerExitedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  worker?: Maybe<Scalars['ID']>
+}
+
+export type WorkerExitedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  worker_eq?: Maybe<Scalars['ID']>
+  worker_in?: Maybe<Array<Scalars['ID']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  worker?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<WorkerExitedEventWhereInput>>
+  OR?: Maybe<Array<WorkerExitedEventWhereInput>>
+}
+
+export type WorkerExitedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export enum WorkerOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  RuntimeIdAsc = 'runtimeId_ASC',
+  RuntimeIdDesc = 'runtimeId_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  MembershipAsc = 'membership_ASC',
+  MembershipDesc = 'membership_DESC',
+  RoleAccountAsc = 'roleAccount_ASC',
+  RoleAccountDesc = 'roleAccount_DESC',
+  RewardAccountAsc = 'rewardAccount_ASC',
+  RewardAccountDesc = 'rewardAccount_DESC',
+  StakeAccountAsc = 'stakeAccount_ASC',
+  StakeAccountDesc = 'stakeAccount_DESC',
+  IsLeadAsc = 'isLead_ASC',
+  IsLeadDesc = 'isLead_DESC',
+  StakeAsc = 'stake_ASC',
+  StakeDesc = 'stake_DESC',
+  RewardPerBlockAsc = 'rewardPerBlock_ASC',
+  RewardPerBlockDesc = 'rewardPerBlock_DESC',
+  MissingRewardAmountAsc = 'missingRewardAmount_ASC',
+  MissingRewardAmountDesc = 'missingRewardAmount_DESC',
+  EntryAsc = 'entry_ASC',
+  EntryDesc = 'entry_DESC',
+  ApplicationAsc = 'application_ASC',
+  ApplicationDesc = 'application_DESC',
+  StorageAsc = 'storage_ASC',
+  StorageDesc = 'storage_DESC',
+}
+
+export type WorkerRewardAccountUpdatedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  worker: Worker
+  workerId: Scalars['String']
+  /** New reward account */
+  newRewardAccount: Scalars['String']
+}
+
+export type WorkerRewardAccountUpdatedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<WorkerRewardAccountUpdatedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type WorkerRewardAccountUpdatedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  worker: Scalars['ID']
+  newRewardAccount: Scalars['String']
+}
+
+export type WorkerRewardAccountUpdatedEventEdge = {
+  node: WorkerRewardAccountUpdatedEvent
+  cursor: Scalars['String']
+}
+
+export enum WorkerRewardAccountUpdatedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  WorkerAsc = 'worker_ASC',
+  WorkerDesc = 'worker_DESC',
+  NewRewardAccountAsc = 'newRewardAccount_ASC',
+  NewRewardAccountDesc = 'newRewardAccount_DESC',
+}
+
+export type WorkerRewardAccountUpdatedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  worker?: Maybe<Scalars['ID']>
+  newRewardAccount?: Maybe<Scalars['String']>
+}
+
+export type WorkerRewardAccountUpdatedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  worker_eq?: Maybe<Scalars['ID']>
+  worker_in?: Maybe<Array<Scalars['ID']>>
+  newRewardAccount_eq?: Maybe<Scalars['String']>
+  newRewardAccount_contains?: Maybe<Scalars['String']>
+  newRewardAccount_startsWith?: Maybe<Scalars['String']>
+  newRewardAccount_endsWith?: Maybe<Scalars['String']>
+  newRewardAccount_in?: Maybe<Array<Scalars['String']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  worker?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<WorkerRewardAccountUpdatedEventWhereInput>>
+  OR?: Maybe<Array<WorkerRewardAccountUpdatedEventWhereInput>>
+}
+
+export type WorkerRewardAccountUpdatedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type WorkerRewardAmountUpdatedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  worker: Worker
+  workerId: Scalars['String']
+  /** New worker reward per block */
+  newRewardPerBlock: Scalars['BigInt']
+}
+
+export type WorkerRewardAmountUpdatedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<WorkerRewardAmountUpdatedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type WorkerRewardAmountUpdatedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  worker: Scalars['ID']
+  newRewardPerBlock: Scalars['BigInt']
+}
+
+export type WorkerRewardAmountUpdatedEventEdge = {
+  node: WorkerRewardAmountUpdatedEvent
+  cursor: Scalars['String']
+}
+
+export enum WorkerRewardAmountUpdatedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  WorkerAsc = 'worker_ASC',
+  WorkerDesc = 'worker_DESC',
+  NewRewardPerBlockAsc = 'newRewardPerBlock_ASC',
+  NewRewardPerBlockDesc = 'newRewardPerBlock_DESC',
+}
+
+export type WorkerRewardAmountUpdatedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  worker?: Maybe<Scalars['ID']>
+  newRewardPerBlock?: Maybe<Scalars['BigInt']>
+}
+
+export type WorkerRewardAmountUpdatedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  worker_eq?: Maybe<Scalars['ID']>
+  worker_in?: Maybe<Array<Scalars['ID']>>
+  newRewardPerBlock_eq?: Maybe<Scalars['BigInt']>
+  newRewardPerBlock_gt?: Maybe<Scalars['BigInt']>
+  newRewardPerBlock_gte?: Maybe<Scalars['BigInt']>
+  newRewardPerBlock_lt?: Maybe<Scalars['BigInt']>
+  newRewardPerBlock_lte?: Maybe<Scalars['BigInt']>
+  newRewardPerBlock_in?: Maybe<Array<Scalars['BigInt']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  worker?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<WorkerRewardAmountUpdatedEventWhereInput>>
+  OR?: Maybe<Array<WorkerRewardAmountUpdatedEventWhereInput>>
+}
+
+export type WorkerRewardAmountUpdatedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type WorkerRoleAccountUpdatedEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  worker: Worker
+  workerId: Scalars['String']
+  /** New role account */
+  newRoleAccount: Scalars['String']
+}
+
+export type WorkerRoleAccountUpdatedEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<WorkerRoleAccountUpdatedEventEdge>
+  pageInfo: PageInfo
+}
+
+export type WorkerRoleAccountUpdatedEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  worker: Scalars['ID']
+  newRoleAccount: Scalars['String']
+}
+
+export type WorkerRoleAccountUpdatedEventEdge = {
+  node: WorkerRoleAccountUpdatedEvent
+  cursor: Scalars['String']
+}
+
+export enum WorkerRoleAccountUpdatedEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  WorkerAsc = 'worker_ASC',
+  WorkerDesc = 'worker_DESC',
+  NewRoleAccountAsc = 'newRoleAccount_ASC',
+  NewRoleAccountDesc = 'newRoleAccount_DESC',
+}
+
+export type WorkerRoleAccountUpdatedEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  worker?: Maybe<Scalars['ID']>
+  newRoleAccount?: Maybe<Scalars['String']>
+}
+
+export type WorkerRoleAccountUpdatedEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  worker_eq?: Maybe<Scalars['ID']>
+  worker_in?: Maybe<Array<Scalars['ID']>>
+  newRoleAccount_eq?: Maybe<Scalars['String']>
+  newRoleAccount_contains?: Maybe<Scalars['String']>
+  newRoleAccount_startsWith?: Maybe<Scalars['String']>
+  newRoleAccount_endsWith?: Maybe<Scalars['String']>
+  newRoleAccount_in?: Maybe<Array<Scalars['String']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  worker?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<WorkerRoleAccountUpdatedEventWhereInput>>
+  OR?: Maybe<Array<WorkerRoleAccountUpdatedEventWhereInput>>
+}
+
+export type WorkerRoleAccountUpdatedEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type WorkerStartedLeavingEvent = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Hash of the extrinsic which caused the event to be emitted */
+  inExtrinsic?: Maybe<Scalars['String']>
+  /** Blocknumber of the block in which the event was emitted. */
+  inBlock: Scalars['Int']
+  /** Network the block was produced in */
+  network: Network
+  /** Index of event in block from which it was emitted. */
+  indexInBlock: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  worker: Worker
+  workerId: Scalars['String']
+  /** Optional rationale */
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type WorkerStartedLeavingEventConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<WorkerStartedLeavingEventEdge>
+  pageInfo: PageInfo
+}
+
+export type WorkerStartedLeavingEventCreateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock: Scalars['Float']
+  network: Network
+  indexInBlock: Scalars['Float']
+  group: Scalars['ID']
+  worker: Scalars['ID']
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type WorkerStartedLeavingEventEdge = {
+  node: WorkerStartedLeavingEvent
+  cursor: Scalars['String']
+}
+
+export enum WorkerStartedLeavingEventOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  InExtrinsicAsc = 'inExtrinsic_ASC',
+  InExtrinsicDesc = 'inExtrinsic_DESC',
+  InBlockAsc = 'inBlock_ASC',
+  InBlockDesc = 'inBlock_DESC',
+  NetworkAsc = 'network_ASC',
+  NetworkDesc = 'network_DESC',
+  IndexInBlockAsc = 'indexInBlock_ASC',
+  IndexInBlockDesc = 'indexInBlock_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  WorkerAsc = 'worker_ASC',
+  WorkerDesc = 'worker_DESC',
+  RationaleAsc = 'rationale_ASC',
+  RationaleDesc = 'rationale_DESC',
+}
+
+export type WorkerStartedLeavingEventUpdateInput = {
+  inExtrinsic?: Maybe<Scalars['String']>
+  inBlock?: Maybe<Scalars['Float']>
+  network?: Maybe<Network>
+  indexInBlock?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  worker?: Maybe<Scalars['ID']>
+  rationale?: Maybe<Scalars['String']>
+}
+
+export type WorkerStartedLeavingEventWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  inExtrinsic_eq?: Maybe<Scalars['String']>
+  inExtrinsic_contains?: Maybe<Scalars['String']>
+  inExtrinsic_startsWith?: Maybe<Scalars['String']>
+  inExtrinsic_endsWith?: Maybe<Scalars['String']>
+  inExtrinsic_in?: Maybe<Array<Scalars['String']>>
+  inBlock_eq?: Maybe<Scalars['Int']>
+  inBlock_gt?: Maybe<Scalars['Int']>
+  inBlock_gte?: Maybe<Scalars['Int']>
+  inBlock_lt?: Maybe<Scalars['Int']>
+  inBlock_lte?: Maybe<Scalars['Int']>
+  inBlock_in?: Maybe<Array<Scalars['Int']>>
+  network_eq?: Maybe<Network>
+  network_in?: Maybe<Array<Network>>
+  indexInBlock_eq?: Maybe<Scalars['Int']>
+  indexInBlock_gt?: Maybe<Scalars['Int']>
+  indexInBlock_gte?: Maybe<Scalars['Int']>
+  indexInBlock_lt?: Maybe<Scalars['Int']>
+  indexInBlock_lte?: Maybe<Scalars['Int']>
+  indexInBlock_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  worker_eq?: Maybe<Scalars['ID']>
+  worker_in?: Maybe<Array<Scalars['ID']>>
+  rationale_eq?: Maybe<Scalars['String']>
+  rationale_contains?: Maybe<Scalars['String']>
+  rationale_startsWith?: Maybe<Scalars['String']>
+  rationale_endsWith?: Maybe<Scalars['String']>
+  rationale_in?: Maybe<Array<Scalars['String']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  worker?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<WorkerStartedLeavingEventWhereInput>>
+  OR?: Maybe<Array<WorkerStartedLeavingEventWhereInput>>
+}
+
+export type WorkerStartedLeavingEventWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type WorkerStatus = WorkerStatusActive | WorkerStatusLeft | WorkerStatusTerminated
+
+export type WorkerStatusActive = {
+  phantom?: Maybe<Scalars['Int']>
+}
+
+export type WorkerStatusActiveCreateInput = {
+  phantom?: Maybe<Scalars['Float']>
+}
+
+export type WorkerStatusActiveUpdateInput = {
+  phantom?: Maybe<Scalars['Float']>
+}
+
+export type WorkerStatusActiveWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  phantom_eq?: Maybe<Scalars['Int']>
+  phantom_gt?: Maybe<Scalars['Int']>
+  phantom_gte?: Maybe<Scalars['Int']>
+  phantom_lt?: Maybe<Scalars['Int']>
+  phantom_lte?: Maybe<Scalars['Int']>
+  phantom_in?: Maybe<Array<Scalars['Int']>>
+  AND?: Maybe<Array<WorkerStatusActiveWhereInput>>
+  OR?: Maybe<Array<WorkerStatusActiveWhereInput>>
+}
+
+export type WorkerStatusActiveWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type WorkerStatusLeft = {
+  /** Related event emitted on leaving initialization */
+  workerStartedLeavingEvent?: Maybe<WorkerStartedLeavingEvent>
+  /** Related event emitted (and set) when the unstaking period is finished */
+  workerExitedEvent?: Maybe<WorkerExitedEvent>
+}
+
+export type WorkerStatusTerminated = {
+  /** Related event emitted on worker termination */
+  terminatedWorkerEvent?: Maybe<TerminatedWorkerEvent>
+}
+
+export type WorkerUpdateInput = {
+  runtimeId?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  membership?: Maybe<Scalars['ID']>
+  roleAccount?: Maybe<Scalars['String']>
+  rewardAccount?: Maybe<Scalars['String']>
+  stakeAccount?: Maybe<Scalars['String']>
+  status?: Maybe<Scalars['JSONObject']>
+  isLead?: Maybe<Scalars['Boolean']>
+  stake?: Maybe<Scalars['BigInt']>
+  rewardPerBlock?: Maybe<Scalars['BigInt']>
+  missingRewardAmount?: Maybe<Scalars['BigInt']>
+  entry?: Maybe<Scalars['ID']>
+  application?: Maybe<Scalars['ID']>
+  storage?: Maybe<Scalars['String']>
+}
+
+export type WorkerWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  runtimeId_eq?: Maybe<Scalars['Int']>
+  runtimeId_gt?: Maybe<Scalars['Int']>
+  runtimeId_gte?: Maybe<Scalars['Int']>
+  runtimeId_lt?: Maybe<Scalars['Int']>
+  runtimeId_lte?: Maybe<Scalars['Int']>
+  runtimeId_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  membership_eq?: Maybe<Scalars['ID']>
+  membership_in?: Maybe<Array<Scalars['ID']>>
+  roleAccount_eq?: Maybe<Scalars['String']>
+  roleAccount_contains?: Maybe<Scalars['String']>
+  roleAccount_startsWith?: Maybe<Scalars['String']>
+  roleAccount_endsWith?: Maybe<Scalars['String']>
+  roleAccount_in?: Maybe<Array<Scalars['String']>>
+  rewardAccount_eq?: Maybe<Scalars['String']>
+  rewardAccount_contains?: Maybe<Scalars['String']>
+  rewardAccount_startsWith?: Maybe<Scalars['String']>
+  rewardAccount_endsWith?: Maybe<Scalars['String']>
+  rewardAccount_in?: Maybe<Array<Scalars['String']>>
+  stakeAccount_eq?: Maybe<Scalars['String']>
+  stakeAccount_contains?: Maybe<Scalars['String']>
+  stakeAccount_startsWith?: Maybe<Scalars['String']>
+  stakeAccount_endsWith?: Maybe<Scalars['String']>
+  stakeAccount_in?: Maybe<Array<Scalars['String']>>
+  status_json?: Maybe<Scalars['JSONObject']>
+  isLead_eq?: Maybe<Scalars['Boolean']>
+  isLead_in?: Maybe<Array<Scalars['Boolean']>>
+  stake_eq?: Maybe<Scalars['BigInt']>
+  stake_gt?: Maybe<Scalars['BigInt']>
+  stake_gte?: Maybe<Scalars['BigInt']>
+  stake_lt?: Maybe<Scalars['BigInt']>
+  stake_lte?: Maybe<Scalars['BigInt']>
+  stake_in?: Maybe<Array<Scalars['BigInt']>>
+  rewardPerBlock_eq?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_gt?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_gte?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_lt?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_lte?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_in?: Maybe<Array<Scalars['BigInt']>>
+  missingRewardAmount_eq?: Maybe<Scalars['BigInt']>
+  missingRewardAmount_gt?: Maybe<Scalars['BigInt']>
+  missingRewardAmount_gte?: Maybe<Scalars['BigInt']>
+  missingRewardAmount_lt?: Maybe<Scalars['BigInt']>
+  missingRewardAmount_lte?: Maybe<Scalars['BigInt']>
+  missingRewardAmount_in?: Maybe<Array<Scalars['BigInt']>>
+  entry_eq?: Maybe<Scalars['ID']>
+  entry_in?: Maybe<Array<Scalars['ID']>>
+  application_eq?: Maybe<Scalars['ID']>
+  application_in?: Maybe<Array<Scalars['ID']>>
+  storage_eq?: Maybe<Scalars['String']>
+  storage_contains?: Maybe<Scalars['String']>
+  storage_startsWith?: Maybe<Scalars['String']>
+  storage_endsWith?: Maybe<Scalars['String']>
+  storage_in?: Maybe<Array<Scalars['String']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  membership?: Maybe<MembershipWhereInput>
+  payouts_none?: Maybe<RewardPaidEventWhereInput>
+  payouts_some?: Maybe<RewardPaidEventWhereInput>
+  payouts_every?: Maybe<RewardPaidEventWhereInput>
+  slashes_none?: Maybe<StakeSlashedEventWhereInput>
+  slashes_some?: Maybe<StakeSlashedEventWhereInput>
+  slashes_every?: Maybe<StakeSlashedEventWhereInput>
+  entry?: Maybe<OpeningFilledEventWhereInput>
+  application?: Maybe<WorkingGroupApplicationWhereInput>
+  leaderseteventworker_none?: Maybe<LeaderSetEventWhereInput>
+  leaderseteventworker_some?: Maybe<LeaderSetEventWhereInput>
+  leaderseteventworker_every?: Maybe<LeaderSetEventWhereInput>
+  leaderunseteventleader_none?: Maybe<LeaderUnsetEventWhereInput>
+  leaderunseteventleader_some?: Maybe<LeaderUnsetEventWhereInput>
+  leaderunseteventleader_every?: Maybe<LeaderUnsetEventWhereInput>
+  memberverificationstatusupdatedeventworker_none?: Maybe<MemberVerificationStatusUpdatedEventWhereInput>
+  memberverificationstatusupdatedeventworker_some?: Maybe<MemberVerificationStatusUpdatedEventWhereInput>
+  memberverificationstatusupdatedeventworker_every?: Maybe<MemberVerificationStatusUpdatedEventWhereInput>
+  newmissedrewardlevelreachedeventworker_none?: Maybe<NewMissedRewardLevelReachedEventWhereInput>
+  newmissedrewardlevelreachedeventworker_some?: Maybe<NewMissedRewardLevelReachedEventWhereInput>
+  newmissedrewardlevelreachedeventworker_every?: Maybe<NewMissedRewardLevelReachedEventWhereInput>
+  stakedecreasedeventworker_none?: Maybe<StakeDecreasedEventWhereInput>
+  stakedecreasedeventworker_some?: Maybe<StakeDecreasedEventWhereInput>
+  stakedecreasedeventworker_every?: Maybe<StakeDecreasedEventWhereInput>
+  stakeincreasedeventworker_none?: Maybe<StakeIncreasedEventWhereInput>
+  stakeincreasedeventworker_some?: Maybe<StakeIncreasedEventWhereInput>
+  stakeincreasedeventworker_every?: Maybe<StakeIncreasedEventWhereInput>
+  terminatedleadereventworker_none?: Maybe<TerminatedLeaderEventWhereInput>
+  terminatedleadereventworker_some?: Maybe<TerminatedLeaderEventWhereInput>
+  terminatedleadereventworker_every?: Maybe<TerminatedLeaderEventWhereInput>
+  terminatedworkereventworker_none?: Maybe<TerminatedWorkerEventWhereInput>
+  terminatedworkereventworker_some?: Maybe<TerminatedWorkerEventWhereInput>
+  terminatedworkereventworker_every?: Maybe<TerminatedWorkerEventWhereInput>
+  workerexitedeventworker_none?: Maybe<WorkerExitedEventWhereInput>
+  workerexitedeventworker_some?: Maybe<WorkerExitedEventWhereInput>
+  workerexitedeventworker_every?: Maybe<WorkerExitedEventWhereInput>
+  workerrewardaccountupdatedeventworker_none?: Maybe<WorkerRewardAccountUpdatedEventWhereInput>
+  workerrewardaccountupdatedeventworker_some?: Maybe<WorkerRewardAccountUpdatedEventWhereInput>
+  workerrewardaccountupdatedeventworker_every?: Maybe<WorkerRewardAccountUpdatedEventWhereInput>
+  workerrewardamountupdatedeventworker_none?: Maybe<WorkerRewardAmountUpdatedEventWhereInput>
+  workerrewardamountupdatedeventworker_some?: Maybe<WorkerRewardAmountUpdatedEventWhereInput>
+  workerrewardamountupdatedeventworker_every?: Maybe<WorkerRewardAmountUpdatedEventWhereInput>
+  workerroleaccountupdatedeventworker_none?: Maybe<WorkerRoleAccountUpdatedEventWhereInput>
+  workerroleaccountupdatedeventworker_some?: Maybe<WorkerRoleAccountUpdatedEventWhereInput>
+  workerroleaccountupdatedeventworker_every?: Maybe<WorkerRoleAccountUpdatedEventWhereInput>
+  workerstartedleavingeventworker_none?: Maybe<WorkerStartedLeavingEventWhereInput>
+  workerstartedleavingeventworker_some?: Maybe<WorkerStartedLeavingEventWhereInput>
+  workerstartedleavingeventworker_every?: Maybe<WorkerStartedLeavingEventWhereInput>
+  workinggroupleader_none?: Maybe<WorkingGroupWhereInput>
+  workinggroupleader_some?: Maybe<WorkingGroupWhereInput>
+  workinggroupleader_every?: Maybe<WorkingGroupWhereInput>
+  AND?: Maybe<Array<WorkerWhereInput>>
+  OR?: Maybe<Array<WorkerWhereInput>>
+}
+
+export type WorkerWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type WorkingGroup = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Working group name */
+  name: Scalars['String']
+  metadata?: Maybe<WorkingGroupMetadata>
+  metadataId?: Maybe<Scalars['String']>
+  leader?: Maybe<Worker>
+  leaderId?: Maybe<Scalars['String']>
+  workers: Array<Worker>
+  openings: Array<WorkingGroupOpening>
+  /** Current working group budget (JOY) */
+  budget: Scalars['BigInt']
+  applicationwithdrawneventgroup?: Maybe<Array<ApplicationWithdrawnEvent>>
+  appliedonopeningeventgroup?: Maybe<Array<AppliedOnOpeningEvent>>
+  budgetseteventgroup?: Maybe<Array<BudgetSetEvent>>
+  budgetspendingeventgroup?: Maybe<Array<BudgetSpendingEvent>>
+  leaderseteventgroup?: Maybe<Array<LeaderSetEvent>>
+  leaderunseteventgroup?: Maybe<Array<LeaderUnsetEvent>>
+  newmissedrewardlevelreachedeventgroup?: Maybe<Array<NewMissedRewardLevelReachedEvent>>
+  openingaddedeventgroup?: Maybe<Array<OpeningAddedEvent>>
+  openingcanceledeventgroup?: Maybe<Array<OpeningCanceledEvent>>
+  openingfilledeventgroup?: Maybe<Array<OpeningFilledEvent>>
+  rewardpaideventgroup?: Maybe<Array<RewardPaidEvent>>
+  stakedecreasedeventgroup?: Maybe<Array<StakeDecreasedEvent>>
+  stakeincreasedeventgroup?: Maybe<Array<StakeIncreasedEvent>>
+  stakeslashedeventgroup?: Maybe<Array<StakeSlashedEvent>>
+  statustextchangedeventgroup?: Maybe<Array<StatusTextChangedEvent>>
+  terminatedleadereventgroup?: Maybe<Array<TerminatedLeaderEvent>>
+  terminatedworkereventgroup?: Maybe<Array<TerminatedWorkerEvent>>
+  upcomingworkinggroupopeninggroup?: Maybe<Array<UpcomingWorkingGroupOpening>>
+  workerexitedeventgroup?: Maybe<Array<WorkerExitedEvent>>
+  workerrewardaccountupdatedeventgroup?: Maybe<Array<WorkerRewardAccountUpdatedEvent>>
+  workerrewardamountupdatedeventgroup?: Maybe<Array<WorkerRewardAmountUpdatedEvent>>
+  workerroleaccountupdatedeventgroup?: Maybe<Array<WorkerRoleAccountUpdatedEvent>>
+  workerstartedleavingeventgroup?: Maybe<Array<WorkerStartedLeavingEvent>>
+  workinggroupmetadatagroup?: Maybe<Array<WorkingGroupMetadata>>
+}
+
+export type WorkingGroupApplication = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** ApplicationId in specific working group module */
+  runtimeId: Scalars['Int']
+  opening: WorkingGroupOpening
+  openingId: Scalars['String']
+  applicant: Membership
+  applicantId: Scalars['String']
+  /** Application stake */
+  stake: Scalars['BigInt']
+  /** Applicant's initial role account */
+  roleAccount: Scalars['String']
+  /** Applicant's initial reward account */
+  rewardAccount: Scalars['String']
+  /** Applicant's initial staking account */
+  stakingAccount: Scalars['String']
+  answers: Array<ApplicationFormQuestionAnswer>
+  /** Current application status */
+  status: WorkingGroupApplicationStatus
+  createdInEvent: AppliedOnOpeningEvent
+  applicationwithdrawneventapplication?: Maybe<Array<ApplicationWithdrawnEvent>>
+  workerapplication?: Maybe<Array<Worker>>
+}
+
+export type WorkingGroupApplicationConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<WorkingGroupApplicationEdge>
+  pageInfo: PageInfo
+}
+
+export type WorkingGroupApplicationCreateInput = {
+  runtimeId: Scalars['Float']
+  opening: Scalars['ID']
+  applicant: Scalars['ID']
+  stake: Scalars['BigInt']
+  roleAccount: Scalars['String']
+  rewardAccount: Scalars['String']
+  stakingAccount: Scalars['String']
+  status: Scalars['JSONObject']
+}
+
+export type WorkingGroupApplicationEdge = {
+  node: WorkingGroupApplication
+  cursor: Scalars['String']
+}
+
+export enum WorkingGroupApplicationOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  RuntimeIdAsc = 'runtimeId_ASC',
+  RuntimeIdDesc = 'runtimeId_DESC',
+  OpeningAsc = 'opening_ASC',
+  OpeningDesc = 'opening_DESC',
+  ApplicantAsc = 'applicant_ASC',
+  ApplicantDesc = 'applicant_DESC',
+  StakeAsc = 'stake_ASC',
+  StakeDesc = 'stake_DESC',
+  RoleAccountAsc = 'roleAccount_ASC',
+  RoleAccountDesc = 'roleAccount_DESC',
+  RewardAccountAsc = 'rewardAccount_ASC',
+  RewardAccountDesc = 'rewardAccount_DESC',
+  StakingAccountAsc = 'stakingAccount_ASC',
+  StakingAccountDesc = 'stakingAccount_DESC',
+}
+
+export type WorkingGroupApplicationStatus =
+  | ApplicationStatusPending
+  | ApplicationStatusAccepted
+  | ApplicationStatusRejected
+  | ApplicationStatusWithdrawn
+  | ApplicationStatusCancelled
+
+export type WorkingGroupApplicationUpdateInput = {
+  runtimeId?: Maybe<Scalars['Float']>
+  opening?: Maybe<Scalars['ID']>
+  applicant?: Maybe<Scalars['ID']>
+  stake?: Maybe<Scalars['BigInt']>
+  roleAccount?: Maybe<Scalars['String']>
+  rewardAccount?: Maybe<Scalars['String']>
+  stakingAccount?: Maybe<Scalars['String']>
+  status?: Maybe<Scalars['JSONObject']>
+}
+
+export type WorkingGroupApplicationWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  runtimeId_eq?: Maybe<Scalars['Int']>
+  runtimeId_gt?: Maybe<Scalars['Int']>
+  runtimeId_gte?: Maybe<Scalars['Int']>
+  runtimeId_lt?: Maybe<Scalars['Int']>
+  runtimeId_lte?: Maybe<Scalars['Int']>
+  runtimeId_in?: Maybe<Array<Scalars['Int']>>
+  opening_eq?: Maybe<Scalars['ID']>
+  opening_in?: Maybe<Array<Scalars['ID']>>
+  applicant_eq?: Maybe<Scalars['ID']>
+  applicant_in?: Maybe<Array<Scalars['ID']>>
+  stake_eq?: Maybe<Scalars['BigInt']>
+  stake_gt?: Maybe<Scalars['BigInt']>
+  stake_gte?: Maybe<Scalars['BigInt']>
+  stake_lt?: Maybe<Scalars['BigInt']>
+  stake_lte?: Maybe<Scalars['BigInt']>
+  stake_in?: Maybe<Array<Scalars['BigInt']>>
+  roleAccount_eq?: Maybe<Scalars['String']>
+  roleAccount_contains?: Maybe<Scalars['String']>
+  roleAccount_startsWith?: Maybe<Scalars['String']>
+  roleAccount_endsWith?: Maybe<Scalars['String']>
+  roleAccount_in?: Maybe<Array<Scalars['String']>>
+  rewardAccount_eq?: Maybe<Scalars['String']>
+  rewardAccount_contains?: Maybe<Scalars['String']>
+  rewardAccount_startsWith?: Maybe<Scalars['String']>
+  rewardAccount_endsWith?: Maybe<Scalars['String']>
+  rewardAccount_in?: Maybe<Array<Scalars['String']>>
+  stakingAccount_eq?: Maybe<Scalars['String']>
+  stakingAccount_contains?: Maybe<Scalars['String']>
+  stakingAccount_startsWith?: Maybe<Scalars['String']>
+  stakingAccount_endsWith?: Maybe<Scalars['String']>
+  stakingAccount_in?: Maybe<Array<Scalars['String']>>
+  status_json?: Maybe<Scalars['JSONObject']>
+  opening?: Maybe<WorkingGroupOpeningWhereInput>
+  applicant?: Maybe<MembershipWhereInput>
+  answers_none?: Maybe<ApplicationFormQuestionAnswerWhereInput>
+  answers_some?: Maybe<ApplicationFormQuestionAnswerWhereInput>
+  answers_every?: Maybe<ApplicationFormQuestionAnswerWhereInput>
+  createdInEvent?: Maybe<AppliedOnOpeningEventWhereInput>
+  applicationwithdrawneventapplication_none?: Maybe<ApplicationWithdrawnEventWhereInput>
+  applicationwithdrawneventapplication_some?: Maybe<ApplicationWithdrawnEventWhereInput>
+  applicationwithdrawneventapplication_every?: Maybe<ApplicationWithdrawnEventWhereInput>
+  workerapplication_none?: Maybe<WorkerWhereInput>
+  workerapplication_some?: Maybe<WorkerWhereInput>
+  workerapplication_every?: Maybe<WorkerWhereInput>
+  AND?: Maybe<Array<WorkingGroupApplicationWhereInput>>
+  OR?: Maybe<Array<WorkingGroupApplicationWhereInput>>
+}
+
+export type WorkingGroupApplicationWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type WorkingGroupConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<WorkingGroupEdge>
+  pageInfo: PageInfo
+}
+
+export type WorkingGroupCreateInput = {
+  name: Scalars['String']
+  metadata?: Maybe<Scalars['ID']>
+  leader?: Maybe<Scalars['ID']>
+  budget: Scalars['BigInt']
+}
+
+export type WorkingGroupEdge = {
+  node: WorkingGroup
+  cursor: Scalars['String']
+}
+
+export type WorkingGroupMetadata = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Working group status */
+  status?: Maybe<Scalars['String']>
+  /** Working group status message */
+  statusMessage?: Maybe<Scalars['String']>
+  /** Working group about text */
+  about?: Maybe<Scalars['String']>
+  /** Working group description text */
+  description?: Maybe<Scalars['String']>
+  setInEvent: StatusTextChangedEvent
+  setInEventId: Scalars['String']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  workinggroupmetadata?: Maybe<Array<WorkingGroup>>
+}
+
+export type WorkingGroupMetadataActionResult =
+  | UpcomingOpeningAdded
+  | UpcomingOpeningRemoved
+  | WorkingGroupMetadataSet
+  | InvalidActionMetadata
+
+export type WorkingGroupMetadataConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<WorkingGroupMetadataEdge>
+  pageInfo: PageInfo
+}
+
+export type WorkingGroupMetadataCreateInput = {
+  status?: Maybe<Scalars['String']>
+  statusMessage?: Maybe<Scalars['String']>
+  about?: Maybe<Scalars['String']>
+  description?: Maybe<Scalars['String']>
+  setInEvent: Scalars['ID']
+  group: Scalars['ID']
+}
+
+export type WorkingGroupMetadataEdge = {
+  node: WorkingGroupMetadata
+  cursor: Scalars['String']
+}
+
+export enum WorkingGroupMetadataOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  StatusAsc = 'status_ASC',
+  StatusDesc = 'status_DESC',
+  StatusMessageAsc = 'statusMessage_ASC',
+  StatusMessageDesc = 'statusMessage_DESC',
+  AboutAsc = 'about_ASC',
+  AboutDesc = 'about_DESC',
+  DescriptionAsc = 'description_ASC',
+  DescriptionDesc = 'description_DESC',
+  SetInEventAsc = 'setInEvent_ASC',
+  SetInEventDesc = 'setInEvent_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+}
+
+export type WorkingGroupMetadataSet = {
+  /** The new metadata snapshot resulting from the update */
+  metadata?: Maybe<WorkingGroupMetadata>
+}
+
+export type WorkingGroupMetadataUpdateInput = {
+  status?: Maybe<Scalars['String']>
+  statusMessage?: Maybe<Scalars['String']>
+  about?: Maybe<Scalars['String']>
+  description?: Maybe<Scalars['String']>
+  setInEvent?: Maybe<Scalars['ID']>
+  group?: Maybe<Scalars['ID']>
+}
+
+export type WorkingGroupMetadataWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  status_eq?: Maybe<Scalars['String']>
+  status_contains?: Maybe<Scalars['String']>
+  status_startsWith?: Maybe<Scalars['String']>
+  status_endsWith?: Maybe<Scalars['String']>
+  status_in?: Maybe<Array<Scalars['String']>>
+  statusMessage_eq?: Maybe<Scalars['String']>
+  statusMessage_contains?: Maybe<Scalars['String']>
+  statusMessage_startsWith?: Maybe<Scalars['String']>
+  statusMessage_endsWith?: Maybe<Scalars['String']>
+  statusMessage_in?: Maybe<Array<Scalars['String']>>
+  about_eq?: Maybe<Scalars['String']>
+  about_contains?: Maybe<Scalars['String']>
+  about_startsWith?: Maybe<Scalars['String']>
+  about_endsWith?: Maybe<Scalars['String']>
+  about_in?: Maybe<Array<Scalars['String']>>
+  description_eq?: Maybe<Scalars['String']>
+  description_contains?: Maybe<Scalars['String']>
+  description_startsWith?: Maybe<Scalars['String']>
+  description_endsWith?: Maybe<Scalars['String']>
+  description_in?: Maybe<Array<Scalars['String']>>
+  setInEvent_eq?: Maybe<Scalars['ID']>
+  setInEvent_in?: Maybe<Array<Scalars['ID']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  setInEvent?: Maybe<StatusTextChangedEventWhereInput>
+  group?: Maybe<WorkingGroupWhereInput>
+  workinggroupmetadata_none?: Maybe<WorkingGroupWhereInput>
+  workinggroupmetadata_some?: Maybe<WorkingGroupWhereInput>
+  workinggroupmetadata_every?: Maybe<WorkingGroupWhereInput>
+  AND?: Maybe<Array<WorkingGroupMetadataWhereInput>>
+  OR?: Maybe<Array<WorkingGroupMetadataWhereInput>>
+}
+
+export type WorkingGroupMetadataWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export type WorkingGroupOpening = BaseGraphQlObject & {
+  id: Scalars['ID']
+  /** Time of opening creation */
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** OpeningId in specific working group module */
+  runtimeId: Scalars['Int']
+  group: WorkingGroup
+  groupId: Scalars['String']
+  applications: Array<WorkingGroupApplication>
+  /** Type of the opening (Leader/Regular) */
+  type: WorkingGroupOpeningType
+  /** Current opening status */
+  status: WorkingGroupOpeningStatus
+  metadata: WorkingGroupOpeningMetadata
+  metadataId: Scalars['String']
+  /** Min. application/role stake amount */
+  stakeAmount: Scalars['BigInt']
+  /** Role stake unstaking period in blocks */
+  unstakingPeriod: Scalars['Int']
+  /** Initial workers' reward per block */
+  rewardPerBlock: Scalars['BigInt']
+  createdInEvent: OpeningAddedEvent
+  appliedonopeningeventopening?: Maybe<Array<AppliedOnOpeningEvent>>
+  openingcanceledeventopening?: Maybe<Array<OpeningCanceledEvent>>
+  openingfilledeventopening?: Maybe<Array<OpeningFilledEvent>>
+}
+
+export type WorkingGroupOpeningConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<WorkingGroupOpeningEdge>
+  pageInfo: PageInfo
+}
+
+export type WorkingGroupOpeningCreateInput = {
+  createdAt: Scalars['DateTime']
+  runtimeId: Scalars['Float']
+  group: Scalars['ID']
+  type: WorkingGroupOpeningType
+  status: Scalars['JSONObject']
+  metadata: Scalars['ID']
+  stakeAmount: Scalars['BigInt']
+  unstakingPeriod: Scalars['Float']
+  rewardPerBlock: Scalars['BigInt']
+}
+
+export type WorkingGroupOpeningEdge = {
+  node: WorkingGroupOpening
+  cursor: Scalars['String']
+}
+
+export type WorkingGroupOpeningMetadata = BaseGraphQlObject & {
+  id: Scalars['ID']
+  createdAt: Scalars['DateTime']
+  createdById: Scalars['String']
+  updatedAt?: Maybe<Scalars['DateTime']>
+  updatedById?: Maybe<Scalars['String']>
+  deletedAt?: Maybe<Scalars['DateTime']>
+  deletedById?: Maybe<Scalars['String']>
+  version: Scalars['Int']
+  /** Whether the originally provided metadata was valid */
+  originallyValid: Scalars['Boolean']
+  /** Opening short description */
+  shortDescription?: Maybe<Scalars['String']>
+  /** Opening description (md-formatted) */
+  description?: Maybe<Scalars['String']>
+  /** Expected max. number of applicants that will be hired */
+  hiringLimit?: Maybe<Scalars['Int']>
+  /** Expected time when the opening will close */
+  expectedEnding?: Maybe<Scalars['DateTime']>
+  /** Md-formatted text explaining the application process */
+  applicationDetails?: Maybe<Scalars['String']>
+  applicationFormQuestions: Array<ApplicationFormQuestion>
+  upcomingworkinggroupopeningmetadata?: Maybe<Array<UpcomingWorkingGroupOpening>>
+  workinggroupopeningmetadata?: Maybe<Array<WorkingGroupOpening>>
+}
+
+export type WorkingGroupOpeningMetadataConnection = {
+  totalCount: Scalars['Int']
+  edges: Array<WorkingGroupOpeningMetadataEdge>
+  pageInfo: PageInfo
+}
+
+export type WorkingGroupOpeningMetadataCreateInput = {
+  originallyValid: Scalars['Boolean']
+  shortDescription?: Maybe<Scalars['String']>
+  description?: Maybe<Scalars['String']>
+  hiringLimit?: Maybe<Scalars['Float']>
+  expectedEnding?: Maybe<Scalars['DateTime']>
+  applicationDetails?: Maybe<Scalars['String']>
+}
+
+export type WorkingGroupOpeningMetadataEdge = {
+  node: WorkingGroupOpeningMetadata
+  cursor: Scalars['String']
+}
+
+export enum WorkingGroupOpeningMetadataOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  OriginallyValidAsc = 'originallyValid_ASC',
+  OriginallyValidDesc = 'originallyValid_DESC',
+  ShortDescriptionAsc = 'shortDescription_ASC',
+  ShortDescriptionDesc = 'shortDescription_DESC',
+  DescriptionAsc = 'description_ASC',
+  DescriptionDesc = 'description_DESC',
+  HiringLimitAsc = 'hiringLimit_ASC',
+  HiringLimitDesc = 'hiringLimit_DESC',
+  ExpectedEndingAsc = 'expectedEnding_ASC',
+  ExpectedEndingDesc = 'expectedEnding_DESC',
+  ApplicationDetailsAsc = 'applicationDetails_ASC',
+  ApplicationDetailsDesc = 'applicationDetails_DESC',
+}
+
+export type WorkingGroupOpeningMetadataUpdateInput = {
+  originallyValid?: Maybe<Scalars['Boolean']>
+  shortDescription?: Maybe<Scalars['String']>
+  description?: Maybe<Scalars['String']>
+  hiringLimit?: Maybe<Scalars['Float']>
+  expectedEnding?: Maybe<Scalars['DateTime']>
+  applicationDetails?: Maybe<Scalars['String']>
+}
+
+export type WorkingGroupOpeningMetadataWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  originallyValid_eq?: Maybe<Scalars['Boolean']>
+  originallyValid_in?: Maybe<Array<Scalars['Boolean']>>
+  shortDescription_eq?: Maybe<Scalars['String']>
+  shortDescription_contains?: Maybe<Scalars['String']>
+  shortDescription_startsWith?: Maybe<Scalars['String']>
+  shortDescription_endsWith?: Maybe<Scalars['String']>
+  shortDescription_in?: Maybe<Array<Scalars['String']>>
+  description_eq?: Maybe<Scalars['String']>
+  description_contains?: Maybe<Scalars['String']>
+  description_startsWith?: Maybe<Scalars['String']>
+  description_endsWith?: Maybe<Scalars['String']>
+  description_in?: Maybe<Array<Scalars['String']>>
+  hiringLimit_eq?: Maybe<Scalars['Int']>
+  hiringLimit_gt?: Maybe<Scalars['Int']>
+  hiringLimit_gte?: Maybe<Scalars['Int']>
+  hiringLimit_lt?: Maybe<Scalars['Int']>
+  hiringLimit_lte?: Maybe<Scalars['Int']>
+  hiringLimit_in?: Maybe<Array<Scalars['Int']>>
+  expectedEnding_eq?: Maybe<Scalars['DateTime']>
+  expectedEnding_lt?: Maybe<Scalars['DateTime']>
+  expectedEnding_lte?: Maybe<Scalars['DateTime']>
+  expectedEnding_gt?: Maybe<Scalars['DateTime']>
+  expectedEnding_gte?: Maybe<Scalars['DateTime']>
+  applicationDetails_eq?: Maybe<Scalars['String']>
+  applicationDetails_contains?: Maybe<Scalars['String']>
+  applicationDetails_startsWith?: Maybe<Scalars['String']>
+  applicationDetails_endsWith?: Maybe<Scalars['String']>
+  applicationDetails_in?: Maybe<Array<Scalars['String']>>
+  applicationFormQuestions_none?: Maybe<ApplicationFormQuestionWhereInput>
+  applicationFormQuestions_some?: Maybe<ApplicationFormQuestionWhereInput>
+  applicationFormQuestions_every?: Maybe<ApplicationFormQuestionWhereInput>
+  upcomingworkinggroupopeningmetadata_none?: Maybe<UpcomingWorkingGroupOpeningWhereInput>
+  upcomingworkinggroupopeningmetadata_some?: Maybe<UpcomingWorkingGroupOpeningWhereInput>
+  upcomingworkinggroupopeningmetadata_every?: Maybe<UpcomingWorkingGroupOpeningWhereInput>
+  workinggroupopeningmetadata_none?: Maybe<WorkingGroupOpeningWhereInput>
+  workinggroupopeningmetadata_some?: Maybe<WorkingGroupOpeningWhereInput>
+  workinggroupopeningmetadata_every?: Maybe<WorkingGroupOpeningWhereInput>
+  AND?: Maybe<Array<WorkingGroupOpeningMetadataWhereInput>>
+  OR?: Maybe<Array<WorkingGroupOpeningMetadataWhereInput>>
+}
+
+export type WorkingGroupOpeningMetadataWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export enum WorkingGroupOpeningOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  RuntimeIdAsc = 'runtimeId_ASC',
+  RuntimeIdDesc = 'runtimeId_DESC',
+  GroupAsc = 'group_ASC',
+  GroupDesc = 'group_DESC',
+  TypeAsc = 'type_ASC',
+  TypeDesc = 'type_DESC',
+  MetadataAsc = 'metadata_ASC',
+  MetadataDesc = 'metadata_DESC',
+  StakeAmountAsc = 'stakeAmount_ASC',
+  StakeAmountDesc = 'stakeAmount_DESC',
+  UnstakingPeriodAsc = 'unstakingPeriod_ASC',
+  UnstakingPeriodDesc = 'unstakingPeriod_DESC',
+  RewardPerBlockAsc = 'rewardPerBlock_ASC',
+  RewardPerBlockDesc = 'rewardPerBlock_DESC',
+}
+
+export type WorkingGroupOpeningStatus = OpeningStatusOpen | OpeningStatusFilled | OpeningStatusCancelled
+
+export enum WorkingGroupOpeningType {
+  Regular = 'REGULAR',
+  Leader = 'LEADER',
+}
+
+export type WorkingGroupOpeningUpdateInput = {
+  createdAt?: Maybe<Scalars['DateTime']>
+  runtimeId?: Maybe<Scalars['Float']>
+  group?: Maybe<Scalars['ID']>
+  type?: Maybe<WorkingGroupOpeningType>
+  status?: Maybe<Scalars['JSONObject']>
+  metadata?: Maybe<Scalars['ID']>
+  stakeAmount?: Maybe<Scalars['BigInt']>
+  unstakingPeriod?: Maybe<Scalars['Float']>
+  rewardPerBlock?: Maybe<Scalars['BigInt']>
+}
+
+export type WorkingGroupOpeningWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  runtimeId_eq?: Maybe<Scalars['Int']>
+  runtimeId_gt?: Maybe<Scalars['Int']>
+  runtimeId_gte?: Maybe<Scalars['Int']>
+  runtimeId_lt?: Maybe<Scalars['Int']>
+  runtimeId_lte?: Maybe<Scalars['Int']>
+  runtimeId_in?: Maybe<Array<Scalars['Int']>>
+  group_eq?: Maybe<Scalars['ID']>
+  group_in?: Maybe<Array<Scalars['ID']>>
+  type_eq?: Maybe<WorkingGroupOpeningType>
+  type_in?: Maybe<Array<WorkingGroupOpeningType>>
+  status_json?: Maybe<Scalars['JSONObject']>
+  metadata_eq?: Maybe<Scalars['ID']>
+  metadata_in?: Maybe<Array<Scalars['ID']>>
+  stakeAmount_eq?: Maybe<Scalars['BigInt']>
+  stakeAmount_gt?: Maybe<Scalars['BigInt']>
+  stakeAmount_gte?: Maybe<Scalars['BigInt']>
+  stakeAmount_lt?: Maybe<Scalars['BigInt']>
+  stakeAmount_lte?: Maybe<Scalars['BigInt']>
+  stakeAmount_in?: Maybe<Array<Scalars['BigInt']>>
+  unstakingPeriod_eq?: Maybe<Scalars['Int']>
+  unstakingPeriod_gt?: Maybe<Scalars['Int']>
+  unstakingPeriod_gte?: Maybe<Scalars['Int']>
+  unstakingPeriod_lt?: Maybe<Scalars['Int']>
+  unstakingPeriod_lte?: Maybe<Scalars['Int']>
+  unstakingPeriod_in?: Maybe<Array<Scalars['Int']>>
+  rewardPerBlock_eq?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_gt?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_gte?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_lt?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_lte?: Maybe<Scalars['BigInt']>
+  rewardPerBlock_in?: Maybe<Array<Scalars['BigInt']>>
+  group?: Maybe<WorkingGroupWhereInput>
+  applications_none?: Maybe<WorkingGroupApplicationWhereInput>
+  applications_some?: Maybe<WorkingGroupApplicationWhereInput>
+  applications_every?: Maybe<WorkingGroupApplicationWhereInput>
+  metadata?: Maybe<WorkingGroupOpeningMetadataWhereInput>
+  createdInEvent?: Maybe<OpeningAddedEventWhereInput>
+  appliedonopeningeventopening_none?: Maybe<AppliedOnOpeningEventWhereInput>
+  appliedonopeningeventopening_some?: Maybe<AppliedOnOpeningEventWhereInput>
+  appliedonopeningeventopening_every?: Maybe<AppliedOnOpeningEventWhereInput>
+  openingcanceledeventopening_none?: Maybe<OpeningCanceledEventWhereInput>
+  openingcanceledeventopening_some?: Maybe<OpeningCanceledEventWhereInput>
+  openingcanceledeventopening_every?: Maybe<OpeningCanceledEventWhereInput>
+  openingfilledeventopening_none?: Maybe<OpeningFilledEventWhereInput>
+  openingfilledeventopening_some?: Maybe<OpeningFilledEventWhereInput>
+  openingfilledeventopening_every?: Maybe<OpeningFilledEventWhereInput>
+  AND?: Maybe<Array<WorkingGroupOpeningWhereInput>>
+  OR?: Maybe<Array<WorkingGroupOpeningWhereInput>>
+}
+
+export type WorkingGroupOpeningWhereUniqueInput = {
+  id: Scalars['ID']
+}
+
+export enum WorkingGroupOrderByInput {
+  CreatedAtAsc = 'createdAt_ASC',
+  CreatedAtDesc = 'createdAt_DESC',
+  UpdatedAtAsc = 'updatedAt_ASC',
+  UpdatedAtDesc = 'updatedAt_DESC',
+  DeletedAtAsc = 'deletedAt_ASC',
+  DeletedAtDesc = 'deletedAt_DESC',
+  NameAsc = 'name_ASC',
+  NameDesc = 'name_DESC',
+  MetadataAsc = 'metadata_ASC',
+  MetadataDesc = 'metadata_DESC',
+  LeaderAsc = 'leader_ASC',
+  LeaderDesc = 'leader_DESC',
+  BudgetAsc = 'budget_ASC',
+  BudgetDesc = 'budget_DESC',
+}
+
+export type WorkingGroupUpdateInput = {
+  name?: Maybe<Scalars['String']>
+  metadata?: Maybe<Scalars['ID']>
+  leader?: Maybe<Scalars['ID']>
+  budget?: Maybe<Scalars['BigInt']>
+}
+
+export type WorkingGroupWhereInput = {
+  id_eq?: Maybe<Scalars['ID']>
+  id_in?: Maybe<Array<Scalars['ID']>>
+  createdAt_eq?: Maybe<Scalars['DateTime']>
+  createdAt_lt?: Maybe<Scalars['DateTime']>
+  createdAt_lte?: Maybe<Scalars['DateTime']>
+  createdAt_gt?: Maybe<Scalars['DateTime']>
+  createdAt_gte?: Maybe<Scalars['DateTime']>
+  createdById_eq?: Maybe<Scalars['ID']>
+  createdById_in?: Maybe<Array<Scalars['ID']>>
+  updatedAt_eq?: Maybe<Scalars['DateTime']>
+  updatedAt_lt?: Maybe<Scalars['DateTime']>
+  updatedAt_lte?: Maybe<Scalars['DateTime']>
+  updatedAt_gt?: Maybe<Scalars['DateTime']>
+  updatedAt_gte?: Maybe<Scalars['DateTime']>
+  updatedById_eq?: Maybe<Scalars['ID']>
+  updatedById_in?: Maybe<Array<Scalars['ID']>>
+  deletedAt_all?: Maybe<Scalars['Boolean']>
+  deletedAt_eq?: Maybe<Scalars['DateTime']>
+  deletedAt_lt?: Maybe<Scalars['DateTime']>
+  deletedAt_lte?: Maybe<Scalars['DateTime']>
+  deletedAt_gt?: Maybe<Scalars['DateTime']>
+  deletedAt_gte?: Maybe<Scalars['DateTime']>
+  deletedById_eq?: Maybe<Scalars['ID']>
+  deletedById_in?: Maybe<Array<Scalars['ID']>>
+  name_eq?: Maybe<Scalars['String']>
+  name_contains?: Maybe<Scalars['String']>
+  name_startsWith?: Maybe<Scalars['String']>
+  name_endsWith?: Maybe<Scalars['String']>
+  name_in?: Maybe<Array<Scalars['String']>>
+  metadata_eq?: Maybe<Scalars['ID']>
+  metadata_in?: Maybe<Array<Scalars['ID']>>
+  leader_eq?: Maybe<Scalars['ID']>
+  leader_in?: Maybe<Array<Scalars['ID']>>
+  budget_eq?: Maybe<Scalars['BigInt']>
+  budget_gt?: Maybe<Scalars['BigInt']>
+  budget_gte?: Maybe<Scalars['BigInt']>
+  budget_lt?: Maybe<Scalars['BigInt']>
+  budget_lte?: Maybe<Scalars['BigInt']>
+  budget_in?: Maybe<Array<Scalars['BigInt']>>
+  metadata?: Maybe<WorkingGroupMetadataWhereInput>
+  leader?: Maybe<WorkerWhereInput>
+  workers_none?: Maybe<WorkerWhereInput>
+  workers_some?: Maybe<WorkerWhereInput>
+  workers_every?: Maybe<WorkerWhereInput>
+  openings_none?: Maybe<WorkingGroupOpeningWhereInput>
+  openings_some?: Maybe<WorkingGroupOpeningWhereInput>
+  openings_every?: Maybe<WorkingGroupOpeningWhereInput>
+  applicationwithdrawneventgroup_none?: Maybe<ApplicationWithdrawnEventWhereInput>
+  applicationwithdrawneventgroup_some?: Maybe<ApplicationWithdrawnEventWhereInput>
+  applicationwithdrawneventgroup_every?: Maybe<ApplicationWithdrawnEventWhereInput>
+  appliedonopeningeventgroup_none?: Maybe<AppliedOnOpeningEventWhereInput>
+  appliedonopeningeventgroup_some?: Maybe<AppliedOnOpeningEventWhereInput>
+  appliedonopeningeventgroup_every?: Maybe<AppliedOnOpeningEventWhereInput>
+  budgetseteventgroup_none?: Maybe<BudgetSetEventWhereInput>
+  budgetseteventgroup_some?: Maybe<BudgetSetEventWhereInput>
+  budgetseteventgroup_every?: Maybe<BudgetSetEventWhereInput>
+  budgetspendingeventgroup_none?: Maybe<BudgetSpendingEventWhereInput>
+  budgetspendingeventgroup_some?: Maybe<BudgetSpendingEventWhereInput>
+  budgetspendingeventgroup_every?: Maybe<BudgetSpendingEventWhereInput>
+  leaderseteventgroup_none?: Maybe<LeaderSetEventWhereInput>
+  leaderseteventgroup_some?: Maybe<LeaderSetEventWhereInput>
+  leaderseteventgroup_every?: Maybe<LeaderSetEventWhereInput>
+  leaderunseteventgroup_none?: Maybe<LeaderUnsetEventWhereInput>
+  leaderunseteventgroup_some?: Maybe<LeaderUnsetEventWhereInput>
+  leaderunseteventgroup_every?: Maybe<LeaderUnsetEventWhereInput>
+  newmissedrewardlevelreachedeventgroup_none?: Maybe<NewMissedRewardLevelReachedEventWhereInput>
+  newmissedrewardlevelreachedeventgroup_some?: Maybe<NewMissedRewardLevelReachedEventWhereInput>
+  newmissedrewardlevelreachedeventgroup_every?: Maybe<NewMissedRewardLevelReachedEventWhereInput>
+  openingaddedeventgroup_none?: Maybe<OpeningAddedEventWhereInput>
+  openingaddedeventgroup_some?: Maybe<OpeningAddedEventWhereInput>
+  openingaddedeventgroup_every?: Maybe<OpeningAddedEventWhereInput>
+  openingcanceledeventgroup_none?: Maybe<OpeningCanceledEventWhereInput>
+  openingcanceledeventgroup_some?: Maybe<OpeningCanceledEventWhereInput>
+  openingcanceledeventgroup_every?: Maybe<OpeningCanceledEventWhereInput>
+  openingfilledeventgroup_none?: Maybe<OpeningFilledEventWhereInput>
+  openingfilledeventgroup_some?: Maybe<OpeningFilledEventWhereInput>
+  openingfilledeventgroup_every?: Maybe<OpeningFilledEventWhereInput>
+  rewardpaideventgroup_none?: Maybe<RewardPaidEventWhereInput>
+  rewardpaideventgroup_some?: Maybe<RewardPaidEventWhereInput>
+  rewardpaideventgroup_every?: Maybe<RewardPaidEventWhereInput>
+  stakedecreasedeventgroup_none?: Maybe<StakeDecreasedEventWhereInput>
+  stakedecreasedeventgroup_some?: Maybe<StakeDecreasedEventWhereInput>
+  stakedecreasedeventgroup_every?: Maybe<StakeDecreasedEventWhereInput>
+  stakeincreasedeventgroup_none?: Maybe<StakeIncreasedEventWhereInput>
+  stakeincreasedeventgroup_some?: Maybe<StakeIncreasedEventWhereInput>
+  stakeincreasedeventgroup_every?: Maybe<StakeIncreasedEventWhereInput>
+  stakeslashedeventgroup_none?: Maybe<StakeSlashedEventWhereInput>
+  stakeslashedeventgroup_some?: Maybe<StakeSlashedEventWhereInput>
+  stakeslashedeventgroup_every?: Maybe<StakeSlashedEventWhereInput>
+  statustextchangedeventgroup_none?: Maybe<StatusTextChangedEventWhereInput>
+  statustextchangedeventgroup_some?: Maybe<StatusTextChangedEventWhereInput>
+  statustextchangedeventgroup_every?: Maybe<StatusTextChangedEventWhereInput>
+  terminatedleadereventgroup_none?: Maybe<TerminatedLeaderEventWhereInput>
+  terminatedleadereventgroup_some?: Maybe<TerminatedLeaderEventWhereInput>
+  terminatedleadereventgroup_every?: Maybe<TerminatedLeaderEventWhereInput>
+  terminatedworkereventgroup_none?: Maybe<TerminatedWorkerEventWhereInput>
+  terminatedworkereventgroup_some?: Maybe<TerminatedWorkerEventWhereInput>
+  terminatedworkereventgroup_every?: Maybe<TerminatedWorkerEventWhereInput>
+  upcomingworkinggroupopeninggroup_none?: Maybe<UpcomingWorkingGroupOpeningWhereInput>
+  upcomingworkinggroupopeninggroup_some?: Maybe<UpcomingWorkingGroupOpeningWhereInput>
+  upcomingworkinggroupopeninggroup_every?: Maybe<UpcomingWorkingGroupOpeningWhereInput>
+  workerexitedeventgroup_none?: Maybe<WorkerExitedEventWhereInput>
+  workerexitedeventgroup_some?: Maybe<WorkerExitedEventWhereInput>
+  workerexitedeventgroup_every?: Maybe<WorkerExitedEventWhereInput>
+  workerrewardaccountupdatedeventgroup_none?: Maybe<WorkerRewardAccountUpdatedEventWhereInput>
+  workerrewardaccountupdatedeventgroup_some?: Maybe<WorkerRewardAccountUpdatedEventWhereInput>
+  workerrewardaccountupdatedeventgroup_every?: Maybe<WorkerRewardAccountUpdatedEventWhereInput>
+  workerrewardamountupdatedeventgroup_none?: Maybe<WorkerRewardAmountUpdatedEventWhereInput>
+  workerrewardamountupdatedeventgroup_some?: Maybe<WorkerRewardAmountUpdatedEventWhereInput>
+  workerrewardamountupdatedeventgroup_every?: Maybe<WorkerRewardAmountUpdatedEventWhereInput>
+  workerroleaccountupdatedeventgroup_none?: Maybe<WorkerRoleAccountUpdatedEventWhereInput>
+  workerroleaccountupdatedeventgroup_some?: Maybe<WorkerRoleAccountUpdatedEventWhereInput>
+  workerroleaccountupdatedeventgroup_every?: Maybe<WorkerRoleAccountUpdatedEventWhereInput>
+  workerstartedleavingeventgroup_none?: Maybe<WorkerStartedLeavingEventWhereInput>
+  workerstartedleavingeventgroup_some?: Maybe<WorkerStartedLeavingEventWhereInput>
+  workerstartedleavingeventgroup_every?: Maybe<WorkerStartedLeavingEventWhereInput>
+  workinggroupmetadatagroup_none?: Maybe<WorkingGroupMetadataWhereInput>
+  workinggroupmetadatagroup_some?: Maybe<WorkingGroupMetadataWhereInput>
+  workinggroupmetadatagroup_every?: Maybe<WorkingGroupMetadataWhereInput>
+  AND?: Maybe<Array<WorkingGroupWhereInput>>
+  OR?: Maybe<Array<WorkingGroupWhereInput>>
+}
+
+export type WorkingGroupWhereUniqueInput = {
+  id?: Maybe<Scalars['ID']>
+  name?: Maybe<Scalars['String']>
+}

+ 69 - 0
tests/integration-tests/src/graphql/queries/membership.graphql

@@ -0,0 +1,69 @@
+fragment MemberMetadataFields on MemberMetadata {
+  name
+  about
+}
+
+fragment MembershipFields on Membership {
+  id
+  handle
+  metadata {
+    ...MemberMetadataFields
+  }
+  controllerAccount
+  rootAccount
+  entry {
+    __typename
+    ... on MembershipEntryPaid {
+      membershipBoughtEvent {
+        id
+      }
+    }
+    ... on MembershipEntryInvited {
+      memberInvitedEvent {
+        id
+      }
+    }
+  }
+  isVerified
+  inviteCount
+  invitedBy {
+    id
+  }
+  invitees {
+    id
+  }
+  boundAccounts
+}
+
+query getMemberById($id: ID!) {
+  membershipByUniqueInput(where: { id: $id }) {
+    ...MembershipFields
+  }
+}
+
+query getMembersByIds($ids: [ID!]) {
+  memberships(where: { id_in: $ids }) {
+    ...MembershipFields
+  }
+}
+
+fragment MembershipSystemSnapshotFields on MembershipSystemSnapshot {
+  createdAt
+  snapshotBlock
+  referralCut
+  invitedInitialBalance
+  defaultInviteCount
+  membershipPrice
+}
+
+query getMembershipSystemSnapshotAt($time: DateTime!) {
+  membershipSystemSnapshots(where: { createdAt_eq: $time }, orderBy: createdAt_DESC, limit: 1) {
+    ...MembershipSystemSnapshotFields
+  }
+}
+
+query getMembershipSystemSnapshotBefore($time: DateTime!) {
+  membershipSystemSnapshots(where: { createdAt_lt: $time }, orderBy: createdAt_DESC, limit: 1) {
+    ...MembershipSystemSnapshotFields
+  }
+}

+ 240 - 0
tests/integration-tests/src/graphql/queries/membershipEvents.graphql

@@ -0,0 +1,240 @@
+# TODO: Always query events by eventId instead of memberid?
+
+fragment MembershipBoughtEventFields on MembershipBoughtEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  newMember {
+    id
+  }
+  rootAccount
+  controllerAccount
+  handle
+  metadata {
+    ...MemberMetadataFields
+  }
+  referrer {
+    id
+  }
+}
+query getMembershipBoughtEventsByEventIds($eventIds: [ID!]) {
+  membershipBoughtEvents(where: { id_in: $eventIds }) {
+    ...MembershipBoughtEventFields
+  }
+}
+
+fragment MemberProfileUpdatedEventFields on MemberProfileUpdatedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  member {
+    id
+  }
+  newHandle
+  newMetadata {
+    name
+    about
+  }
+}
+
+query getMemberProfileUpdatedEventsByMemberId($memberId: ID!) {
+  memberProfileUpdatedEvents(where: { member: { id_eq: $memberId } }) {
+    ...MemberProfileUpdatedEventFields
+  }
+}
+
+fragment MemberAccountsUpdatedEventFields on MemberAccountsUpdatedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  member {
+    id
+  }
+  newRootAccount
+  newControllerAccount
+}
+
+query getMemberAccountsUpdatedEventsByMemberId($memberId: ID!) {
+  memberAccountsUpdatedEvents(where: { member: { id_eq: $memberId } }) {
+    ...MemberAccountsUpdatedEventFields
+  }
+}
+
+fragment MemberInvitedEventFields on MemberInvitedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  invitingMember {
+    id
+  }
+  newMember {
+    id
+  }
+  rootAccount
+  controllerAccount
+  handle
+  metadata {
+    ...MemberMetadataFields
+  }
+}
+
+query getMemberInvitedEventsByEventIds($eventIds: [ID!]) {
+  memberInvitedEvents(where: { id_in: $eventIds }) {
+    ...MemberInvitedEventFields
+  }
+}
+
+fragment InvitesTransferredEventFields on InvitesTransferredEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  sourceMember {
+    id
+  }
+  targetMember {
+    id
+  }
+  numberOfInvites
+}
+
+query getInvitesTransferredEventsBySourceMemberId($sourceMemberId: ID!) {
+  invitesTransferredEvents(where: { sourceMember: { id_eq: $sourceMemberId } }) {
+    ...InvitesTransferredEventFields
+  }
+}
+
+fragment StakingAccountAddedEventFields on StakingAccountAddedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  member {
+    id
+  }
+  account
+}
+
+query getStakingAccountAddedEventsByMemberId($memberId: ID!) {
+  stakingAccountAddedEvents(where: { member: { id_eq: $memberId } }) {
+    ...StakingAccountAddedEventFields
+  }
+}
+
+fragment StakingAccountConfirmedEventFields on StakingAccountConfirmedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  member {
+    id
+  }
+  account
+}
+
+query getStakingAccountConfirmedEventsByMemberId($memberId: ID!) {
+  stakingAccountConfirmedEvents(where: { member: { id_eq: $memberId } }) {
+    ...StakingAccountConfirmedEventFields
+  }
+}
+
+fragment StakingAccountRemovedEventFields on StakingAccountRemovedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  member {
+    id
+  }
+  account
+}
+
+query getStakingAccountRemovedEventsByMemberId($memberId: ID!) {
+  stakingAccountRemovedEvents(where: { member: { id_eq: $memberId } }) {
+    ...StakingAccountRemovedEventFields
+  }
+}
+
+fragment ReferralCutUpdatedEventFields on ReferralCutUpdatedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  newValue
+}
+
+query getReferralCutUpdatedEventsByEventId($eventId: ID!) {
+  referralCutUpdatedEvents(where: { id_eq: $eventId }) {
+    ...ReferralCutUpdatedEventFields
+  }
+}
+
+fragment MembershipPriceUpdatedEventFields on MembershipPriceUpdatedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  newPrice
+}
+
+query getMembershipPriceUpdatedEventsByEventId($eventId: ID!) {
+  membershipPriceUpdatedEvents(where: { id_eq: $eventId }) {
+    ...MembershipPriceUpdatedEventFields
+  }
+}
+
+fragment InitialInvitationBalanceUpdatedEventFields on InitialInvitationBalanceUpdatedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  newInitialBalance
+}
+
+query getInitialInvitationBalanceUpdatedEventsByEventId($eventId: ID!) {
+  initialInvitationBalanceUpdatedEvents(where: { id_eq: $eventId }) {
+    ...InitialInvitationBalanceUpdatedEventFields
+  }
+}
+
+fragment InitialInvitationCountUpdatedEventFields on InitialInvitationCountUpdatedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  newInitialInvitationCount
+}
+
+query getInitialInvitationCountUpdatedEventsByEventId($eventId: ID!) {
+  initialInvitationCountUpdatedEvents(where: { id_eq: $eventId }) {
+    ...InitialInvitationCountUpdatedEventFields
+  }
+}

+ 248 - 0
tests/integration-tests/src/graphql/queries/workingGroups.graphql

@@ -0,0 +1,248 @@
+fragment ApplicationBasicFields on WorkingGroupApplication {
+  id
+  runtimeId
+  status {
+    __typename
+    ... on ApplicationStatusCancelled {
+      openingCanceledEvent {
+        id
+      }
+    }
+    ... on ApplicationStatusWithdrawn {
+      applicationWithdrawnEvent {
+        id
+      }
+    }
+    ... on ApplicationStatusAccepted {
+      openingFilledEvent {
+        id
+      }
+    }
+    ... on ApplicationStatusRejected {
+      openingFilledEvent {
+        id
+      }
+    }
+  }
+}
+
+fragment OpeningStatusFields on WorkingGroupOpeningStatus {
+  __typename
+  ... on OpeningStatusFilled {
+    openingFilledEvent {
+      id
+    }
+  }
+  ... on OpeningStatusCancelled {
+    openingCanceledEvent {
+      id
+    }
+  }
+}
+
+fragment ApplicationFormQuestionFields on ApplicationFormQuestion {
+  question
+  type
+  index
+}
+
+fragment OpeningMetadataFields on WorkingGroupOpeningMetadata {
+  shortDescription
+  description
+  hiringLimit
+  expectedEnding
+  applicationDetails
+  applicationFormQuestions {
+    ...ApplicationFormQuestionFields
+  }
+}
+
+fragment WorkerFields on Worker {
+  id
+  runtimeId
+  group {
+    name
+  }
+  membership {
+    id
+  }
+  roleAccount
+  rewardAccount
+  stakeAccount
+  status {
+    __typename
+    ... on WorkerStatusLeft {
+      workerStartedLeavingEvent {
+        id
+      }
+      workerExitedEvent {
+        id
+      }
+    }
+    ... on WorkerStatusTerminated {
+      terminatedWorkerEvent {
+        id
+      }
+    }
+  }
+  isLead
+  stake
+  payouts {
+    id
+  }
+  slashes {
+    id
+  }
+  entry {
+    id
+  }
+  application {
+    ...ApplicationBasicFields
+  }
+  storage
+  rewardPerBlock
+  missingRewardAmount
+}
+
+fragment WorkingGroupMetadataFields on WorkingGroupMetadata {
+  id
+  status
+  statusMessage
+  about
+  description
+  setInEvent {
+    id
+  }
+}
+
+fragment OpeningFields on WorkingGroupOpening {
+  id
+  runtimeId
+  group {
+    name
+  }
+  applications {
+    ...ApplicationBasicFields
+  }
+  type
+  status {
+    ...OpeningStatusFields
+  }
+  metadata {
+    ...OpeningMetadataFields
+  }
+  stakeAmount
+  unstakingPeriod
+  rewardPerBlock
+  createdInEvent {
+    id
+  }
+}
+
+query getOpeningById($openingId: ID!) {
+  workingGroupOpeningByUniqueInput(where: { id: $openingId }) {
+    ...OpeningFields
+  }
+}
+
+query getOpeningsByIds($openingIds: [ID!]) {
+  workingGroupOpenings(where: { id_in: $openingIds }) {
+    ...OpeningFields
+  }
+}
+
+fragment ApplicationFields on WorkingGroupApplication {
+  ...ApplicationBasicFields
+  createdInEvent {
+    id
+  }
+  opening {
+    id
+    runtimeId
+  }
+  applicant {
+    id
+  }
+  roleAccount
+  rewardAccount
+  stakingAccount
+  answers {
+    question {
+      question
+    }
+    answer
+  }
+  stake
+}
+
+query getApplicationById($applicationId: ID!) {
+  workingGroupApplicationByUniqueInput(where: { id: $applicationId }) {
+    ...ApplicationFields
+  }
+}
+
+query getApplicationsByIds($applicationIds: [ID!]) {
+  workingGroupApplications(where: { id_in: $applicationIds }) {
+    ...ApplicationFields
+  }
+}
+
+fragment WorkingGroupFields on WorkingGroup {
+  id
+  name
+  metadata {
+    ...WorkingGroupMetadataFields
+  }
+  leader {
+    id
+    runtimeId
+  }
+  budget
+}
+
+query getWorkingGroupByName($name: String!) {
+  workingGroupByUniqueInput(where: { name: $name }) {
+    ...WorkingGroupFields
+  }
+}
+
+fragment UpcomingOpeningFields on UpcomingWorkingGroupOpening {
+  id
+  group {
+    name
+  }
+  metadata {
+    ...OpeningMetadataFields
+  }
+  expectedStart
+  stakeAmount
+  rewardPerBlock
+  createdInEvent {
+    id
+  }
+  createdAt
+}
+
+query getUpcomingOpeningById($id: ID!) {
+  upcomingWorkingGroupOpeningByUniqueInput(where: { id: $id }) {
+    ...UpcomingOpeningFields
+  }
+}
+
+query getUpcomingOpeningsByCreatedInEventIds($createdInEventIds: [ID!]) {
+  upcomingWorkingGroupOpenings(where: { createdInEvent: { id_in: $createdInEventIds } }) {
+    ...UpcomingOpeningFields
+  }
+}
+
+query getWorkingGroupMetadataSnapshotsByTimeAsc($groupId: ID!) {
+  workingGroupMetadata(where: { group: { id_eq: $groupId } }, orderBy: createdAt_ASC) {
+    ...WorkingGroupMetadataFields
+  }
+}
+
+query getWorkersByRuntimeIds($workerIds: [Int!], $groupId: ID!) {
+  workers(where: { runtimeId_in: $workerIds, group: { id_eq: $groupId } }) {
+    ...WorkerFields
+  }
+}

+ 447 - 0
tests/integration-tests/src/graphql/queries/workingGroupsEvents.graphql

@@ -0,0 +1,447 @@
+fragment AppliedOnOpeningEventFields on AppliedOnOpeningEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  opening {
+    id
+    runtimeId
+  }
+  application {
+    id
+    runtimeId
+  }
+}
+
+query getAppliedOnOpeningEventsByEventIds($eventIds: [ID!]) {
+  appliedOnOpeningEvents(where: { id_in: $eventIds }) {
+    ...AppliedOnOpeningEventFields
+  }
+}
+
+fragment OpeningAddedEventFields on OpeningAddedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  opening {
+    id
+    runtimeId
+  }
+}
+
+query getOpeningAddedEventsByEventIds($eventIds: [ID!]) {
+  openingAddedEvents(where: { id_in: $eventIds }) {
+    ...OpeningAddedEventFields
+  }
+}
+
+fragment LeaderSetEventFields on LeaderSetEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  worker {
+    id
+    runtimeId
+  }
+}
+
+query getLeaderSetEventsByEventIds($eventIds: [ID!]) {
+  leaderSetEvents(where: { id_in: $eventIds }) {
+    ...LeaderSetEventFields
+  }
+}
+
+fragment OpeningFilledEventFields on OpeningFilledEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  opening {
+    id
+    runtimeId
+  }
+  workersHired {
+    ...WorkerFields
+  }
+}
+
+query getOpeningFilledEventsByEventIds($eventIds: [ID!]) {
+  openingFilledEvents(where: { id_in: $eventIds }) {
+    ...OpeningFilledEventFields
+  }
+}
+
+fragment ApplicationWithdrawnEventFields on ApplicationWithdrawnEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  application {
+    id
+    runtimeId
+  }
+}
+
+query getApplicationWithdrawnEventsByEventIds($eventIds: [ID!]) {
+  applicationWithdrawnEvents(where: { id_in: $eventIds }) {
+    ...ApplicationWithdrawnEventFields
+  }
+}
+
+fragment OpeningCanceledEventFields on OpeningCanceledEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  opening {
+    id
+    runtimeId
+  }
+}
+
+query getOpeningCancelledEventsByEventIds($eventIds: [ID!]) {
+  openingCanceledEvents(where: { id_in: $eventIds }) {
+    ...OpeningCanceledEventFields
+  }
+}
+
+fragment StatusTextChangedEventFields on StatusTextChangedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  metadata
+  result {
+    __typename
+    ... on UpcomingOpeningAdded {
+      upcomingOpeningId
+    }
+    ... on UpcomingOpeningRemoved {
+      upcomingOpeningId
+    }
+    ... on WorkingGroupMetadataSet {
+      metadata {
+        id
+      }
+    }
+    ... on InvalidActionMetadata {
+      reason
+    }
+  }
+}
+
+query getStatusTextChangedEventsByEventIds($eventIds: [ID!]) {
+  statusTextChangedEvents(where: { id_in: $eventIds }) {
+    ...StatusTextChangedEventFields
+  }
+}
+
+fragment WorkerRoleAccountUpdatedEventFields on WorkerRoleAccountUpdatedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  worker {
+    id
+    runtimeId
+  }
+  newRoleAccount
+}
+
+query getWorkerRoleAccountUpdatedEventsByEventIds($eventIds: [ID!]) {
+  workerRoleAccountUpdatedEvents(where: { id_in: $eventIds }) {
+    ...WorkerRoleAccountUpdatedEventFields
+  }
+}
+
+fragment WorkerRewardAccountUpdatedEventFields on WorkerRewardAccountUpdatedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  worker {
+    id
+    runtimeId
+  }
+  newRewardAccount
+}
+
+query getWorkerRewardAccountUpdatedEventsByEventIds($eventIds: [ID!]) {
+  workerRewardAccountUpdatedEvents(where: { id_in: $eventIds }) {
+    ...WorkerRewardAccountUpdatedEventFields
+  }
+}
+
+fragment StakeIncreasedEventFields on StakeIncreasedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  worker {
+    id
+    runtimeId
+  }
+  amount
+}
+
+query getStakeIncreasedEventsByEventIds($eventIds: [ID!]) {
+  stakeIncreasedEvents(where: { id_in: $eventIds }) {
+    ...StakeIncreasedEventFields
+  }
+}
+
+fragment WorkerStartedLeavingEventFields on WorkerStartedLeavingEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  worker {
+    id
+    runtimeId
+  }
+  rationale
+}
+
+query getWorkerStartedLeavingEventsByEventIds($eventIds: [ID!]) {
+  workerStartedLeavingEvents(where: { id_in: $eventIds }) {
+    ...WorkerStartedLeavingEventFields
+  }
+}
+
+fragment WorkerRewardAmountUpdatedEventFields on WorkerRewardAmountUpdatedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  worker {
+    id
+    runtimeId
+  }
+  newRewardPerBlock
+}
+
+query getWorkerRewardAmountUpdatedEventsByEventIds($eventIds: [ID!]) {
+  workerRewardAmountUpdatedEvents(where: { id_in: $eventIds }) {
+    ...WorkerRewardAmountUpdatedEventFields
+  }
+}
+
+fragment StakeSlashedEventFields on StakeSlashedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  worker {
+    id
+    runtimeId
+  }
+  requestedAmount
+  slashedAmount
+  rationale
+}
+
+query getStakeSlashedEventsByEventIds($eventIds: [ID!]) {
+  stakeSlashedEvents(where: { id_in: $eventIds }) {
+    ...StakeSlashedEventFields
+  }
+}
+
+fragment StakeDecreasedEventFields on StakeDecreasedEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  worker {
+    id
+    runtimeId
+  }
+  amount
+}
+
+query getStakeDecreasedEventsByEventIds($eventIds: [ID!]) {
+  stakeDecreasedEvents(where: { id_in: $eventIds }) {
+    ...StakeDecreasedEventFields
+  }
+}
+
+fragment TerminatedWorkerEventFields on TerminatedWorkerEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  worker {
+    id
+    runtimeId
+  }
+  penalty
+  rationale
+}
+
+query getTerminatedWorkerEventsByEventIds($eventIds: [ID!]) {
+  terminatedWorkerEvents(where: { id_in: $eventIds }) {
+    ...TerminatedWorkerEventFields
+  }
+}
+
+fragment TerminatedLeaderEventFields on TerminatedLeaderEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  worker {
+    id
+    runtimeId
+  }
+  penalty
+  rationale
+}
+
+query getTerminatedLeaderEventsByEventIds($eventIds: [ID!]) {
+  terminatedLeaderEvents(where: { id_in: $eventIds }) {
+    ...TerminatedLeaderEventFields
+  }
+}
+
+fragment LeaderUnsetEventFields on LeaderUnsetEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  leader {
+    id
+    runtimeId
+  }
+}
+
+query getLeaderUnsetEventsByEventIds($eventIds: [ID!]) {
+  leaderUnsetEvents(where: { id_in: $eventIds }) {
+    ...LeaderUnsetEventFields
+  }
+}
+
+fragment BudgetSetEventFields on BudgetSetEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  newBudget
+}
+
+query getBudgetSetEventsByEventIds($eventIds: [ID!]) {
+  budgetSetEvents(where: { id_in: $eventIds }) {
+    ...BudgetSetEventFields
+  }
+}
+
+fragment BudgetSpendingEventFields on BudgetSpendingEvent {
+  id
+  createdAt
+  inBlock
+  network
+  inExtrinsic
+  indexInBlock
+  group {
+    name
+  }
+  reciever
+  amount
+  rationale
+}
+
+query getBudgetSpendingEventsByEventIds($eventIds: [ID!]) {
+  budgetSpendingEvents(where: { id_in: $eventIds }) {
+    ...BudgetSpendingEventFields
+  }
+}

+ 2 - 0
tests/integration-tests/src/scenarios/full.ts

@@ -0,0 +1,2 @@
+import './memberships'
+import './workingGroups'

+ 19 - 0
tests/integration-tests/src/scenarios/memberships.ts

@@ -0,0 +1,19 @@
+import creatingMemberships from '../flows/membership/creatingMemberships'
+import updatingMemberProfile from '../flows/membership/updatingProfile'
+import updatingMemberAccounts from '../flows/membership/updatingAccounts'
+import invitingMebers from '../flows/membership/invitingMembers'
+import transferringInvites from '../flows/membership/transferringInvites'
+import managingStakingAccounts from '../flows/membership/managingStakingAccounts'
+import membershipSystem from '../flows/membership/membershipSystem'
+import { scenario } from '../Scenario'
+
+scenario(async ({ job }) => {
+  const membershipSystemJob = job('membership system', membershipSystem)
+  // All other job should be executed after, otherwise changing membershipPrice etc. may break them
+  job('creating members', creatingMemberships).after(membershipSystemJob)
+  job('updating member profile', updatingMemberProfile).after(membershipSystemJob)
+  job('updating member accounts', updatingMemberAccounts).after(membershipSystemJob)
+  job('inviting members', invitingMebers).after(membershipSystemJob)
+  job('transferring invites', transferringInvites).after(membershipSystemJob)
+  job('managing staking accounts', managingStakingAccounts).after(membershipSystemJob)
+})

+ 16 - 0
tests/integration-tests/src/scenarios/workingGroups.ts

@@ -0,0 +1,16 @@
+import leadOpening from '../flows/working-groups/leadOpening'
+import openingsAndApplications from '../flows/working-groups/openingsAndApplications'
+import upcomingOpenings from '../flows/working-groups/upcomingOpenings'
+import groupStatus from '../flows/working-groups/groupStatus'
+import workerActions from '../flows/working-groups/workerActions'
+import { scenario } from '../Scenario'
+import groupBudget from '../flows/working-groups/groupBudget'
+
+scenario(async ({ job }) => {
+  const sudoHireLead = job('sudo lead opening', leadOpening)
+  job('openings and applications', openingsAndApplications).requires(sudoHireLead)
+  job('upcoming openings', upcomingOpenings).requires(sudoHireLead)
+  job('group status', groupStatus).requires(sudoHireLead)
+  job('worker actions', workerActions).requires(sudoHireLead)
+  job('group budget', groupBudget).requires(sudoHireLead)
+})

+ 90 - 0
tests/integration-tests/src/types.ts

@@ -0,0 +1,90 @@
+import { MemberId } from '@joystream/types/common'
+import { ApplicationId, OpeningId, WorkerId, ApplyOnOpeningParameters } from '@joystream/types/working-group'
+import { Event } from '@polkadot/types/interfaces/system'
+import { BTreeMap } from '@polkadot/types'
+import { MembershipBoughtEvent } from './graphql/generated/schema'
+
+export type MemberContext = {
+  account: string
+  memberId: MemberId
+}
+
+export type AnyQueryNodeEvent = Pick<
+  MembershipBoughtEvent,
+  'createdAt' | 'updatedAt' | 'id' | 'inBlock' | 'inExtrinsic' | 'indexInBlock' | 'network'
+>
+
+export interface EventDetails {
+  event: Event
+  blockNumber: number
+  blockTimestamp: number
+  blockHash: string
+  indexInBlock: number
+}
+
+export interface MembershipBoughtEventDetails extends EventDetails {
+  memberId: MemberId
+}
+
+export interface MemberInvitedEventDetails extends EventDetails {
+  newMemberId: MemberId
+}
+
+export type MembershipEventName =
+  | 'MembershipBought'
+  | 'MemberProfileUpdated'
+  | 'MemberAccountsUpdated'
+  | 'MemberVerificationStatusUpdated'
+  | 'InvitesTransferred'
+  | 'MemberInvited'
+  | 'StakingAccountAdded'
+  | 'StakingAccountConfirmed'
+  | 'StakingAccountRemoved'
+  | 'InitialInvitationCountUpdated'
+  | 'MembershipPriceUpdated'
+  | 'ReferralCutUpdated'
+  | 'InitialInvitationBalanceUpdated'
+  | 'LeaderInvitationQuotaUpdated'
+
+export interface OpeningAddedEventDetails extends EventDetails {
+  openingId: OpeningId
+}
+
+export interface AppliedOnOpeningEventDetails extends EventDetails {
+  applicationId: ApplicationId
+  params: ApplyOnOpeningParameters
+}
+
+export interface OpeningFilledEventDetails extends EventDetails {
+  applicationIdToWorkerIdMap: BTreeMap<ApplicationId, WorkerId>
+}
+
+export type WorkingGroupsEventName =
+  | 'OpeningAdded'
+  | 'AppliedOnOpening'
+  | 'OpeningFilled'
+  | 'LeaderSet'
+  | 'WorkerRoleAccountUpdated'
+  | 'LeaderUnset'
+  | 'WorkerExited'
+  | 'TerminatedWorker'
+  | 'TerminatedLeader'
+  | 'StakeSlashed'
+  | 'StakeDecreased'
+  | 'StakeIncreased'
+  | 'ApplicationWithdrawn'
+  | 'OpeningCanceled'
+  | 'BudgetSet'
+  | 'WorkerRewardAccountUpdated'
+  | 'WorkerRewardAmountUpdated'
+  | 'StatusTextChanged'
+  | 'BudgetSpending'
+  | 'WorkerStartedLeaving'
+  | 'RewardPaid'
+  | 'NewMissedRewardLevelReached'
+
+export type WorkingGroupModuleName =
+  | 'storageWorkingGroup'
+  | 'contentDirectoryWorkingGroup'
+  | 'forumWorkingGroup'
+  | 'membershipWorkingGroup'

+ 26 - 0
tests/integration-tests/src/utils.ts

@@ -4,7 +4,18 @@ import { blake2AsHex } from '@polkadot/util-crypto'
 import BN from 'bn.js'
 import fs from 'fs'
 import { decodeAddress } from '@polkadot/keyring'
+import { Bytes } from '@polkadot/types'
+import { createType } from '@joystream/types'
 
+export type AnyMessage<T> = T & {
+  toJSON(): Record<string, unknown>
+}
+
+export type AnyMetadataClass<T> = {
+  decode(binary: Uint8Array): AnyMessage<T>
+  encode(obj: T): { finish(): Uint8Array }
+  toObject(obj: AnyMessage<T>): Record<string, unknown>
+}
 export class Utils {
   private static LENGTH_ADDRESS = 32 + 1 // publicKey + prefix
   private static LENGTH_ERA = 2 // assuming mortals
@@ -45,4 +56,19 @@ export class Utils {
   public static camelToSnakeCase(key: string): string {
     return key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)
   }
+
+  public static metadataToBytes<T>(metaClass: AnyMetadataClass<T>, obj: T): Bytes {
+    return createType('Bytes', '0x' + Buffer.from(metaClass.encode(obj).finish()).toString('hex'))
+  }
+
+  public static metadataFromBytes<T>(metaClass: AnyMetadataClass<T>, bytes: Bytes): T {
+    // We use `toObject()` to get rid of .prototype defaults for optional fields
+    return metaClass.toObject(metaClass.decode(bytes.toU8a(true))) as T
+  }
+
+  public static assert(condition: any, msg?: string): asserts condition {
+    if (!condition) {
+      throw new Error(msg || 'Assertion failed')
+    }
+  }
 }

+ 29 - 29
types/augment-codec/augment-api-query.ts

@@ -61,7 +61,7 @@ declare module '@polkadot/api/types/storage' {
       initialized: AugmentedQuery<ApiType, () => Observable<Option<MaybeRandomness>>>;
       /**
        * How late the current block is compared to its parent.
-       * 
+       *
        * This entry is populated as part of block execution and is cleaned up
        * on block finalization. Querying this storage entry outside of block
        * execution context should always yield zero.
@@ -77,9 +77,9 @@ declare module '@polkadot/api/types/storage' {
       nextRandomness: AugmentedQuery<ApiType, () => Observable<Randomness>>;
       /**
        * The epoch randomness for the *current* epoch.
-       * 
+       *
        * # Security
-       * 
+       *
        * This MUST NOT be used for gambling, as it can be influenced by a
        * malicious validator in the short term. It MAY be used in many
        * cryptographic protocols, however, so long as one remembers that this
@@ -90,11 +90,11 @@ declare module '@polkadot/api/types/storage' {
       randomness: AugmentedQuery<ApiType, () => Observable<Randomness>>;
       /**
        * Randomness under construction.
-       * 
+       *
        * We make a tradeoff between storage accesses and list length.
        * We store the under-construction randomness in segments of up to
        * `UNDER_CONSTRUCTION_SEGMENT_LENGTH`.
-       * 
+       *
        * Once a segment reaches this length, we begin the next one.
        * We reset all segments and return to `0` at the beginning of every
        * epoch.
@@ -108,7 +108,7 @@ declare module '@polkadot/api/types/storage' {
     balances: {
       /**
        * The balance of an account.
-       * 
+       *
        * NOTE: This is only used in the case that this module is used to store balances.
        **/
       account: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<AccountData>>;
@@ -119,7 +119,7 @@ declare module '@polkadot/api/types/storage' {
       locks: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Vec<BalanceLock>>>;
       /**
        * Storage version of the pallet.
-       * 
+       *
        * This is set to v2.0.0 for new networks.
        **/
       storageVersion: AugmentedQuery<ApiType, () => Observable<Releases>>;
@@ -431,7 +431,7 @@ declare module '@polkadot/api/types/storage' {
       /**
        * A mapping from grandpa set ID to the index of the *most recent* session for which its
        * members were responsible.
-       * 
+       *
        * TWOX-NOTE: `SetId` is not under user control.
        **/
       setIdSession: AugmentedQuery<ApiType, (arg: SetId | AnyNumber | Uint8Array) => Observable<Option<SessionIndex>>>;
@@ -452,7 +452,7 @@ declare module '@polkadot/api/types/storage' {
       authoredBlocks: AugmentedQueryDoubleMap<ApiType, (key1: SessionIndex | AnyNumber | Uint8Array, key2: ValidatorId | string | Uint8Array) => Observable<u32>>;
       /**
        * The block number after which it's ok to send heartbeats in current session.
-       * 
+       *
        * At the beginning of each session we set this to a value that should
        * fall roughly in the middle of the session duration.
        * The idea is to first wait for the validators to produce a block
@@ -566,9 +566,9 @@ declare module '@polkadot/api/types/storage' {
       reports: AugmentedQuery<ApiType, (arg: ReportIdOf | string | Uint8Array) => Observable<Option<OffenceDetails>>>;
       /**
        * Enumerates all reports of a kind along with the time they happened.
-       * 
+       *
        * All reports are sorted by the time of offence.
-       * 
+       *
        * Note that the actual type of this mapping is `Vec<u8>`, this is because values of
        * different types are not supported at the moment so we are doing the manual serialization.
        **/
@@ -650,7 +650,7 @@ declare module '@polkadot/api/types/storage' {
       currentIndex: AugmentedQuery<ApiType, () => Observable<SessionIndex>>;
       /**
        * Indices of disabled validators.
-       * 
+       *
        * The set is cleared when `on_session_ending` returns a new set of identities.
        **/
       disabledValidators: AugmentedQuery<ApiType, () => Observable<Vec<u32>>>;
@@ -680,7 +680,7 @@ declare module '@polkadot/api/types/storage' {
     staking: {
       /**
        * The active era information, it holds index and start.
-       * 
+       *
        * The active era is the era currently rewarded.
        * Validator set of this era must be equal to `SessionInterface::validators`.
        **/
@@ -691,7 +691,7 @@ declare module '@polkadot/api/types/storage' {
       bonded: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Option<AccountId>>>;
       /**
        * A mapping from still-bonded eras to the first session index of that era.
-       * 
+       *
        * Must contains information for eras for the range:
        * `[active_era - bounding_duration; active_era]`
        **/
@@ -703,7 +703,7 @@ declare module '@polkadot/api/types/storage' {
       canceledSlashPayout: AugmentedQuery<ApiType, () => Observable<BalanceOf>>;
       /**
        * The current era index.
-       * 
+       *
        * This is the latest planned era, depending on how the Session pallet queues the validator
        * set, it might be active or not.
        **/
@@ -724,23 +724,23 @@ declare module '@polkadot/api/types/storage' {
       erasRewardPoints: AugmentedQuery<ApiType, (arg: EraIndex | AnyNumber | Uint8Array) => Observable<EraRewardPoints>>;
       /**
        * Exposure of validator at era.
-       * 
+       *
        * This is keyed first by the era index to allow bulk deletion and then the stash account.
-       * 
+       *
        * Is it removed after `HISTORY_DEPTH` eras.
        * If stakers hasn't been set or has been removed then empty exposure is returned.
        **/
       erasStakers: AugmentedQueryDoubleMap<ApiType, (key1: EraIndex | AnyNumber | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<Exposure>>;
       /**
        * Clipped Exposure of validator at era.
-       * 
+       *
        * This is similar to [`ErasStakers`] but number of nominators exposed is reduced to the
        * `T::MaxNominatorRewardedPerValidator` biggest stakers.
        * (Note: the field `total` and `own` of the exposure remains unchanged).
        * This is used to limit the i/o cost for the nominator payout.
-       * 
+       *
        * This is keyed fist by the era index to allow bulk deletion and then the stash account.
-       * 
+       *
        * Is it removed after `HISTORY_DEPTH` eras.
        * If stakers hasn't been set or has been removed then empty exposure is returned.
        **/
@@ -756,15 +756,15 @@ declare module '@polkadot/api/types/storage' {
       erasTotalStake: AugmentedQuery<ApiType, (arg: EraIndex | AnyNumber | Uint8Array) => Observable<BalanceOf>>;
       /**
        * Similar to `ErasStakers`, this holds the preferences of validators.
-       * 
+       *
        * This is keyed first by the era index to allow bulk deletion and then the stash account.
-       * 
+       *
        * Is it removed after `HISTORY_DEPTH` eras.
        **/
       erasValidatorPrefs: AugmentedQueryDoubleMap<ApiType, (key1: EraIndex | AnyNumber | Uint8Array, key2: AccountId | string | Uint8Array) => Observable<ValidatorPrefs>>;
       /**
        * The total validator era payout for the last `HISTORY_DEPTH` eras.
-       * 
+       *
        * Eras that haven't finished yet or has been removed doesn't have reward.
        **/
       erasValidatorReward: AugmentedQuery<ApiType, (arg: EraIndex | AnyNumber | Uint8Array) => Observable<Option<BalanceOf>>>;
@@ -774,9 +774,9 @@ declare module '@polkadot/api/types/storage' {
       forceEra: AugmentedQuery<ApiType, () => Observable<Forcing>>;
       /**
        * Number of eras to keep in history.
-       * 
+       *
        * Information is kept for eras in `[current_era - history_depth; current_era]`.
-       * 
+       *
        * Must be more than the number of eras delayed by session otherwise. I.e. active era must
        * always be in history. I.e. `active_era > current_era - history_depth` must be
        * guaranteed.
@@ -829,7 +829,7 @@ declare module '@polkadot/api/types/storage' {
       slashingSpans: AugmentedQuery<ApiType, (arg: AccountId | string | Uint8Array) => Observable<Option<SlashingSpans>>>;
       /**
        * The percentage of the slash that is distributed to reporters.
-       * 
+       *
        * The rest of the slashed value is handled by the `Slash`.
        **/
       slashRewardFraction: AugmentedQuery<ApiType, () => Observable<Perbill>>;
@@ -851,7 +851,7 @@ declare module '@polkadot/api/types/storage' {
       /**
        * True if network has been upgraded to this version.
        * Storage version of the pallet.
-       * 
+       *
        * This is set to v3.0.0 for new networks.
        **/
       storageVersion: AugmentedQuery<ApiType, () => Observable<Releases>>;
@@ -953,11 +953,11 @@ declare module '@polkadot/api/types/storage' {
       /**
        * Mapping between a topic (represented by T::Hash) and a vector of indexes
        * of events in the `<Events<T>>` list.
-       * 
+       *
        * All topic vectors have deterministic storage locations depending on the topic. This
        * allows light-clients to leverage the changes trie storage tracking mechanism and
        * in case of changes fetch the list of events of interest.
-       * 
+       *
        * The value has the type `(T::BlockNumber, EventIndex)` because if we used only just
        * the `EventIndex` then in case if the topic has the same contents on the next block
        * no notification will be triggered thus the event might be lost.

File diff suppressed because it is too large
+ 157 - 157
types/augment-codec/augment-api-tx.ts


Some files were not shown because too many files changed in this diff