Аккаунты
Аккаунт в 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,
}
);
Метод производит замену ключа в блокчейне на переданный. На текущий момент здесь не используется каких-либо дополнительных децентрализованных сценариев проверки. Считаем, что если кооператив меняет ключ пайщика - значит ему так надо, т.к. обычно сейчас один пайщик с одним аккаунтом является членом только одного кооператива.
Однако, в дальнейшем, при введении функционала "карты пайщика", которая сделает допустимым "быстрый вход" для пайщиков одного кооператива - в другой, система замены ключа будет требовать подтверждения нескольких кооперативов.
/** Заменить приватный ключ аккаунта