Перейти к содержанию

Пайщики

Пайщик - это пользователь, у которого есть принадлежащий ему объект аккаунта пайщика ParticipantAccount, содержащий информацию о его членстве в кооперативе. Аккаунт пайщика выдаётся кооперативом, при прохождении полной процедуры регистрации пайщика, или при добавлении ранее зарегистрированного пайщика в систему.

Регистрация пайщика

Аккаунт пайщика ParticipantAccount выдаётся пользователю смарт-контрактом при прохождении полной процедуры регистрации пайщика. После завершения процедуры аккаунт пайщика будет доступен в объекте Account -> ParticipantAccount при получении аккаунта пользователя.

sequenceDiagram
    autonumber
    participant U as Пользователь
    participant SDK as SDK
    participant SYS as Блокчейн
    participant GOV as Совет Кооператива

    Note over U,SYS: Общий процесс регистрации пайщика

    U->>SDK: Регистрация аккаунта
    SDK->>SYS: Проверка мажоритарности кооператива

    alt Кооператив мажоритарен
        U->>SDK: Выбор кооперативного участка
    else
        Note over U,SYS: Участок не требуется
    end

    U->>SDK: Предгенерация 4х соглашений и заявления на вступление
    SDK->>U: Отображение документов
    U->>SDK: Приём собственноручной подписи
    U->>SDK: Генерация заявления с собственнручной подписью
    SDK->>U: Заявление с собственноручной подписью
    U->>SDK: Цифровая подпись пакета документов

    SDK->>SYS: Отправка пакета документов
    U->>SDK: Оплата вступительного и паевого взноса
    SDK->>SYS: Подтверждение оплаты

    SYS->>GOV: Вынесение вопроса в повестку
    GOV->>SYS: Решение совета
    SYS->>U: Уведомление о принятии в кооператив

1. Регистрация аккаунта

Пользователь заполняет форму и регистрирует аккаунт провайдера, как это описано в разделе Регистрация Аккаунта.

2. Выбор кооперативного участка

Пользователю необходимо выбрать кооперативный участок в том случае, если кооператив перешёл на мажоритарную систему управления, организовав >= 3 кооперативных участков в своём кооперативе. В случае, если кооператив - мажоритарен, пользователю потребуется предоставить выбор идентификатора кооперативного участка, председателю которого он делегирует свой голос на общих собраниях.

Для того, чтобы выяснить, является ли кооператив мажоритарным, необходимо извлечь объект системной информации SystemInfo, обратиться в нём к CooperativeOperatorAccount, и извлечь булево свойство is_branched.

Значение true в is_branched означает, что кооператив - мажоритарный, и пайщику при регистрации будет необходимо предоставить идентификатор имени кооперативного участка, иначе, регистрация пайщика будет отклонена. Извлечение списка кооперативных участков описано в разделе Получить Кооперативные Участки. Для отправки последующей отправки документов на регистрацию пайщика, потребуется выбрать из списка параметр braname - имя аккаунта кооперативного участка, при котором регистрируется пайщик.

3. Предгенерация документов

Для того, чтобы сгенерировать пайщику персональное заявление на вступление и все сопутствующие соглашения, и показать их ему в том виде, в котором он будет подписывать, необходимо произвести предгенерацию пакета документов.

Заявление на вступление

🛠️ SDK: Mutations.Participants.GenerateParticipantApplication | 🔗 GraphQL API: Mutation.generateParticipantApplication

Мутация для генерации заявления на вступление пайщика в кооператив вызывается с параметром signature, который может быть пустым для пред-генерации, или содержать png изображение подписи в кодировке base64 для основной генерации. Массив links будет пустым для пред-генерации, но обязательно должен содержать хэши 4-х соглашений для основной генерации.

import { Mutations } from '@coopenomics/sdk';

