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

Transfer policy

Transfer policy определяет, как обрабатывать исходящие транзакции (withdrawal) ещё до того, как они уходят в блокчейн. Это центральный элемент управления рисками: на этой стадии решается, кому, куда, сколько и при каких условиях разрешено выводить средства.

Когда применяется

Проверка Transfer policy — третья стадия обработки исходящей транзакции: после базовых валидаций (баланс, fee, активность vault) и AML Screening, но до того, как транзакция уходит на подписание и в блокчейн. В этой точке решение политики — последний барьер перед началом подписания.

Action — что делает правило

Action Что произойдёт с транзакцией
ALLOW Транзакция проходит автоматически, без аппрува. Если правило указывает подписантов — они будут назначены этой транзакции.
REQUEST_APPROVAL Транзакция переходит в статус awaiting_approvals. Указанным аппруверам уходит push/WS-уведомление; решение принимается по правилам апрува.
BLOCK Транзакция получает терминальный статус blocked_by_policy и больше никак не двинется — для повторной попытки клиент должен создать новую.

Структура правила

Правило состоит из четырёх логических блоков:

WHO  →  Initiator (кто инициировал транзакцию)
FROM →  Source    (откуда выводим)
TO   →  Destination (куда выводим)
WHAT →  Asset + Limitation (какой актив и в каких пределах)

Все блоки соединяются логическим И: правило срабатывает, только если совпадают все указанные условия. Дополнительно для ALLOW и REQUEST_APPROVAL правило описывает, кто будет подписывать (Signer) и кто должен подтвердить (Approval).

Initiator — инициатор транзакции

Кто запустил withdrawal: пользователь или сервисный аккаунт.

Поле Описание
any_initiator true — правило срабатывает для любого инициатора. Удобно для широких разрешающих/блокирующих правил.
initiators Карта uuid → type. Конкретный список инициаторов; typeUSER или SERVICE_ACCOUNT. Если запросивший подходит и его тип совпадает — матч.

Зачем разделять User и Service Account

Часто полезно разрешать сервисным аккаунтам только мелкие автоматические выводы (например, выплаты пользователям до 100 USD), а крупные операции отдавать пользователям с обязательным аппрувом. Это делается двумя правилами с разными initiators.

Source — откуда списываем

Источник средств для исходящей транзакции — всегда один из vault workspace.

Поле Описание
any_source true — любой vault workspace.
vault.any_vault true — любой vault (эквивалент any_source).
vault.vault_uuids Конкретный список vault, к которым применимо правило.
whitelisted.* Зарезервировано — реальные исходящие транзакции всегда идут из vault, но поле есть для симметрии с Destination.

Destination — куда отправляем

Назначение бывает нескольких типов: внутренний vault (перевод между vault workspace), whitelisted-кошелёк (адрес из белого списка) или one-time address (свободно введённый адрес).

Поле Описание
any_destination true — любое назначение. Самое широкое условие; используйте в дефолтных правилах.
one_time_addresses_only true — правило срабатывает только для свободно введённых адресов. Хороший крючок для требования аппрува на любые «новые» адреса.
vault.any_vault / vault.vault_uuids Перевод во внутренний vault: любой или конкретный.
whitelisted.any_whitelisted_address Любой адрес из whitelist workspace.
whitelisted.any_whitelisted_internal_address Любой whitelisted внутренний адрес.
whitelisted.any_whitelisted_external_address Любой whitelisted внешний адрес.
whitelisted.any_whitelisted_contract_address Любой whitelisted адрес смарт-контракта.
whitelisted.whitelisted_external_addresses Конкретный список внешних адресов.
whitelisted.whitelisted_internal_addresses Конкретный список внутренних.
whitelisted.whitelisted_contract_addresses Конкретный список контрактных.

One-time addresses

Включите one_time_addresses_only в правило с REQUEST_APPROVAL — это самый простой способ гарантировать, что любая транзакция на «новый» адрес проходит через ручное подтверждение.

Asset — какой актив и какой порог

Описывает актив и порог суммы, при превышении которого правило активируется.

Поле Описание
any_asset true — правило действует для любого актива. В этом режиме сумма всегда сравнивается в USD-эквиваленте.
asset_id Конкретный актив (например, BTC, ETH, USDT-TRC20).
amount Пороговое значение (decimal-строка). Правило матчится, если сумма транзакции ≥ amount. Для дефолтных правил укажите 0 — тогда правило применяется к любым суммам.
currency USD — сравнивать в USD-эквиваленте; NATIVE — в единицах самого актива (например, в BTC). При any_asset = true всегда используется USD.

Семантика порога

Условие — «сумма больше или равна порогу». Чтобы правило срабатывало для всех сумм, поставьте amount = 0. Чтобы разделить «мелкие» и «крупные» переводы, заведите два правила: одно с amount = 1000 (например, требует аппрув от 1000 USD), второе ниже по списку с amount = 0 (мелкие — auto-allow).

