TMA Wallet — некастодиальный MPC воллет для вашего Telegram Mini App

в 14:56, , рубрики: crypto, telegram mini app, tma wallet, некастодиальный кошелёк

Всем привет! Думаю, все уже знают, что в телеге уже год как бум мини-аппов, все тапали хомяка. Подавляющее большинство из них связаны с криптой. Многие хотят внутри приложения давать своим пользователям кошелёк (EVM, TON или Solana, etc.), как некий виртуальный счёт, который можно пополнить, выводить средства, и, самое главное, дергать смарт-контракты.

Простое и небезопасное решение - хранить все ключи на серваке, выполнять транзакции от имени юзера. Взлом вашего сервера = потеря всех клиентских средств, добиться доверия в этом случае очень сложно.

Сложное и неудобное решение - кошелёк, который юзер должен записать на бумажке и следить за его безопасностью сам. В этом случае, вам лучше вообще использовать WalletConnect или не делать миниапп вообще. Правда, в этом случае UI миниаппа превращается в ад, где юзер должен подтверждать каждое действие во внешнем приложении.

Мы искали для нашего миниаппа вариант, который бы давал безопасность некастодиального кошелька, но с максимально гладким UX/UI. И нашли.

В этой статье я хочу сделать обзор TMA Wallet (npm-пакет, сайт, github) - opensource некастодиального multi-party кошелька, подходящего для любых чейнов, работающего на базе недавно появившееся API Telegram Cloud Storage.

Поехали!

Очень краткое объяснение терминов

Кошелёк = приватный ключ. Этот приватный ключ используется для подписи транзакций и даёт тому, кто им владеет, право распоряжаться средствами на конкретном блокчейн-адресе.

Кастодиальный кошелёк = вашим приватным ключом владеет другая организация и выполняет действия от вашего имени. Классический пример - криптобиржи, аля Binance. Это удобно, но требует большого доверия к организации.

Некастодиальный кошелёк = ваш приватный ключ только у вас. Он хранится на вашем устройстве, и все действия со средствами выполняются либо напрямую вами, либо с вашего подтверждения. Главная проблема некастодиальных кошельков - их легко потерять. Утратил доступ к приватному ключу - прощайте, средства.

MPC (multi-party-computation) - попытка решить проблему утери кошелька: разбить ключ на несколько частей, каждая из которых хранится у разных контрагентов, и они все требуются для формирования подписи транзакции. В этом сценарии взлом одного из контрагентов не даёт доступа к средствам клиента. При этом клиенту не надо переживать за хранение ключа самостоятельно.

Поэтому, некастодиальный MPC-кошелёк - это как раз кошелёк, части приватного ключа которого хранятся в разных местах, и никогда не собираются вместе у какого-либо из контрагентов.

Что вообще такое TMA Wallet?

TMA Wallet - это некастодиальный multi-party (MPC) кошелёк, который использует новые возможности Telegram Cloud Storage для безопасного хранения ключей. Всё это завязано на Telegram-аккаунт пользователя и не требует от человека запоминать какие-то seed-фразы или заводить внешние кошельки. Флоу настолько плавный, что ваш пользователь может даже не знать, что под капотом используется крипто-кошелёк - можно сделать совершенно человеческий UI, изолировав от пользователя блокчейн-магию.

Какие конкретные плюсы я бы выделил:

  • Лёгкая интеграция: просто ставишь npm-пакет, прицепляешь его к своему коду - и всё, у каждого юзера вашего мини-аппа теперь есть кошелёк.

  • Никаких костылей с TON Connect, WalletConnect: пользователь остаётся целиком в Telegram, и все транзакции подписываются "под капотом".

  • MPC-технология: приватный ключ не доступен никому — ни Telegram, ни вашему серверу, ни серверам TMA Wallet. Он воссоздаётся на устройстве пользователя, держится в памяти считаные наносекунды (на время транзакции) и исчезает.

  • Удобное восстановление: потерял телефон - без проблем, бери новый, заходи в Telegram, и кошелёк восстановится автоматически.

  • Доступ с разных устройств: если юзер зашёл в миниапп с десктопа с тем же аккаунтом - он получит доступ к тому же воллету, что и на телефоне.

  • Открытый исходный код: всё лежит на GitHub, можно проверить и убедиться в безопасности, либо самостоятельно провести аудит.

  • Поддержка Viem/Wagmi/Ethers.js: если вы пишете под любой EVM-совместимый блокчейн (Ethereum, BSC, Polygon и т.д.), то сможете использовать стандартные либы.

  • Поддержа любых чейнов: из коробки поддерживаются EVM-чейны, но сама суть TMA Wallet - это просто раздельное хранение некоего секрета, так что в качестве секрета может выступать приватник от любого чейна (TON/Solana/etc).