const variables: Mutations.Participants.GenerateParticipantApplication.IInput = {
  data: {
    block_num?: <null | number>; // Номер блока, на котором был создан документ
    braname: <string>; // Имя аккаунта кооперативного участка
    coopname: <string>; // Название кооператива, связанное с документом
    created_at?: <null | string>; // Дата и время создания документа
    generator?: <null | string>; // Имя генератора, использованного для создания документа
    lang?: <null | string>; // Язык документа
    links?: <null | string[]>; // Ссылки, связанные с документом
    signature: <string>; // Изображение собственноручной подписи (base-64)
    skip_save: <boolean>; // Флаг пропуска сохранения документа (используется для предварительной генерации и демонстрации пользователю)
    timezone?: <null | string>; // Часовой пояс, в котором был создан документ
    title?: <null | string>; // Название документа
    username: <string>; // Имя пользователя, создавшего документ
    version?: <null | string>; // Версия генератора, использованного для создания документа
  };
  options?: {
    skip_save?: <null | boolean>; // Пропустить сохранение
  };
};

const { [Mutations.Participants.GenerateParticipantApplication.name]: result } = await client.Mutation(
  Mutations.Participants.GenerateParticipantApplication.mutation,
  { variables }
);

Соглашение о ЦПП "Цифровой Кошелёк"

🛠️ SDK: Mutations.Agreements.GenerateWalletAgreement | 🔗 GraphQL API: Mutation.generateWalletAgreement

import { Mutations } from '@coopenomics/sdk';

const variables: Mutations.Participants.GenerateParticipantApplication.IInput = {
  data: {
    block_num?: <null | number>; // Номер блока, на котором был создан документ
    braname: <string>; // Имя аккаунта кооперативного участка
    coopname: <string>; // Название кооператива, связанное с документом
    created_at?: <null | string>; // Дата и время создания документа
    generator?: <null | string>; // Имя генератора, использованного для создания документа
    lang?: <null | string>; // Язык документа
    links?: <null | string[]>; // Ссылки, связанные с документом
    signature: <string>; // Изображение собственноручной подписи (base-64)
    skip_save: <boolean>; // Флаг пропуска сохранения документа (используется для предварительной генерации и демонстрации пользователю)
    timezone?: <null | string>; // Часовой пояс, в котором был создан документ
    title?: <null | string>; // Название документа
    username: <string>; // Имя пользователя, создавшего документ
    version?: <null | string>; // Версия генератора, использованного для создания документа
  };
  options?: {
    skip_save?: <null | boolean>; // Пропустить сохранение
  };
};

const { [Mutations.Participants.GenerateParticipantApplication.name]: result } = await client.Mutation(
  Mutations.Participants.GenerateParticipantApplication.mutation,
  { variables }
);

Соглашение о простой электронной подписи

🛠️ SDK: Mutations.Agreements.GenerateSignatureAgreement | 🔗 GraphQL API: Mutation.generateSignatureAgreement

import { Mutations } from '@coopenomics/sdk';

const variables: Mutations.Participants.GenerateParticipantApplication.IInput = {
  data: {
    block_num?: <null | number>; // Номер блока, на котором был создан документ
    braname: <string>; // Имя аккаунта кооперативного участка
    coopname: <string>; // Название кооператива, связанное с документом
    created_at?: <null | string>; // Дата и время создания документа
    generator?: <null | string>; // Имя генератора, использованного для создания документа
    lang?: <null | string>; // Язык документа
    links?: <null | string[]>; // Ссылки, связанные с документом
    signature: <string>; // Изображение собственноручной подписи (base-64)
    skip_save: <boolean>; // Флаг пропуска сохранения документа (используется для предварительной генерации и демонстрации пользователю)
    timezone?: <null | string>; // Часовой пояс, в котором был создан документ
    title?: <null | string>; // Название документа
    username: <string>; // Имя пользователя, создавшего документ
    version?: <null | string>; // Версия генератора, использованного для создания документа
  };
  options?: {
    skip_save?: <null | boolean>; // Пропустить сохранение
  };
};

const { [Mutations.Participants.GenerateParticipantApplication.name]: result } = await client.Mutation(
  Mutations.Participants.GenerateParticipantApplication.mutation,
  { variables }
);