Signer — кто подпишет

Применимо для ALLOW и REQUEST_APPROVAL.

Поле Описание
signer_uuids Конкретный список подписантов, которым будет назначена транзакция.
is_initiator_signer true — подписывает сам инициатор (если у него есть право SIGN_TRANSACTION и привязанное устройство).

Approval — кто и как должен подтвердить

Применимо только для REQUEST_APPROVAL. Описывает, какие именно подписи аппруверов нужны, чтобы транзакция была одобрена.

Поле Описание
initiator_can_approve true — инициатор может сам выступить в роли одного из аппруверов. По умолчанию false, чтобы избежать «само-аппрува».
users_sets Карта именованных наборов аппруверов. Каждый набор — { user_uuids, threshold }. Имя набора (A, B, …) используется в expression.
expression Логическое выражение, описывающее, какие наборы должны выполниться. Поддерживает &&, \|\|, (…) и имена наборов. Примеры: A, A && B, (A && B) \|\| C.

Внутри одного набора threshold задаёт минимальное число подписей. Например, набор A со списком из 5 финансистов и threshold = 2 требует подписи любых двух из них. Если выражение (A && B) || C, транзакция проходит, если выполнен набор C целиком или оба набора A и B.

Имена наборов

По умолчанию один безымянный набор называется A (DefaultApprovalSetName = "A"). При работе через UI имена обычно проставляются автоматически.

Limitation — лимит на сумму

Описывает, как считается порог суммы из блока Asset: по одной транзакции или накопительно за окно времени.

SINGLE_TX (по одной транзакции)

Самый простой вариант. Правило срабатывает, если сумма текущей транзакции ≥ asset.amount. Историю предыдущих транзакций не учитывает.

TIMEFRAME (накопительный лимит за окно)

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

Поля *_mode определяют, как именно агрегируются суммы:

Поле Значения Что означает
hours положительное число Размер окна в часах (sliding window). Максимум — 15 дней (360 часов).
initiator_mode PER_INITIATOR Считать отдельно для каждого инициатора. У каждого пользователя/SA — свой счётчик.
ACCUMULATED_INITIATORS Один общий счётчик на всех инициаторов вместе.
source_mode PER_SOURCE Отдельный счётчик для каждого vault-источника.
ACCUMULATED_SOURCES Общий счётчик по всем источникам.
destination_mode PER_DESTINATION Отдельный счётчик для каждого получателя.
ACCUMULATED_DESTINATIONS Общий счётчик по всем получателям.

Примеры

  • «Каждый сотрудник — не более 10 000 USD в сутки»: hours = 24, initiator_mode = PER_INITIATOR, source_mode = ACCUMULATED_SOURCES, destination_mode = ACCUMULATED_DESTINATIONS, amount = 10000, currency = USD.
  • «Со всех vault'ов не больше 1 BTC в час суммарно»: hours = 1, все *_mode = ACCUMULATED_*, asset_id = BTC, amount = 1, currency = NATIVE.

Резервирование лимита

Когда транзакция входит в awaiting_approvals, её сумма резервируется в счётчике и блокирует дальнейшие переводы до достижения порога. Если транзакция позже отклонится (declined/expired/failed), резерв автоматически освобождается и счётчик уменьшается.

Поведение по умолчанию

При первом обращении к политике в workspace создаются два правила:

  1. Default allow (position 1) — ALLOW, any_initiator, any_source, any_destination, any_asset, amount=0, is_initiator_signer=true. Разрешает любые транзакции с подписанием инициатором.
  2. Default block (position 2) — BLOCK, помечен как global, не редактируется. Срабатывает, если ни одно пользовательское правило не подошло (страховка от «дыр»).

Если политика отсутствует или деактивирована — все транзакции автоматически одобряются системой с пометкой no active transfer policy, transaction automatically approved.

Не оставляйте default allow в проде

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

Типовые сценарии

1. Whitelist-only режим

Разрешить переводы только на адреса из white-list, всё остальное — блокировать.

# Action Destination Asset Limitation
1 ALLOW whitelisted.any_whitelisted_address any_asset, 0 USD SINGLE_TX
2 BLOCK any_destination any_asset, 0 USD SINGLE_TX
2. Двойной контроль для крупных сумм

Мелкие — авто-разрешать, крупные — два аппрува, очень крупные — блокировать.

# Action Asset.amount/currency Approval
1 BLOCK 100000 USD
2 REQUEST_APPROVAL 1000 USD A && B (директор и финансист)
3 ALLOW 0 USD
3. Любой новый адрес — через подтверждение
# Action Destination Approval
1 REQUEST_APPROVAL one_time_addresses_only = true A (любой из админов)
2 ALLOW any_destination
4. Дневной лимит на сотрудника
# Action Initiator Limitation
1 BLOCK any_initiator TIMEFRAME 24h, PER_INITIATOR, accumulated by src/dst, amount=10000 USD
2 ALLOW any_initiator SINGLE_TX, 0