Обзор
Страница "Кошелек" со стола пайщика отображает баланс лицевого счета пайщика по всем целевым потребительским программам и договорам, для которых у пайщика заведены кошельки.
Главный кошелек обеспечивает учёт взносов на лицевом счете пайщика по целевой потребительской програме "Цифровой Кошелек". Он же является центральным входом и выходом денег из цифрового кооператива для пайщиков, обеспечивая приём паевых взносов банковскими переводами и их возврат банковскими переводами.
Для участия в любых кооперативных приложениях на платформе пайщику необходимо сперва пополнить главный кошелек, потому как именно его баланс транслируется приложением по заявлению пайщика в кошелек договора участия в хозяйственной деятельности или кошелек целевой потребительской программы. Такие кошельки называются "кошельками проложений".
Возврат средств из кошельков приложений осуществляется в обратном порядке - трансляция в главный кошелек, и затем возврат паевого взноса банковским переводом по заявлению пайщика.
flowchart LR
contrib[Паевой взнос] --> main["Главный кошелек"]
refund[Возврат взноса] --> main
main <-->|трансляция| subgraph_apps["Кошельки приложений"]
subgraph_apps --> app1[Кошелек приложения A]
subgraph_apps --> app2[Кошелек приложения B]
subgraph_apps --> app3[Кошелек приложения C]

Главный кошелёк.¶
Является центральным входом и выходом паевых взносов из системы. Чтобы начать участвовать в любом кооперативном приложении (целевой потребительской программе), необходимо пополнить главный кошелек.

Принимая участие в любом приложении, где ожидаются взносы (например, стол заказов) - они взносы будут производиться с главному кошелька по цифровому заявлению на зачёт средств паевого взноса с одной целевой потребительской программы в счет средств другой.
Главный кошелек показывает два состояния паевых взносов по целевой потребительской программе "Цифровой Кошелек": доступные средства и заблокированные средства.
Доступные средства доступны к возврату или участию в любых кооперативных приложениях. Заблокированные средства в случае главного кошелька, это средства, которые недоступны к возврату прямо сейчас. Такими средствами является, например, минимальный паевой взнос который возвращается пайщику при выходе из кооператива. Также, средства переходят из доступного - в заблокированное на период оплаты возврата паевого взноса до момента фактической оплаты кассиром.
Кошельки приложений¶
Когда средства с главного кошелька пайщика по заявлению пайщика отправляются принимать участие в приложениях, то баланс средств в главном кошельке уменьшается, а баланс в кошельке приложения - увеличивается. Т.е. средства передается (транслируются) с главного кошелька - в кошелек конкретного приложения по заявлению пайщика.

Кошельки приложений связаны с целевыми потребительскими программами и/или договорами участия в хозяйственной деятельности, и открываются пайщику тогда, когда он подписывает соответствующий документ или публичную оферту в приложении. Приложение, например, "Благорост" или "Стол заказов" самостоятельно обеспечивают подпись необходимых соглашений и договоров, тем самым, открывая кошельки приложений пайщикам.
У кошельков приложений, аналогично главному кошельку, есть доступные и заблокированные средства паевых взносов. Доступные средства приложения могут быть использованы для трансляции в главный кошелек или задействованы внутри приложения согласно его бизнес-процессу.
Кошельками приложений управляют кооперативные смарт-контракты согласно принятым стандартам. Один смарт-контракт может управлять одновременно несколькими кошельками приложений согласно своей бизнес-логике. Например, смарт-контракт "Благорост" открывает пайщикам одновременно два кошелька приложений: по договору участия в хозяйственной деятельности и по условиям публичной оферты целевой потребительской программы.
Следует сказать, что смарт-контракты обычно автоматически возвращают средства из доступных средств кошелька приложения в главный кошелек по мере достижения условий завершения своего исполнения. Именно поэтому у кошельков приложений нет специализированных кнопок управления, вроде взносов и возвратов в и из кошельков приложений, т.к. все управление ими производится непосредственно на столах и страницах самих приложения. Здесь же, на странице кошелька пайщика, кошельки приложений представлены пайщику для мониторинга - где, сколько и в каком состоянии у него находится.
Микро-кошелек¶
Микро-кошелек отображает баланс главного кошелька и кнопки управления взносами в всегда доступном месте главного меню.

