13 октября команда TON Core опубликовала рекомендации для экосистемы по кошельку Telegram. Отдельным приложениям-кошелькам предложено новые кошельки по-прежнему создавать на контракте W5 (wallet-v5r1), потому что контракт кошелька Telegram, WalletTg, сделан под сам Telegram, но научиться открывать уже существующие кошельки Telegram по их секретной фразе. Это касается всех, кто хочет держать кошелёк Telegram ещё и в отдельном приложении: My Wallet и Gram Wallet такой импорт уже поддерживают, код для него появился в версии 26.10.0 от 6 октября.
Как открыть кошелёк Telegram в другом приложении
- Запишите адрес кошелька из Telegram. По нему вы потом сверите, тот ли кошелёк открылся.
- Возьмите текущую фразу. По документации в Telegram Desktop она лежит в меню кошелька: Keys & Backup → Show Recovery Phrase. Если ключ не меняли, слов 12. После смены ключа фраза становится из 24 слов, и вводить нужно все 24. Как хранить фразу, разобрано отдельно.
- Импортируйте фразу в My Wallet или Gram Wallet: Import Existing Wallet → Secret Words. Обе программы собраны из одного открытого кода, а в App Store и на wallet.ton.org сейчас стоит версия 26.10.4, в которой поддержка уже есть.
- Сверьте адрес. Совпал с адресом из Telegram — кошелёк открыт целиком, с балансом и историей. Не совпал — приложение открыло другой кошелёк на том же ключе, и причина обычно одна из трёх ниже.
С кошелька ещё ничего не отправляли. Контракт в TON появляется на адресе с первой исходящей транзакцией: до неё на адресе могут лежать монеты, но кода там нет. Приложение признаёт адрес кошельком Telegram, только если по нему уже работает контракт с кодом Telegram и нужным ключом. Для неразвёрнутого кошелька 12 слов откроют пустой кошелёк W5, а 24 слова закончатся ошибкой: приложение сообщит, что контракта кошелька Telegram по этому адресу нет. По логике кода выход в том, чтобы сначала отправить из Telegram хотя бы один перевод и после этого повторить импорт.
Ключ меняли, а введены первые 12 слов. После смены ключа первая половина фразы по-прежнему задаёт адрес, но подписывать уже не может. Приложение видит, что ключ в контракте другой, и показывает пустой кошелёк W5 вместо вашего. Нужны все 24 слова текущей фразы.
Фраза устарела. Если ключ меняли больше одного раза, а у вас записана предыдущая версия фразы, приложение ответит, что публичный ключ не совпадает с фразой и кошелёк, возможно, сменил ключ. Помогает только свежая фраза из Telegram.
Приложение, которое кошелёк Telegram не поддерживает, 12 слов чаще всего примет как обычную фразу BIP-39 и покажет кошелёк с другим адресом и нулевым балансом, а 24 слова из двух половин может не принять вовсе. Монеты при этом остаются на адресе Telegram: приложение просто не умеет считать этот адрес из фразы и подписывать переводы в формате WalletTg.
После импорта ключ живёт в двух местах. Telegram по умолчанию держит зашифрованную копию ключа, разделённую на три части в дата-центрах на трёх континентах, а теперь ключ лежит ещё и в приложении. Если цель — переехать на самостоятельное хранение, документация описывает выход: Keys & Backup → Disable Backup с отметкой Update Secret Phrase. Telegram сменит ключ подписи, покажет новую фразу из 24 слов и отключит облачную копию только после того, как смена прошла в сети. За смену ключа берётся комиссия в Gram. Адрес остаётся прежним, старая фраза перестаёт подписывать переводы, и в приложение после этого нужно заново ввести новые 24 слова.
Одна фраза, три адреса
Адрес кошелька в TON вычисляется не из ключа, а из хеша начального состояния контракта: кода и стартовых данных. Ключ входит в эти данные, но код у каждого типа кошелька свой. Поэтому один и тот же ключ даёт столько адресов, сколько существует типов контракта, и на каждом может лежать что-то своё.
Ключ из фразы кошелька Telegram выводится по общему стандарту BIP-39 с путём m/44'/607'/0', тем же, по которому My Wallet выводит ключ из своей фразы из 12 слов. Дальше пути расходятся. В начальном состоянии кошелька Telegram лежит код трамплина и четыре поля: номер ревизии хранилища, счётчик seqno, номер подкошелька 0x7FFF7F11 и открытый ключ. У W5 код другой и свой идентификатор кошелька.
Как это выглядит на деле, проверено на одноразовой фразе из 12 слов, сгенерированной для этой статьи: по алгоритму из документации получен один ключ и из него три адреса.
| Контракт | Адрес из одной фразы |
|---|---|
| WalletTg, кошелёк Telegram | UQAgG-WT…P_gXad |
| W5 (wallet-v5r1) | UQA7s7tH…boDdkIc |
| v4R2 | UQBVSR_U…djLee01 |
Какой из адресов покажет приложение, решает его код. My Wallet и Gram Wallet для фразы из 12 слов перебирают все известные им версии контракта, от самых старых до W5 и telegram, на двух первых индексах пути. Кошелёк Telegram попадает в этот список, только если по адресу работает контракт с трамплином, номер подкошелька равен 0x7FFF7F11, а ключ из get-метода get_public_key совпадает с ключом из фразы. Из найденного выбирается W5, если у него есть история; иначе адрес с наибольшим балансом; иначе адрес с последней транзакцией; если пусто везде — W5. Отсюда и пустой W5 в ловушках выше: когда кошелёк Telegram не прошёл проверку, его просто нет среди кандидатов.
Фраза из 24 слов идёт отдельной веткой. Если каждая половина по 12 слов проходит проверку BIP-39, первая половина даёт ключ-якорь и из него адрес, а вторая — ключ подписи, который сверяется с ключом в контракте. Нужна эта ветка потому, что 24 слова бывают и у старых кошельков TON, выведенных по собственным правилам сети. Документация велит в спорном случае показать пользователю оба кандидата и не выбирать молча; My Wallet сначала пробует ветку Telegram и, если контракта Telegram по адресу нет, а фраза годится как обычная, импортирует её как обычную.
Как кошелёк Telegram меняет ключ, не меняя адрес
В хранилище контракта WalletTg ключ подписи — изменяемое поле, а адрес навсегда вычислен из начального состояния, где стоял первый ключ, ключ-якорь. Смена ключа — это запрос, подписанный текущим ключом, с доказательством, подписанным новым. Контракт перезаписывает поле, и get-метод get_public_key с этого момента возвращает новый ключ. Ключ-якорь по-прежнему нужен, чтобы пересчитать адрес, но подписывать уже не может. Чтобы зашифрованные комментарии, полученные до смены ключа, оставались читаемыми, контракт публикует при каждой смене прежний закрытый ключ, зашифрованный новым: по цепочке таких событий приложение восстанавливает все предыдущие ключи, имея на руках только текущий.
Почему новые кошельки остаются на W5
Обоснование в рекомендации TON Core одно: WalletTg сделан специально для Telegram. Устройство контракта показывает, что за этим стоит.
Код кошелька общий и меняется голосованием. На каждом адресе кошелька Telegram лежит неизменяемый трамплин, который передаёт управление коду из параметра −123 конфигурации сети. Новую версию этого кода утверждают валидаторы, по документации нужно больше 75% их суммарного веса, и она достаётся всем кошелькам Telegram сразу. Владелец кошелька не может закрепить версию или отказаться от обновления. Код W5 лежит в каждом аккаунте свой и не меняется.
Расширений нет. W5 поддерживает расширения: отдельные контракты, которым кошелёк разрешает действовать от своего имени, на них строятся подписки и дополнительные проверки. Двухфакторное подтверждение в самом My Wallet ищется именно как расширение кошелька W5. В WalletTg расширений нет, по замыслу авторов двухфакторка и подписки появятся в нём встроенными функциями.
Формат запросов свой. Подпись в WalletTg стоит перед телом запроса, у отправки одного сообщения отдельный короткий формат, а для оплаты комиссии за пользователя запрос передаётся через посредника, который прикладывает Gram на исполнение. Приложению, которое хочет не только показывать баланс кошелька Telegram, но и отправлять с него, приходится реализовать этот формат отдельно от W5.
Главное, ради чего WalletTg устроен иначе, — смена ключа без смены адреса. В описании контракта сказано прямо: Telegram создаёт кошелёк, но позволяет перейти на самостоятельное хранение. Импорт в сторонние приложения и есть вторая половина этого перехода.
Что рекомендовано остальным
Приложениям с входом через кошелёк TON Core советует обновить TON Connect и проверять подпись ton_proof так, как требует спецификация: ключ кошелька Telegram берётся из сети, а не из начального состояния. Эта часть разобрана в материале про TON Connect 5.0.
Обозревателям блокчейна предложено распознавать кошельки Telegram, показывать смену ключа и помечать переводы, комиссию за которые заплатил не владелец. API Toncenter научился различать контракт кошелька Telegram и отдаёт смену ключа отдельным действием с новым ключом и зашифрованным старым, а tonscan.org на этих данных уже подписывает кошельки Telegram и переводы с пометкой «Fee paid by Telegram».