Как это устроено «под капотом»?

Как я уже раза три написал - TMA Wallet основан на принципах Multi-Party Computation (MPC), где приватник, по сути, распределён между несколькими сторонами и собирается только на клиенте, на мгновение при транзакции. Вот краткая схема:

  1. При первом запуске мини-аппа у пользователя на устройстве генерируются ClientPublicKey и ClientSecretKey. ClientSecretKey сохраняется в Telegram Cloud Storage.

  2. ClientPublicKey и WebApp.initData (подписанная Telegram'ом авторизационная строка) летят на сервер.

  3. Сервер проверяет валидность подписи от Telegram и (при желании) запрашивает у пользователя дополнительный фактор аутентификации (2FA). Можно и без него, как у нас.

  4. Сервер генерирует так называемый IntermediaryKey, подписав (ClientPublicKey + telegramUserId) своим ServerSecretKey. Этот IntermediaryKey шифруется перед отправкой на клиент.

  5. IntermediaryKey возвращается обратно на клиент и расшифровывается там.

  6. На финальном шаге IntermediaryKey подписывается ClientSecretKey и превращается в WalletPrivateKey (собственно, приватный ключ от воллета).

Этот ключ используется для подписи транзакции, при этом нигде не сохраняется, для каждого нового действия вся цепочка выше (кроме 1 пункта) повторяется.

В итоге мы имеем приложение, которое (по UX) выглядит идеально: логин бесшовный благодаря авто-авторизации в миниаппах, а транзакции бесшовные, потому что используется собственный in-app кошелёк.

Как добавить в свой миниапп?

  1. Установите SDK в проект:

    npm install --save @tmawallet/sdk
  2. Добавьте в код инициализацию ключа:

    import { TMAWalletClient } from '@tmawallet/sdk';
    import { ethers } from 'ethers';
    
    // не забудьте зарегаться на dash.tmawallet.com
    const myApiKey = '1234567812345678'; // API-ключ из dash.tmawallet.com
    const client = new TMAWalletClient(myApiKey);
    
    // Авторизуем пользователя и создаём/загружаем для него кошелёк
    await client.authenticate();
    
    console.log('Your wallet address: ', client.walletAddress);
  3. Пример, как сделать транзакцию (в данном случае через Ethers.js):

    // Используем TMA Wallet как "signer" для ethers
    const provider = new ethers.JsonRpcProvider();
    const signer = client.getEthersSigner(provider);
    
    const tx = await signer.sendTransaction({
      to: '0x...',
      value: ethers.parseEther('1.0'),
    });
    console.log('Transaction hash:', tx.hash);

    Вуаля.

FAQ

Перевёл вопросы (с легкой редактурой), ответы на которые TMA Wallet написали в своем README:

  1. Это точно безопасно?

    Да, и это принципиально: благодаря MPC-протоколу ни серверы TMA Wallet, ни Telegram, ни вы не имеете полного доступа к приватному ключу. Только юзер.

  2. Мне надо давать вам доступ к токену моего бота?

    Нет, мы одни из первых кто поддерживает новую асимметричную схему подписи Telegram. Нам нужен только ID вашего бота, он итак является публичным.

  3. Какой блокчейн можно поддерживать?

    Любой. Из коробки - всё, что работает с ethers.js (то есть EVM). Если у вас что-то кастомное, можно использовать метод accessPrivateKey.

  4. А если пользователь потерял устройство?

    Пока у него есть доступ к его Telegram-аккаунту, он просто залогинится на новом девайсе и кошелёк сам восстановится. Сид-фразу искать не придётся.

  5. Можно ли сделать бэкап ключа?

    Технически да, но не нужно. Кошелёк и так восстанавливается через Telegram. Если хотите, можете дать пользователю возможность забекапить ключ - но это уже на ваш страх и риск.

Заключение

Мы использовали TMA Wallet в двух собственных приложениях, одно из которых уже в проде (постеснялся выкладывать ссылку в начале статьи, чтобы не выглядело как реклама, но в футере ящитаю уже можно, Only100x)

Это отличный выбор для тех, кто разрабатывает мини-аппы в Telegram и хочет давать своим юзерам секьюрный воллет, не уродуя при этом UX всякими коннекторами.

Пробуйте, изучайте, если есть вопросы - вся документация и исходники проекта доступны на GitHub. Удачи!

P.S. 2025 год на дворе, как же без рекламы канала? собсна, я тоже сделал тг-канал. там я отвратительно себя веду, много матерюсь, но часто пишу всякое полезное про техно-фаундерство, AI, и прочее: как про мои/чужие opensource-либы, так и про то, как я укус за укусом прогрызаю свой путь в этом вашем медиа-пространстве. Подписывайтесь!

Автор: ElKornacio

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js