Пользовательское соглашение

🛠️ SDK: Mutations.Agreements.GenerateUserAgreement | 🔗 GraphQL API: Mutation.generateUserAgreement

import { Mutations } from '@coopenomics/sdk';

const variables: Mutations.Participants.GenerateParticipantApplication.IInput = {
  data: {
    block_num?: <null | number>; // Номер блока, на котором был создан документ
    braname: <string>; // Имя аккаунта кооперативного участка
    coopname: <string>; // Название кооператива, связанное с документом
    created_at?: <null | string>; // Дата и время создания документа
    generator?: <null | string>; // Имя генератора, использованного для создания документа
    lang?: <null | string>; // Язык документа
    links?: <null | string[]>; // Ссылки, связанные с документом
    signature: <string>; // Изображение собственноручной подписи (base-64)
    skip_save: <boolean>; // Флаг пропуска сохранения документа (используется для предварительной генерации и демонстрации пользователю)
    timezone?: <null | string>; // Часовой пояс, в котором был создан документ
    title?: <null | string>; // Название документа
    username: <string>; // Имя пользователя, создавшего документ
    version?: <null | string>; // Версия генератора, использованного для создания документа
  };
  options?: {
    skip_save?: <null | boolean>; // Пропустить сохранение
  };
};

const { [Mutations.Participants.GenerateParticipantApplication.name]: result } = await client.Mutation(
  Mutations.Participants.GenerateParticipantApplication.mutation,
  { variables }
);

Согласие с политикой конфиденциальности

🛠️ SDK: Mutations.Agreements.GeneratePrivacyAgreement | 🔗 GraphQL API: Mutation.generatePrivacyAgreement

import { Mutations } from '@coopenomics/sdk';

const variables: Mutations.Participants.GenerateParticipantApplication.IInput = {
  data: {
    block_num?: <null | number>; // Номер блока, на котором был создан документ
    braname: <string>; // Имя аккаунта кооперативного участка
    coopname: <string>; // Название кооператива, связанное с документом
    created_at?: <null | string>; // Дата и время создания документа
    generator?: <null | string>; // Имя генератора, использованного для создания документа
    lang?: <null | string>; // Язык документа
    links?: <null | string[]>; // Ссылки, связанные с документом
    signature: <string>; // Изображение собственноручной подписи (base-64)
    skip_save: <boolean>; // Флаг пропуска сохранения документа (используется для предварительной генерации и демонстрации пользователю)
    timezone?: <null | string>; // Часовой пояс, в котором был создан документ
    title?: <null | string>; // Название документа
    username: <string>; // Имя пользователя, создавшего документ
    version?: <null | string>; // Версия генератора, использованного для создания документа
  };
  options?: {
    skip_save?: <null | boolean>; // Пропустить сохранение
  };
};

const { [Mutations.Participants.GenerateParticipantApplication.name]: result } = await client.Mutation(
  Mutations.Participants.GenerateParticipantApplication.mutation,
  { variables }
);

В результате предгенерации будет получены объекты с документами, которые могут быть продемонстрированы пользователю перед запросом его собственноручной подписи. Кроме того, предгенерация необходима, чтобы криптографически связать заявление на вступление с соглашениями на этапе основной генерации после получения собственноручной подписи.

4. Собственноручная подпись

Для получения собственноручной подписи пользователя используется вспомогательный набор методов 🛠️ SDK: Methods.Canvas. Для начала процесса получения собственноручной подписи необходимо создать область для подписи с помощью Canvas.createCanvas(), передав id элемента div, в котором будет размещен canvas.

import { Classes } from '@coopenomics/sdk'

// Указываем контейнер, где будет размещён холст
const container = document.getElementById('signature-container') as HTMLElement

// Создаём экземпляр Canvas для работы с подписью
const signatureCanvas = new Classes.Canvas(container, {
  lineWidth: 5,
  strokeStyle: '#000',
})

