Операції з гаманцями
Co-Signer
BroSettlement Co-Signer — це сервіс із відкритим кодом, який працює у вашій інфраструктурі, зберігає вашу MPC-частку ключа та бере участь у підписанні без відновлення повного приватного ключа.
Що робить Co-Signer
Co-Signer:
- опитує BroSettlement щодо нових DKG- і signing intents;
- автентифікує запити вашим Ed25519 API-ключем;
- отримує роботу через підписані HTTPS-запити;
- обмінюється MPC-повідомленнями через BroSettlement;
- зберігає основну частку B і відновлювальну частку C у зашифрованих локальних файлах;
- бере участь у підписанні транзакцій без відновлення повного приватного ключа;
- повідомляє BroSettlement фінальний результат.
Репозиторій: BroLabel/brosettlement-mpc-co-signer
Межа довіри
BroSettlement і ваш Co-Signer контролюють окремі MPC-матеріали для підписання. BroSettlement не може завершити MPC-підпис без участі Co-Signer під контролем клієнта.
Для звичайного підписання Co-Signer використовує частку B разом із часткою A BroSettlement. Частка C створюється під час DKG для аварійного відновлення і після активації не потрібна для A+B. У v2.2.0 вона спочатку потрапляє до окремого каталогу на тому самому сервері. Коли DKG остаточно завершено й ключ активовано, скопіюйте зашифрований артефакт C в окреме контрольоване сховище, перевірте цілісність копії та приберіть файл C із робочого сервера. Каталог CO_SIGNER_RECOVERY_SHARES_DIR, його налаштування й спільний ключ шифрування залиште: вони потрібні для майбутніх DKG. Для незавершеної DKG-операції C не переміщуйте — перевірка після перезапуску потребує обох артефактів.
Збережіть точні байти артефакту C, відповідну резервну копію B, початковий ключ шифрування та його ідентифікатор. Перевірте, що резервна копія або знімок робочого сервера не залишили на ньому C. Після перенесення на робочому сервері має залишитися тільки B. Відсутність файлу C для вже активованого ключа не заважає запуску Co-Signer і звичайному підписанню A+B, але без доступної резервної копії C аварійне відновлення B+C неможливе. Інструкція до тегу `v2.2.0` досі вимагає залишати обидва створені артефакти на сервері; її потрібно узгодити з цією вимогою до зберігання.
Co-Signer використовує pull model і сам ініціює вихідні HTTPS-з’єднання з BroSettlement. Відкривати локальний health port у публічний інтернет не потрібно.
Конфігурація
| Змінна | Обов’язкова | Опис |
|---|---|---|
CO_SIGNER_MONOLITH_URL | Так | Базова адреса API BroSettlement для робочого середовища: https://brosettlement-api.brolabel.io/. |
CO_SIGNER_API_KEY_ID | Так | UUID API-ключа, створеного для Co-Signer. |
CO_SIGNER_API_PRIVATE_KEY | Так | Приватний Ed25519-ключ клієнта у форматі PKCS#8 PEM, hex або Base64. |
CO_SIGNER_SHARE_ENCRYPTION_KEY | Так | Канонічний Base64 із заповненням для 32 випадкових байтів; шифрує файли MPC-часток. |
CO_SIGNER_SHARE_ENCRYPTION_KEY_ID | Так | Постійний ASCII-ідентифікатор ключа шифрування. |
CO_SIGNER_PRIMARY_SHARES_DIR | Так | Абсолютний шлях до наявного приватного каталогу основної частки B. |
CO_SIGNER_RECOVERY_SHARES_DIR | Так | Абсолютний шлях до наявного приватного каталогу відновлювальної частки C; не має перетинатися з основним. Залиште каталог і налаштування після перенесення артефакту C: вони потрібні для майбутніх DKG. |
CO_SIGNER_HTTP_ADDR | Ні | Адреса локального health server. Типово: 0.0.0.0:8081. |
CO_SIGNER_MAX_CONCURRENT | Ні | Максимальна кількість паралельних workers. Типово: 4. |
CO_SIGNER_POLL_MIN_INTERVAL | Ні | Мінімальний інтервал опитування intents. Типово: 2s. |
CO_SIGNER_POLL_MAX_INTERVAL | Ні | Максимальний інтервал опитування intents. Типово: 10s. |
CO_SIGNER_POLL_BACKOFF_FACTOR | Ні | Множник backoff для опитування. Типово: 1.5. |
CO_SIGNER_FRAME_POLL_INTERVAL | Ні | Інтервал опитування MPC-повідомлень. Типово: 500ms. |
CO_SIGNER_HTTP_TIMEOUT | Ні | Timeout запитів до BroSettlement API. Типово: 30s. |
CO_SIGNER_SHARES_DIR і CO_SIGNER_PARTY_ID більше не підтримуються та заважають запуску. Інші налаштування перевіряйте в README обраного випуску.
Робота з secrets
- Ніколи не додавайте
private.pem, ключ шифрування частки або каталог часток до Git. - Не передавайте secrets через аргументи командного рядка, query string, тікети або чати.
- Передавайте secrets під час запуску через secrets manager або захищені файли.
- Обмежте API-ключ необхідними дозволами й access settings зі сторінки API key.
- Прив’яжіть health endpoint до
127.0.0.1, якщо приватна мережа моніторингу не вимагає іншого. - Надайте доступ до обох каталогів часток лише користувачу операційної системи, який запускає Co-Signer.
- Вимкніть core dumps і не допускайте потрапляння secrets або вмісту часток у logs.
Постійне сховище та резервні копії
Під час DKG Co-Signer створює зашифровані MPC-матеріали в каталогах основної та відновлювальної часток. Файли зашифровані AES-256-GCM і створюються з обмеженими правами доступу. Після активації ключа перенесіть перевірений артефакт C в окреме сховище; каталог відновлення залиште.
Захищайте та резервуйте:
- основний каталог часток, каталог відновлення, журнал схвалень та їхній постійний батьківський каталог;
- точний артефакт C в окремому сховищі для відновлення та відповідну резервну копію B;
- відповідний ключ шифрування часток і його ідентифікатор;
- приватний Ed25519 API-ключ або задокументовану процедуру ротації API-ключа.
Зберігайте резервні копії зашифрованих часток і ключ шифрування в різних захищених місцях. Перевірте процедуру відновлення до того, як покладатися на неї. Файл частки неможливо використати без відповідного ключа шифрування.
Не прибирайте робочий файл C, доки його окрему копію не перевірено й DKG остаточно не завершено. Ніколи не змінюйте байти артефактів і не копіюйте частки між організаціями.
Запуск і моніторинг
Сервіс записує структуровані JSON logs у standard output. Надсилайте stdout і stderr у централізовану систему logs із належним редагуванням secrets і контролем доступу.
Контролюйте:
- доступність процесу;
- HTTP-статус
/health; - значення
ready; - версію сервісу;
- перевірку каталогу часток;
- статус і останній heartbeat Co-Signer у BroSettlement Console;
- помилки автентифікації, опитування, DKG і підписання.
Оновлення
Перед оновленням:
- створіть резервну копію зашифрованого каталогу часток;
- переконайтеся, що відповідний ключ шифрування доступний;
- прочитайте release notes;
- зберіть і протестуйте цільову версію;
- коректно зупиніть старий процес;
- запустіть нову версію з тим самим каталогом часток і secrets;
- перевірте локальний health і heartbeat у BroSettlement;
- виконайте testnet-перевірку підписання перед поверненням сервісу до робочого режиму.
Не запускайте два процеси Co-Signer для однієї організації та одного каталогу часток, якщо release documentation прямо не підтримує таку модель.
Усунення проблем
Co-Signer не запускається
Переконайтеся, що всі обов’язкові змінні задані, а також:
- приватний ключ є дійсним Ed25519-ключем;
- обидва каталоги часток існують і мають обмежений доступ;
- користувач сервісу може читати й записувати обидва каталоги;
- локальний health port вільний.
Локальний health повертає ready: false
Перевірте стан обох сховищ часток у відповіді health. Переконайтеся, що каталоги існують і користувач сервісу має до них доступ.
Console показує Co-Signer як offline
Перевірте:
CO_SIGNER_MONOLITH_URLвідповідає середовищу; для робочого середовища використовуєтьсяhttps://brosettlement-api.brolabel.io/;- API Key ID;
- відповідність приватного ключа завантаженому публічному ключу;
- наявність усіх трьох MPC-дозволів;
- завершені network і allowlist settings на сторінці API key;
- вихідний HTTPS-доступ;
- активність API-ключа та строк його дії.
MPC залишається not configured
Co-Signer у статусі Online не запускає MPC автоматично. Відкрийте Multi-Party Computation і явно натисніть Initialize MPC.
Ініціалізація MPC завершується помилкою
Не вимикайте Co-Signer і перевірте його JSON logs. Виправте помилки автентифікації, IP allowlist, з’єднання, версії або сховища. Повторюйте спробу лише після того, як попередня ініціалізація перейде у фінальний стан failed або expired.
Створення гаманця недоступне
Переконайтеся, що:
- MPC-ключ має статус Active або Ready;
- Co-Signer має статус Online;
- вибрана мережа має статус Ready;
- план організації дозволяє створити ще один гаманець.
Схвалення транзакцій у Co-Signer
Схвалення транзакцій підтримує стабільний Co-Signer v2.2.0. Використовуйте сумісну серверну версію BroSettlement й узгоджуйте оновлення перед увімкненням схвалень. Якщо оновлюєте наявну інсталяцію, перегляньте випуск Co-Signer `v2.2.0` та інструкцію з роботи зі схваленнями.
Оберіть режим схвалення
CO_SIGNER_APPROVAL_MODE | Поведінка |
|---|---|
external | Ваш сервіс через HTTPS вирішує, чи може кожен переказ продовжитися. Використовуйте для ручної перевірки або бізнес-правил. |
auto_approve | Co-Signer автоматично схвалює кожен новий запит. Сервіс схвалення не викликається. |
Типовий режим — auto_approve, зокрема коли змінну не задано. Якщо потрібна перевірка вашою командою, явно встановіть external. Перед зміною режиму перегляньте невирішені запити: перехід до автоматичного схвалення може схвалити раніше не оброблені запити. Для запиту, вже записаного в журнал схвалень Co-Signer, зберігаються початковий режим і адреса сервісу.
Як проходить схвалення
- Ваш застосунок створює переказ через BroSettlement API. BroSettlement резервує суму та максимальну мережеву комісію.
- Co-Signer отримує запит на схвалення. У режимі
externalвін передає точні параметри переказу вашому сервісу через HTTPS. - Поки триває перевірка, сервіс повертає
PENDING; потім —APPROVEDабоREJECTED. Co-Signer повторно перевіряє невирішені запити, тому зворотний виклик не потрібен. - Co-Signer зберігає остаточне рішення та передає його BroSettlement. MPC-підписання можливе лише після застосованого схвалення. Відхилення звільняє резерв.
- Окремо перевіряйте статус схвалення і виконання переказу. Схвалення ще не означає підтвердження транзакції в блокчейні.
Налаштуйте зовнішнє схвалення
Встановіть Co-Signer v2.2.0 за інструкцією зі встановлення. Використовуйте окремий API-ключ із дозволом mpc:raw. Зберігайте каталоги основної та відновлювальної часток на одному постійному томі зі спільним батьківським каталогом, доступним для запису. Під час першого запуску Co-Signer створює поряд журнал схвалень. Під час перезапусків, оновлень і резервного копіювання зберігайте весь том, ключ шифрування та його ідентифікатор. Не замінюйте втрачений журнал порожнім.
У захищеній конфігурації запуску Co-Signer задайте ці змінні. Замініть заповнювачі власними обліковими даними, а для наявної інсталяції збережіть початкові ключ шифрування та його ідентифікатор:
export CO_SIGNER_MONOLITH_URL="https://brosettlement-api.brolabel.io"
export CO_SIGNER_API_KEY_ID="<co-signer-api-key-id>"
export CO_SIGNER_API_PRIVATE_KEY="<Ed25519-private-key>"
export CO_SIGNER_PRIMARY_SHARES_DIR="/var/lib/co-signer/primary"
export CO_SIGNER_RECOVERY_SHARES_DIR="/var/lib/co-signer/recovery"
export CO_SIGNER_SHARE_ENCRYPTION_KEY="<base64-32-byte-key>"
export CO_SIGNER_SHARE_ENCRYPTION_KEY_ID="<stable-key-id>"
export CO_SIGNER_APPROVAL_MODE="external"
export CO_SIGNER_APPROVAL_ENDPOINT="https://<your-host>/transfer-approval"
export CO_SIGNER_APPROVAL_BEARER_TOKEN="<dedicated-approval-credential>"Базова адреса API не повинна містити /api/v1. Обидва каталоги часток мають існувати заздалегідь, мати обмежений доступ і не перетинатися. Значення CO_SIGNER_SHARE_ENCRYPTION_KEY має бути канонічним Base64 із заповненням для 32 випадкових байтів; зберігайте його разом із незмінним ідентифікатором ключа. Адреса сервісу схвалення має бути прямою HTTPS-адресою з чинним TLS-сертифікатом; переадресації не виконуються. Для сервісу схвалення використовуйте окремі облікові дані. Необов’язкова змінна CO_SIGNER_APPROVAL_JOURNAL_DIR перевизначає типовий шлях до журналу лише тоді, коли каталог уже існує та відповідає вимогам Co-Signer до сховища. Перед перевизначенням або відновленням журналу прочитайте інструкцію з роботи зі схваленнями.
Для автоматичного схвалення встановіть CO_SIGNER_APPROVAL_MODE="auto_approve". Адреса сервісу й токен у цьому режимі не використовуються, але журнал схвалень залишається обов’язковим. Не перемикайте режим, щоб обійти недоступність сервісу або помилку сховища.
Реалізуйте сервіс схвалення
Co-Signer надсилає HTTPS POST із заголовками Content-Type: application/json, Authorization: Bearer <dedicated-approval-credential> та Idempotency-Key: <requestId>:<authorizationHash>. Тіло JSON містить version (1), orgId, requestId, authorizationHash та authorization із параметрами переказу. Перевірте токен і відповідність orgId вашій організації. Пов’яжіть перевірку з ідентифікаторами організації, запиту та хешем параметрів; покажіть перевіряльнику збережені параметри.
У authorization перевіряйте clientReference, walletId, chain, fromAddress, toAddress, asset, amountAtomic, networkFeeAsset, maxNetworkFeeAtomic і transferKind. Для токенів також перевіряйте tokenStandard, tokenContractCanonical та tokenDecimals. Суми й комісії передаються як цілі числа в мінімальних одиницях активу.
Поверніть HTTP 200 рівно із сімома полями, скопіювавши перші чотири значення із запиту:
{
"version": 1,
"orgId": "<orgId from request>",
"requestId": "<requestId from request>",
"authorizationHash": "<authorizationHash from request>",
"status": "PENDING",
"reason": null,
"decisionReference": null
}Поки перевірка триває, швидко повертайте PENDING. Для схвалення поверніть status: "APPROVED" і reason: null. Для відхилення поверніть status: "REJECTED" і непорожню причину, наприклад {"code":"BUSINESS_LIMIT_EXCEEDED","text":"Transfer exceeds the approved limit."}. Код причини може містити великі латинські літери, цифри й підкреслення (до 64 символів); текст причини — до 512 байтів UTF-8. decisionReference може містити ідентифікатор перевірки у вашій системі або null; для PENDING він має бути null, в інших випадках його довжина обмежена 128 байтами UTF-8. Зберігайте остаточне рішення й повертайте той самий результат під час повторних запитів. Якщо той самий requestId надходить з іншим authorizationHash, з’ясуйте причину конфлікту замість повторного використання рішення.
Помилка HTTP, тайм-аут, недійсна відповідь або недоступний сервіс залишають переказ в очікуванні. Режим external ніколи не переходить до автоматичного схвалення. Запити в очікуванні не завершуються автоматично; кошти залишаються зарезервованими. Після прийняття остаточного рішення його не можна змінити наступною відповіддю сервісу.
Перевірте результат
Почніть із невеликого переказу в тестовій мережі. Створіть переказ через звичайний API-клієнт і збережіть його transaction ID та approval.requestId. Знайдіть запит у вашому сервісі схвалення, перевірте адресу отримувача, актив, суму й максимальну комісію та зафіксуйте рішення. Прочитайте GET /api/v1/transactions/{transactionId} і перевірте approval.status та execution.status:
| Статус | Значення |
|---|---|
approval.status=PENDING_APPROVAL | Очікується остаточне рішення. |
approval.status=APPROVED | Переказ схвалено; окремо перевірте виконання. |
approval.status=REJECTED | Переказ відхилено; перегляньте approval.rejectionReason. |
execution.status=CONFIRMED | BroSettlement підтвердив виконання. |
execution.status=BROADCAST_AMBIGUOUS | Результат відправлення в мережу невизначений; збережіть початковий transaction ID і з’ясуйте стан перед повторною спробою. |
До початку виконання можна надіслати POST /api/v1/transactions/{transactionId}/cancel із порожнім JSON-об’єктом. Скасування може збігтися з початком виконання; 409 APPROVAL_ALREADY_ACTIVATED означає, що цей endpoint уже не може зупинити переказ. Відхилення або успішне скасування звільняє зарезервовану суму й комісію. Підтримуйте Co-Signer і сервіс схвалення доступними та перевіряйте окремі перекази за їхнім статусом, а не лише за локальним health.
Для TRON Co-Signer покладається на BroSettlement у виборі мережі; Nile і Mainnet можуть використовувати ту саму адресу гаманця. Не надсилайте реальні кошти на тестові адреси та перевіряйте потрібну мережу перед поповненням або схваленням переказу. Докладніше — у описі межі довіри для мережі TRON.