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

Аккаунты

Аккаунт в MONO - это составной объект с информацией о пользователе. Он составляется из информации, которая описывает состояние пользователя на разных уровнях работы платформы с идентификацией по имени пользователя - username.

Username — это уникальный идентификатор пользователя в системе. Он состоит из 12 латинских букв без пробелов и специальных символов. С помощью него производится сквозная идентификация принадлежности аккаунта к пользователю во всех кооперативных системах платформы.

Объект аккаунта

У каждого аккаунта есть 4 уровня хранения информации, их удобно проследить по объекту Account в GraphQL-API:

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

UserAccount - объект пользователя кооперативной экономики содержит в блокчейне информацию о типе аккаунта пайщика, а также, обезличенные публичные данные (хэши) для верификации пайщиков между кооперативами. Этот уровень предназначен для хранения информации пайщика, которая необходима всем кооперативам, но не относится к какому-либо из них конкретно.

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

ProviderAccount - объект аккаунта в системе учёта провайдера, т.е. MONO. Здесь хранится приватная информация о пайщике кооператива, которая содержит его приватные данные. Эти данные не публикуются в блокчейне и не выходят за пределы базы данных провайдера. Они используются для заполнения шаблонов документов при нажатии соответствующих кнопок на платформе. Также, эта информация используется провайдером для организации входа пользователя в систему по наличию соответстветсвия между email и username в его базе данных и блокчейне (подробнее)

Зарегистрировать аккаунт

🛠️ SDK: Mutations.Accounts.RegisterAccount | 🔗 GraphQL API: Mutation.registerAccount

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

Успешный вызов мутации НЕ означает, что пользователь становится пайщиком и получает блокчейн-аккаунт. При вызове мутации пользователь получает только объект ProviderAccount, а для его перехода в пайщики необходимо пройти дополнительный путь, описанный в разделе Регистрация Пайщика.

Зарегистрировать аккаунт пользователя в системе

Регистрация аккаунта производится мутацией RegisterAccount, где в качестве переменных принимаются данные пользователя одного из трех типов, определяемых в перечислении AccountType: Individual (физическое лицо), Organization (юридическое лицо) или Entrepreneur (индивидуальный предприниматель).

При указании типа пользователя Individual необходимо передать объект individual_data с данными физлица, при регистрации Organization - ожидается обязательная передача organization_data, при указании типа Entrepreneur - entrepreneur_data.

Имя пользователя username и публичный ключ public_key генерируются вызовом метода generateAccount из SDK:

import {generateAccount} from '@coopenomics/sdk'

const account = generateAccount()

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

// console.log(account)
{
  name: "abcd1234wxyz",
  privateKey: "5JxyzABC1234567890defGHIJKLMNopqRSTUV",
  publicKey: "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5SozEZ8i8jUBS6yX79y6"
}

Используя сгенерированный объект аккаунта с ключами, проводим регистрацию в системе учёта провайдера:

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

const variables = {
  data: {
    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>; // Телефон
      }>; // Данные физического лица
    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>; // Тип организации
      }>; // Данные организации
    public_key?: <null | string>; // Публичный ключ
    referer?: <null | string>; // Имя аккаунта реферера
    role: <User>; // Роль пользователя
    type: <AccountType>; // Тип аккаунта
    username: <string>; // Имя пользователя
  };
};

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

По-умолчанию, каждый пайщик регистрирует новый аккаунт в том кооперативе, в который вступает. Кооператив, при этом, самостоятельно управляет процессом восстановления ключей доступа, в случае их утери.

Извлечь аккаунт

🛠️ SDK: Queries.Accounts.GetAccount | 🔗 GraphQL API: Query.getAccount

Запрос извлечения объекта аккаунта по username. Может быть выполнен председателем или членом совета на любой аккаунт, или пользователем, с собственным username. Если запрос совершает пользователь, то он должен предоставить свой username, который совпадёт с тем именем аккаунта, которое будет извлечено из JWT на бэкенде.

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

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

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

const { [Queries.Accounts.GetAccount.name]: result } = await client.Query(
  Queries.Accounts.GetAccount.query,
  { variables }
);

Извлечь лист аккаунтов

🛠️ SDK: Queries.Accounts.GetAccounts | 🔗 GraphQL API: Query.getAccounts

Получить сводную информацию о аккаунтах системы

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

const variables = {
  data?: {
    role?: <null | string>;
    username?: <null | string>;
  };
  options?: {
    limit: <number>; // Количество элементов на странице
    page: <number>; // Номер страницы
    sortBy?: <null | string>; // Ключ сортировки (например, "name")
    sortOrder: <string>; // Направление сортировки ("ASC" или "DESC")
  };
};

const { [Queries.Accounts.GetAccounts.name]: result } = await client.Query(
  Queries.Accounts.GetAccounts.query,
  { variables }
);

Результат будет представлен в виде объекта с массивом items, где каждый элемент массива - это составной объект аккаунта.

Обновить аккаунт

🛠️ SDK: Mutations.Accounts.UpdateAccount | 🔗 GraphQL API: Mutation.updateAccount

Обновить аккаунт в системе провайдера. Обновление аккаунта пользователя производится по username. Мутация позволяет изменить приватные данные пользователя, а также, адрес электронной почты в MONO. Использовать мутацию может только председатель совета.

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

const variables = {
  data: {
    email: <string>; // Электронная почта
    entrepreneur_data?: <null | {
        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>; // Телефон
      }>; // Данные физического лица
    organization_data?: <null | {
        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>; // Тип организации
      }>; // Данные организации
    public_key?: <null | string>; // Публичный ключ
    referer?: <null | string>; // Имя аккаунта реферера
    role: <User>; // Роль пользователя
    type: <AccountType>; // Тип аккаунта
    username: <string>; // Имя пользователя
  };
};

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

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

Восстановить доступ к аккаунту

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

Получить токен для замены

🛠️ SDK: Mutations.Accounts.StartResetKey | 🔗 GraphQL API: Mutation.startResetKey

Обновить аккаунт в системе провайдера. Обновление аккаунта пользователя производится по username. Мутация позволяет изменить приватные данные пользователя, а также, адрес электронной почты в MONO. Использовать мутацию может только председатель совета.

Заменить ключ

🛠️ SDK: Mutations.Accounts.ResetKey | 🔗 GraphQL API: Mutation.resetKey

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

import { Mutations } from '@coopenomics/sdk'

const variables: Mutations.Accounts.ResetKey.IInput = {
   data: {
     public_key: <новый_публичный_ключ>,
     token: <токен_из_письма>,
 }

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

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

Однако, в дальнейшем, при введении функционала "карты пайщика", которая сделает допустимым "быстрый вход" для пайщиков одного кооператива - в другой, система замены ключа будет требовать подтверждения нескольких кооперативов.
/** Заменить приватный ключ аккаунта