После завершения процесса собственноручной подписи, необходимо извлечь её и, при необходимости, очистить область:

// Извлечение подписи в формате base64
const signature = signatureCanvas.getSignature()
console.log('Подпись в формате base64:', signature)

// Очистка холста при необходимости
signatureCanvas.clearCanvas()

// Освобождение ресурсов, если холст больше не нужен
signatureCanvas.destroy()

В результате, у вас будет строковое представление изображения собственноручной подписи пользователя, которое теперь необходимо использовать на основной генерации заявления на вступление в кооператив.

5. Генерация заявления

🛠️ SDK: Mutations.Participants.GenerateApplication | 🔗 GraphQL API: Mutation.generateApplication

Основная генерация заявления производится аналогично предгенерации, однако, в signature необходимо передать полученную ранее собственноручную подпись, а в массиве links указать хэши всех ранее сгенерированных соглашений.

const variables: Mutations.Participants.GenerateApplication.IInput = {
    data: {
      singature: <полученная ранее строка с изображением подписи в png/base64>,
      links: [participantApplication.hash, signatureAgreement.hash, userAgreement.hash, privacyAgreement.hash]
      username: <имя аккаунта пользователя>,
      coopname: <имя аккаунта кооператива>
  }

const { [Mutations.Participants.GenerateApplication.name]: participantApplication2 } = await client.Mutation(
  Mutations.Participants.GenerateApplication.mutation,
  {
    variables,
  }
);

В результате исполнения мутации будет возвращён объект заявления, который сгенерирован с применением его собственноручной подписи. Все документы будут сохранены в MONO и криптографически связаны с пользователем, между собой, и его собственноручной подписью.

5. Подпись документов

Теперь у нас есть полный пакет документов: 4 соглашения с этапа пред-генерации и 1 заявление с предыдущего этапа, которое включает собственноручную подпись пользователя и хэш-ссылки на соглашения.

Теперь необходимо подписать все эти 5 документов. Цифровая подпись осуществляется методом класса 🛠️ Document.sign, активный инстанс которого есть в SDK-клиенте. Вы можете использовать client.Document.sign(doc) на действующем экземпляре клиента или создать новый экземпляр класса Document, импортировав его из SDK:

const wif = <приватный ключ>

//устанавливаем ключ в клиента, если необходимо
client.Document.setWif(wif)

//последовательно подписываем все документы:
const signedSignatureAgreement = client.Document.sign(signatureAgreement)
const signedUserAgreement = client.Document.sign(userAgreement)
const signedWalletAgreement = client.Document.sign(walletAgreement)
const signedPrivacyAgreement = client.Document.sign(privacyAgreement)
const signedParticipantApplication = client.Document.sign(participantApplication2)

Для успешной подписи документов в SDK-клиенте должен быть установлен приватный ключ. В результате, каждый документ будет подписан подготовлен к отправке приведением к необходимому формату.

6. Отправка документов

🛠️ SDK: Mutations.Participants.RegisterParticipant | 🔗 GraphQL API: Mutation.registerParticipant

Регистрация пайщика производится мутацией RegisterParticipant с передачей подписанного заявления и соглашений. Отправленный пакет документов сохраняется в MONO для пользователя и ожидает поступления оплаты взносов перед отправкой в совет на голосование.

import { Mutations } from '@coopenomics/sdk';

const variables: Mutations.Participants.RegisterParticipant.IInput = {
  data: {
    privacy_agreement: {
      hash: <string>; // Хэш документа
      meta: {
        block_num: <number>; // Номер блока, на котором был создан документ
        coopname: <string>; // Название кооператива, связанное с документом
        created_at: <string>; // Дата и время создания документа
        generator: <string>; // Имя генератора, использованного для создания документа
        lang: <string>; // Язык документа
        links: <string[]>; // Ссылки, связанные с документом
        registry_id: <number>; // ID документа в реестре
        timezone: <string>; // Часовой пояс, в котором был создан документ
        title: <string>; // Название документа
        username: <string>; // Имя пользователя, создавшего документ
        version: <string>; // Версия генератора, использованного для создания документа
      };
      public_key: <string>; // Публичный ключ документа
      signature: <string>; // Подпись документа
    };
    signature_agreement: {
      hash: <string>; // Хэш документа
      meta: {
        block_num: <number>; // Номер блока, на котором был создан документ
        coopname: <string>; // Название кооператива, связанное с документом
        created_at: <string>; // Дата и время создания документа
        generator: <string>; // Имя генератора, использованного для создания документа
        lang: <string>; // Язык документа
        links: <string[]>; // Ссылки, связанные с документом
        registry_id: <number>; // ID документа в реестре
        timezone: <string>; // Часовой пояс, в котором был создан документ
        title: <string>; // Название документа
        username: <string>; // Имя пользователя, создавшего документ
        version: <string>; // Версия генератора, использованного для создания документа
      };
      public_key: <string>; // Публичный ключ документа
      signature: <string>; // Подпись документа
    };
    statement: {
      hash: <string>; // Хэш документа
      meta: {
        block_num: <number>; // Номер блока, на котором был создан документ
        braname: <string>; // Имя аккаунта кооперативного участка
        coopname: <string>; // Название кооператива, связанное с документом
        created_at: <string>; // Дата и время создания документа
        generator: <string>; // Имя генератора, использованного для создания документа
        lang: <string>; // Язык документа
        links: <string[]>; // Ссылки, связанные с документом
        registry_id: <number>; // ID документа в реестре
        signature: <string>; // Изображение собственноручной подписи (base-64)
        skip_save: <boolean>; // Флаг пропуска сохранения документа (используется для предварительной генерации и демонстрации пользователю)
        timezone: <string>; // Часовой пояс, в котором был создан документ
        title: <string>; // Название документа
        username: <string>; // Имя пользователя, создавшего документ
        version: <string>; // Версия генератора, использованного для создания документа
      };
      public_key: <string>; // Публичный ключ документа
      signature: <string>; // Подпись документа
    };
    user_agreement: {
      hash: <string>; // Хэш документа
      meta: {
        block_num: <number>; // Номер блока, на котором был создан документ
        coopname: <string>; // Название кооператива, связанное с документом
        created_at: <string>; // Дата и время создания документа
        generator: <string>; // Имя генератора, использованного для создания документа
        lang: <string>; // Язык документа
        links: <string[]>; // Ссылки, связанные с документом
        registry_id: <number>; // ID документа в реестре
        timezone: <string>; // Часовой пояс, в котором был создан документ
        title: <string>; // Название документа
        username: <string>; // Имя пользователя, создавшего документ
        version: <string>; // Версия генератора, использованного для создания документа
      };
      public_key: <string>; // Публичный ключ документа
      signature: <string>; // Подпись документа
    };
    username: <string>; // Имя аккаунта пайщика
    wallet_agreement: {
      hash: <string>; // Хэш документа
      meta: {
        block_num: <number>; // Номер блока, на котором был создан документ
        coopname: <string>; // Название кооператива, связанное с документом
        created_at: <string>; // Дата и время создания документа
        generator: <string>; // Имя генератора, использованного для создания документа
        lang: <string>; // Язык документа
        links: <string[]>; // Ссылки, связанные с документом
        registry_id: <number>; // ID документа в реестре
        timezone: <string>; // Часовой пояс, в котором был создан документ
        title: <string>; // Название документа
        username: <string>; // Имя пользователя, создавшего документ
        version: <string>; // Версия генератора, использованного для создания документа
      };
      public_key: <string>; // Публичный ключ документа
      signature: <string>; // Подпись документа
    };
  };
};

const { [Mutations.Participants.RegisterParticipant.name]: result } = await client.Mutation(
  Mutations.Participants.RegisterParticipant.mutation,
  { variables }
);

7. Оплата взносов

🛠️ SDK: Mutations.Payments.CreateInitialPayment | 🔗 GraphQL API: Mutation.createInitialPayment

Перед тем, как принятые документы будут отправлены в повестку совета на голосование, новому пайщику необходимо оплатить вступительный и минимальный паевый взносы (одним платежом).

import { Mutations } from '@coopenomics/sdk';

const variables: Mutations.Payments.CreateInitialPayment.IInput = {
  data: {
    username: <string>; // Имя аккаунта пользователя
  };
};

const { [Mutations.Payments.CreateInitialPayment.name]: result } = await client.Mutation(
  Mutations.Payments.CreateInitialPayment.mutation,
  { variables }
);

Результат:

interface IOutput {
  createInitialPayment: {
    amount: <number>; // Сумма платежа
    blockchain_id: <number>; // Идентификационный номер платежа в блокчейне
    created_at: <unknown>; // Дата создания платежа
    details: {
      amount_plus_fee: <string>; // Сумма платежа с учетом комиссии
      amount_without_fee: <string>; // Сумма платежа без учета комиссии
      data: <string>; // Строка с данными платежа
      fact_fee_percent: <number>; // Фактический процент комиссии
      fee_amount: <string>; // Размер комиссии в абсолютных значениях
      fee_percent: <number>; // Процент комиссии
      tolerance_percent: <number>; // Допустимый процент отклонения
    };
    expired_at: <unknown>; // Дата истечения срока давности платежа
    id: <string>; // Идентификатор платежа во внутренней системе учёта
    message: <string>; // Содержит сервисное сообщение провайдера об ошибке обработки платежа
    provider: <string>; // Идентификатор наименования провайдера платежа, ответственного за обработку
    status: <PaymentStatus>; // Идентификатор номера платежа, который отображается пользователю в платежных документах
    symbol: <string>; // Символ тикера валюты платежа
    updated_at: <unknown>; // Дата обновления платежа
    username: <string>; // Имя аккаунта пользователя, совершающего платеж
  };
}

Подробнее о доступных платежных провайдерах и управлении платежами смотри раздел Платежи. После получения подтверждения о поступлении платежа (статус платежа PAID), пользователю будет зарегистрирован аккаунт в блокчейне, а пакет документов пайщика поставлен в повестку голосования совета кооператива.

8. Получение решения совета

После поступления платежа вопрос добавляется в повестку голосования совета, где каждый член совета голосует за решение о приёме нового пайщика, а председатель - утверждает это решение. Процесс принятия решения советом описан в разделе Решения.

После того, как совет примет решение, оно будет автоматически исполнено: обновятся все реестры, будут созданы счета, открыты кошельки и т.д., а пользователь получит уведомление на электронную почту о том, что он принят в кооператив. С этого момента он является пайщиком, обладает объектом ParticipantAccount в Account, и может участвовать во всех целевых потребительских программах кооператива.

Добавление пайщика

🛠️ SDK: Mutations.Participants.AddParticipant | 🔗 GraphQL API: Mutation.addParticipant

Иногда необходимо добавить в цифровую систему уже действующего пайщика кооператива. В таком случае, нам не нужно проводить регистрацию пайщика по полному процессу, а достаточно сразу добавить его в систему.

Данная мутация должна использоваться ТОГДА И ТОЛЬКО ТОГДА, когда решение совета кооператива уже принято и оформлено в бумажном протоколе, а пайщик фактически совершил взносы в кооператив. Т.е. юридически пользователь уже является пайщиком кооператива и его необходимо только добавить в систему, переведя взаимоотношения с ним в цифровую форму.

import { Mutations } from '@coopenomics/sdk';

const variables: Mutations.Participants.AddParticipant.IInput = {
  data: {
    created_at: <string>; // Дата создания аккаунта в строковом формате даты EOSIO по UTC (2024-12-28T06:58:52.500)
    email: <string>; // Электронная почта
    entrepreneur_data?: <null | {
        bank_account: {
          account_number: <string>; // Номер банковского счета
          bank_name: <string>; // Название банка
          card_number?: <null | string>; // Номер карты
          currency: <string>; // Валюта счета
          details: {
            bik: <string>; // БИК банка
            corr: <string>; // Корреспондентский счет
            kpp: <string>; // КПП банка
          };
        };
        birthdate: <string>; // Дата рождения
        city: <string>; // Город
        country: <Russia>; // Страна
        details: {
          inn: <string>; // ИНН
          ogrn: <string>; // ОГРН
        };
        first_name: <string>; // Имя
        full_address: <string>; // Полный адрес
        last_name: <string>; // Фамилия
        middle_name: <string>; // Отчество
        phone: <string>; // Телефон
      }>; // Данные индивидуального предпринимателя
    individual_data?: <null | {
        birthdate: <string>; // Дата рождения
        first_name: <string>; // Имя
        full_address: <string>; // Полный адрес
        last_name: <string>; // Фамилия
        middle_name: <string>; // Отчество
        passport?: <null | {
            code: <string>;
            issued_at: <string>;
            issued_by: <string>;
            number: <number>;
            series: <number>;
          }>; // Данные паспорта
        phone: <string>; // Телефон
      }>; // Данные физического лица
    initial: <string>; // Вступительный взнос, который был внесён пайщиком
    minimum: <string>; // Минимальный паевый взнос, который был внесён пайщиком
    organization_data?: <null | {
        bank_account: {
          account_number: <string>; // Номер банковского счета
          bank_name: <string>; // Название банка
          card_number?: <null | string>; // Номер карты
          currency: <string>; // Валюта счета
          details: {
            bik: <string>; // БИК банка
            corr: <string>; // Корреспондентский счет
            kpp: <string>; // КПП банка
          };
        };
        city: <string>; // Город
        country: <string>; // Страна
        details: {
          inn: <string>;
          kpp: <string>;
          ogrn: <string>;
        };
        fact_address: <string>; // Фактический адрес
        full_address: <string>; // Полный адрес
        full_name: <string>; // Полное наименование организации
        phone: <string>; // Телефон
        represented_by: {
          based_on: <string>;
          first_name: <string>;
          last_name: <string>;
          middle_name: <string>;
          position: <string>;
        };
        short_name: <string>; // Краткое наименование организации
        type: <OrganizationType>; // Тип организации
      }>; // Данные организации
    referer?: <null | string>; // Имя аккаунта реферера
    spread_initial: <boolean>; // Флаг распределения вступительного взноса в невозвратный фонд вступительных взносов кооператива
    type: <AccountType>; // Тип аккаунта
  };
};

const { [Mutations.Participants.AddParticipant.name]: result } = await client.Mutation(
  Mutations.Participants.AddParticipant.mutation,
  { variables }
);

Результат:

interface IOutput {
  addParticipant: {
    blockchain_account?: {
      account_name: <string>; // Имя аккаунта
      core_liquid_balance?: <null | string>; // Баланс
      cpu_limit: {
        available: <string>; // Доступные ресурсы
        current_used?: <null | string>; // Текущее использование ресурсов
        last_usage_update_time?: <null | string>; // Время последнего обновления использования ресурсов
        max: <string>; // Максимальное количество ресурсов
        used: <string>; // Использовано ресурсов
      };
      cpu_weight: <string>; // Вес CPU
      created: <string>; // Дата создания
      head_block_num: <number>; // Номер последнего блока
      head_block_time: <string>; // Время последнего блока
      last_code_update: <string>; // Время последнего обновления кода
      net_limit: {
        available: <string>; // Доступные ресурсы
        current_used?: <null | string>; // Текущее использование ресурсов
        last_usage_update_time?: <null | string>; // Время последнего обновления использования ресурсов
        max: <string>; // Максимальное количество ресурсов
        used: <string>; // Использовано ресурсов
      };
      net_weight: <string>; // Вес сети
      permissions: <{
          parent: <string>; // Родительское разрешение
          perm_name: <string>; // Имя разрешения
          required_auth: {
            accounts: <{
                permission: {
                  actor: <string>; // Актор
                  permission: <string>; // Разрешение
                };
                weight: <number>; // Вес
              }[]>; // Уровни разрешений
            keys: <{
                key: <string>; // Ключ
                weight: <number>; // Вес
              }[]>; // Ключи
            threshold: <number>; // Порог
            waits: <{
                wait_sec: <number>; // Время ожидания в секундах
                weight: <number>; // Вес
              }[]>; // Вес ожидания
          };
        }[]>; // Разрешения
      privileged: <boolean>; // Флаг привилегий
      ram_quota: <number>; // Квота RAM
      ram_usage: <number>; // Использование RAM
      refund_request?: {
        cpu_amount: <string>; // Сумма CPU
        net_amount: <string>; // Сумма сети
        owner: <string>; // Владелец
        request_time: <string>; // Время запроса
      };
      rex_info?: <null | string>; // Информация о REX
      self_delegated_bandwidth?: {
        cpu_weight: <string>; // Вес CPU
        from: <string>; // Отправитель
        net_weight: <string>; // Вес сети
        to: <string>; // Получатель
      };
      total_resources?: {
        cpu_weight: <string>; // Вес CPU
        net_weight: <string>; // Вес сети
        owner: <string>; // Владелец
        ram_bytes: <number>; // Используемая RAM
      };
      voter_info?: <null | string>; // Информация о голосовании
    };
    participant_account?: {
      braname?: <null | string>; // Имя кооперативного участка
      created_at: <unknown>; // Время создания записи о члене
      has_vote: <boolean>; // LEGACY Флаг, имеет ли член право голоса
      is_initial: <boolean>; // LEGACY Флаг, внесен ли регистрационный взнос
      is_minimum: <boolean>; // LEGACY Флаг, внесен ли минимальный паевый взнос
      last_min_pay: <unknown>; // Время последнего минимального платежа
      last_update: <unknown>; // Время последнего обновления информации о члене
      status: <string>; // Статус члена кооператива (accepted | blocked)
      type?: <null | string>; // Тип участника (individual | entrepreneur | organization)
      username: <string>; // Уникальное имя члена кооператива
    };
    provider_account?: {
      email: <string>; // Электронная почта пользователя
      has_account: <boolean>; // Есть ли у пользователя аккаунт
      initial_order?: <null | string>; // ID начального заказа
      is_email_verified: <boolean>; // Подтверждена ли электронная почта
      is_registered: <boolean>; // Зарегистрирован ли пользователь
      message?: <null | string>; // Сообщение
      public_key: <string>; // Публичный ключ пользователя
      referer: <string>; // Реферер пользователя
      role: <string>; // Роль пользователя
      status: <UserStatus>; // Статус пользователя
      type: <string>; // Тип пользователя
      username: <string>; // Имя пользователя
    };
    user_account?: {
      meta: <string>; // Метаинформация
      referer: <string>; // Реферал
      registered_at: <string>; // Дата регистрации
      registrator: <string>; // Регистратор
      status: <string>; // Статус аккаунта
      storages: <string[]>; // Список хранилищ
      type: <string>; // Тип учетной записи
      username: <string>; // Имя аккаунта
      verifications: <{
          created_at: <string>; // Дата создания верификации
          is_verified: <boolean>; // Флаг верификации
          last_update: <string>; // Дата последнего обновления верификации
          notice: <string>; // Заметка верификации
          procedure: <string>; // Процедура верификации
          verificator: <string>; // Имя верификатора
        }[]>; // Дата регистрации
    };
    username: <string>; // Имя аккаунта кооператива
  };
}

В результате исполнения мутации, пайщик будет добавлен в кооператив, а ему на электронную почту выслано приглашение на получение приватного ключа доступа к системе. Воспользовавшись им, он сможет войти в систему.

Однако, для получения полной функциональности, ему необходимо предоставить 4 базовых подписанных соглашения, как это описано в разделе Соглашения. Без наличия подписанных соглашений, функционал платформы для него может быть ограничен.