Своя страница подписи
Vela разбирает каждую транзакцию до того, как вы её подтвердите, и это настоящая работа — но делает её то же приложение, которое эту транзакцию и собрало. Если приложение или путь, которым оно до вас доходит, подменили, оно может показать одно, а подписать другое. Именно это произошло с Bybit.
Страница подписи существует, чтобы разделить это надвое: транзакция приходит из одного места, а проверка и подпись происходят в другом, которым управляете вы.
Что это такое
Одна папка — app-web/clearsigning в репозитории — которая одновременно и
веб-страница, и расширение Chrome. Чистые HTML, CSS и JavaScript: ни фреймворка, ни
сборщика, ни шага сборки, ни зависимостей и ни одного собственного сетевого
запроса.
Получив запрос на подпись, она не верит присланной вместе с ним сводке. Она сама разбирает сырую calldata, сама считает дайджест, показывает, что подпись на самом деле разрешит, и только затем просит ваш passkey.
Поскольку шага сборки нет, файлы, которые вы читаете, — это и есть файлы, которые выполняются. Папку можно сравнить с репозиторием и точно знать, что вы раздаёте.
Какая копия может подписывать за ваш кошелёк
Passkey привязан к домену, на котором он создан. Ваши ключи Vela зарегистрированы
под getvela.app, и браузер предложит их только странице, чья relying party — getvela.app. Это единственное правило и решает, какой способ запустить свою копию
вам подходит.
Как расширение Chrome — именно этот вариант работает с вашим текущим кошельком. Relying party расширения — getvela.app, откуда бы ни взялась папка, поэтому ваши
существующие ключи могут в нём подписывать, а исполняется тот самый код из папки,
которую вы загрузили и осмотрели.
- Откройте
chrome://extensionsи включите режим разработчика. - Загрузить распакованное расширение и выберите папку
app-web/clearsigning. - Иконка на панели откроет страницу во вкладке.
Как страница на вашем домене или на localhost. При раздаче по HTTP(S) relying
party страницы — её собственное имя хоста, то есть подписывать она может ключами,
зарегистрированными под этим хостом, а не ключами под getvela.app. Это
правильный способ прогнать всю церемонию целиком, отработать десктопный сценарий и
подписать за кошелёк, ключ которого создан на вашем домене. Но не способ подписать
за уже существующий кошелёк getvela.app.
cd app-web/clearsigning
python3 -m http.server 8080 # → http://localhost:8080 Все пути в приложении относительные, поэтому подкаталог на существующем хосте тоже
работает; открыть index.html прямо с диска (file://) годится, чтобы осмотреться,
— без origin нет relying party, и подписать ничего нельзя.
Что она делает до подписи
- Сама разбирает транзакцию. Что делает вызов, кому и на какую сумму — из calldata, включая вложенные вызовы внутри пакета.
- Подписывает только тот дайджест, который вычислила сама. Дайджесты EIP-191,
EIP-712, SafeOp и SafeMessage считаются прямо на странице и сверяются с
vela-core— тем же кодом, что использует кошелёк. Дайджест, который посчитать не удалось, — это отказ, а не подпись. - Проверяет, что транзакция та самая, которую запросили. Вызов, о котором просил сайт, должен действительно находиться внутри подписываемой операции.
- Отказывает в неограниченном разрешении. Не предупреждение — отказ, с указанием, что делать вместо этого.
- Говорит, когда чего-то не может прочитать, вместо дружелюбной сводки, за которую не может отвечать.
- Показывает адрес и идентикон аккаунта и не показывает имя получателя, присланное тем, кто просит подпись. Всё, чем управляет запрашивающая сторона, либо убирается, либо помечается как её слова.
Чего у неё намеренно нет
- Никаких редакторов. Запрос фиксируется в момент прихода: вы его либо подписываете, либо нет. Выбор комиссии или редактор лимита переписали бы calldata, а это ровно та болезнь, ради которой страница и существует.
- Никакого создания ключей. Страница подписи не может создать passkey. Создать его — значит создать другой аккаунт.
- Никаких сетевых запросов. Если нечего запрашивать, нечего и перехватывать.
Как до неё доходит запрос
| Кто запрашивает | Канал |
|---|---|
| Страница в том же браузере | postMessage |
| Страница того же браузера — расширению | Порт расширения |
| Десктопное приложение на той же машине | Фрагмент URL + колбэк на loopback |
| Телефон или другой компьютер | Bluetooth LE (протокол реализован; радио на настоящем железе ещё не проверено) |
Формат обмена, дайджесты и таблица, откуда берётся каждый элемент на экране, лежат
в PROTOCOL.md рядом с кодом.
Когда ею пользоваться
С того дня, когда на аккаунте появляются деньги, потерять которые было бы неприятно, — и дальше, для каждой подписи. Не только для крупных сумм: маленькое разрешение может отдать достаточно, чтобы опустошить аккаунт. Привычка подписывать «по особым случаям» не работает в тот день, когда она нужна.