Находясь в любом приложении цифрового кооператива пайщику всегда доступен его баланс, которым он может принимать участие. При необходимости, он может как пополнить свой главный кошелек, совершив паевой взнос, так и запросить возврат паевого взноса, нажав соответствующие кнопки в микро-кошельке.
Разработчикам¶
Канонические имена полей и типов — в файле components/controller/schema.gql монорепозитория; интерактивно — в документации GraphQL-API.
Получить программный кошелёк¶
🛠️ SDK: Queries.Wallet.GetProgramWallet | Query.getProgramWallet
Получить один программный кошелек по фильтру Требуемые роли: chairman, member.
import { Queries } from '@coopenomics/sdk';
const variables: Queries.Wallet.GetProgramWallet.IInput = {
filter: {
coopname?: <null | string>; // Фильтр по имени кооператива
program_id?: <null | string>; // Фильтр по ID программы
program_type?: <null | ProgramType>; // Фильтр по типу программы
username?: <null | string>; // Фильтр по имени пользователя
};
options: {
limit: <number>; // Количество элементов на странице
page: <number>; // Номер страницы
sortBy?: <null | string>; // Ключ сортировки (например, "name")
sortOrder: <string>; // Направление сортировки ("ASC" или "DESC")
};
};
const { [Queries.Wallet.GetProgramWallet.name]: result } = await client.Query(
Queries.Wallet.GetProgramWallet.query,
{ variables }
);
Результат:
interface IOutput {
getProgramWallet?: <undefined | {
agreement_id: <unknown>; // Идентификатор соглашения
available: <string>; // Доступный баланс (формат: "100.0000 RUB")
blockNum?: <null | number>; // Номер блока последнего обновления
coopname: <string>; // Имя кооператива
id: <unknown>; // Уникальный идентификатор кошелька в блокчейне
membership_contribution: <string>; // Паевой взнос (формат: "100.0000 RUB")
program_id: <unknown>; // Идентификатор программы
program_type?: <null | ProgramType>; // Тип программы
username: <string>; // Имя пользователя
}>; // Получить один программный кошелек по фильтру
Требуемые роли: chairman, member.
}
Список программных кошельков¶
🛠️ SDK: Queries.Wallet.GetProgramWallets | Query.getProgramWallets
Получить список программных кошельков с фильтрацией и пагинацией Требуемые роли: chairman, member.
import { Queries } from '@coopenomics/sdk';
const variables: Queries.Wallet.GetProgramWallets.IInput = {
filter?: {
coopname?: <null | string>; // Фильтр по имени кооператива
program_id?: <null | string>; // Фильтр по ID программы
program_type?: <null | ProgramType>; // Фильтр по типу программы
username?: <null | string>; // Фильтр по имени пользователя
};
options?: {
limit: <number>; // Количество элементов на странице
page: <number>; // Номер страницы
sortBy?: <null | string>; // Ключ сортировки (например, "name")
sortOrder: <string>; // Направление сортировки ("ASC" или "DESC")
};
};
const { [Queries.Wallet.GetProgramWallets.name]: result } = await client.Query(
Queries.Wallet.GetProgramWallets.query,
{ variables }
);
Результат:
interface IOutput {
getProgramWallets: {
currentPage: <number>; // Текущая страница
items: <{
agreement_id: <unknown>; // Идентификатор соглашения
available: <string>; // Доступный баланс (формат: "100.0000 RUB")
blockNum?: <null | number>; // Номер блока последнего обновления
coopname: <string>; // Имя кооператива
id: <unknown>; // Уникальный идентификатор кошелька в блокчейне
membership_contribution: <string>; // Паевой взнос (формат: "100.0000 RUB")
program_id: <unknown>; // Идентификатор программы
program_type?: <null | ProgramType>; // Тип программы
username: <string>; // Имя пользователя
}[]>; // Элементы текущей страницы
totalCount: <number>; // Общее количество элементов
totalPages: <number>; // Общее количество страниц
};
}
Получить информацию об аккаунте¶
🛠️ SDK: Queries.Accounts.GetAccount | Query.getAccount
/** Получить сводную информацию о аккаунте Требуемые роли: chairman, member.
import { Queries } from '@coopenomics/sdk';
const variables: Queries.Accounts.GetAccount.IInput = {
data: {
username: <string>; // Имя аккаунта пользователя
};
};
const { [Queries.Accounts.GetAccount.name]: result } = await client.Query(
Queries.Accounts.GetAccount.query,
{ variables }
);
Результат:
interface IOutput {
getAccount: {
account_kind: <AccountKind>; // Вид аккаунта: пайщик, кооперативный участок, кооператив или нераспознанный. Позволяет единообразно отображать субъект во всех реестрах — например, пометить кооперативный участок, а не принять его за организацию-пайщика.
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>; // Информация о голосовании
};
has_password: <boolean>; // Установлен ли у аккаунта пароль входа. Пока пароль не установлен, действует вход по ключу доступа; после установки вход возможен только по email и паролю.
participant_account?: {
braname?: <null | string>; // Имя кооперативного участка
created_at: <unknown>; // Время создания записи о члене
has_vote: <boolean>; // LEGACY Флаг, имеет ли член право голоса
initial_amount?: <null | string>; // Сумма вступительного взноса
is_initial: <boolean>; // LEGACY Флаг, внесен ли регистрационный взнос
is_minimum: <boolean>; // LEGACY Флаг, внесен ли минимальный паевый взнос
last_min_pay: <unknown>; // Время последнего минимального платежа
last_update: <unknown>; // Время последнего обновления информации о члене
minimum_amount?: <null | string>; // Сумма минимального паевого взноса
status: <string>; // Статус члена кооператива (accepted | blocked)
type?: <null | string>; // Тип участника (individual | entrepreneur | organization)
username: <string>; // Уникальное имя члена кооператива
};
private_account?: {
entrepreneur_data?: {
birthdate: <string>; // Дата рождения
city: <string>; // Город
country: <string>; // Страна
details: {
inn: <string>; // ИНН
ogrn: <string>; // ОГРН
};
email: <string>; // Email
first_name: <string>; // Имя
full_address: <string>; // Юридический адрес
last_name: <string>; // Фамилия
middle_name: <string>; // Отчество
phone: <string>; // Телефон
username: <string>; // Имя аккаунта
};
individual_data?: {
birthdate: <string>; // Дата рождения
email: <string>; // Email
first_name: <string>; // Имя
full_address: <string>; // Полный адрес
last_name: <string>; // Фамилия
middle_name: <string>; // Отчество
passport?: {
code: <string>; // Код подразделения
issued_at: <string>; // Дата выдачи
issued_by: <string>; // Кем выдан
number: <number>; // Номер паспорта
series: <number>; // Серия паспорта
};
phone: <string>; // Телефон
username: <string>; // Имя аккаунта
};