Как это работает
Оператор создаёт инвойс
Вызов createInvoice фиксирует параметры (token, amount, coldWallet) и возвращает predictedPayment — адрес для оплаты.
Плательщик отправляет средства
ETH или ERC‑20 переводятся на predictedPayment. Approve не требуется — достаточно обычного transfer() на этот адрес.
Свип на холодный кошелёк
Оператор вызывает createAndSweep. Контракт разворачивает Vault ровно на paid‑адрес и переводит всё на coldWallet.
Комиссии (on‑chain)
Регистрация оператора
Единовременная комиссия, взимается вызовом registerOperator().
Текущие значения читаются из контракта: getOperatorRegistrationCommission()
Создание инвойса
Небольшая комиссия за каждый счёт — при вызове createInvoice().
Текущие значения: getCreateInvoiceCommission()
Сетевые комиссии
Газ за транзакции оплачивает вызывающая сторона. Для свипа оператор дополнительно газа не платит сверх обычной tx‑стоимости.
Почему это удобно
Без сервера
Не нужно генерировать и хранить ключи под каждый адрес. Адрес оплаты вычисляется on‑chain.
Холодное хранение
Свип идёт сразу на coldWallet оператора. Минимум ончейн‑следа и рисков.
ETH и ERC‑20
Поддержка нативного ETH и стандартных токенов без approve.
Прозрачные комиссии
Все комиссии и события фиксируются в смарт‑контракте.
Для разработчиков
Адрес контракта
0x6ab185d9068b15e14103c90ef22082e0fcb5495e
Сеть: Sepolia
(пример). RPC: https://sepolia.infura.io/v3/<API_KEY>
События
InvoiceCreated(invId, operator, token, amount, coldWallet, salt, predictedPayment)
InvoiceSwept(invId, operator, token, sweptAmount, coldWallet, vault)
InvoiceCanceled(invId, operator)
OperatorRegistered(operator, feePaid)
FAQ
Нужен ли approve для ERC‑20?
Нет. Плательщик отправляет токены напрямую на predictedPayment. После деплоя Vault выступает владельцем этого адреса и переводит весь баланс на coldWallet.
Можно ли вернуть платёж?
Ончейн — нет. Возврат возможен только оффчейн со стороны оператора после получения средств на coldWallet.
Все ли ERC‑20 поддержаны?
Стандартные — да. Токены с налогами/блокировками могут повлиять на итоговую сумму, используйте minAmount
.