Восстановление доступа к кошельку

Восстановишь доступ по seed: выберешь верную версию контракта, проверишь адрес на testnet/mainnet и поймёшь типичные причины «пустого» баланса.

Восстановление = тот же ключ + та же версия контракта

Доступ к средствам восстанавливается, если есть seed (или secretKey) и ты открываешь ту же версию кошелька (v3R2 / v4R2 / v5R1), тот же workchain и параметры (walletId для v5). Без seed восстановление криптографически невозможно — «поддержка» не сбросит пароль.

UI (Tonkeeper и др.): Import wallet → ввод фразы → выбор версии, если приложение спрашивает.


Проверка адреса после импорта (offline)

typescript
// @ton/crypto ^3.3.0, @ton/ton ^15.1.0
import { mnemonicValidate, mnemonicToPrivateKey } from "@ton/crypto";
import {
  WalletContractV3R2,
  WalletContractV4,
  WalletContractV5R1,
} from "@ton/ton";

const words = process.env.RECOVERY_MNEMONIC!.split(" "); // не логируй

if (!(await mnemonicValidate(words))) {
  throw new Error("Невалидная мнемоника: опечатка или не BIP39");
}

const { publicKey } = await mnemonicToPrivateKey(words);

const candidates = [
  {
    name: "v3R2",
    address: WalletContractV3R2.create({ workchain: 0, publicKey }).address,
  },
  {
    name: "v4R2",
    address: WalletContractV4.create({ workchain: 0, publicKey }).address,
  },
  {
    name: "v5R1-mainnet",
    address: WalletContractV5R1.create({
      publicKey,
      walletId: { networkGlobalId: -239 },
    }).address,
  },
  {
    name: "v5R1-testnet",
    address: WalletContractV5R1.create({
      publicKey,
      walletId: { networkGlobalId: -3 },
    }).address,
  },
];

for (const c of candidates) {
  console.log(
    c.name,
    c.address.toString({ bounceable: false, urlSafe: true }),
  );
}
// Сверь с адресом, на котором был баланс в explorer — импортируй эту версию.

Если фраза верная, но баланс «ноль», почти всегда открыта другая версия или другая сеть (mainnet vs testnet).

СимптомЧто проверить
«Invalid seed»Число слов (24), язык словаря, лишние пробелы
Адрес не тот, что в explorerВерсия контракта, v5 networkGlobalId
Баланс на старом адресе, новый пустойТы смотришь другой StateInit — не «сгоревший» seed

Как это работает

  1. Seed → keypair (детерминированно).
  2. Версия контракта + параметры → StateInit → адрес.
  3. Импорт в приложении пересчитывает адрес и подписывает external тем же secretKey.
  4. Без on-chain «привязки личности»: сеть знает только ключ и код контракта.

Частые ошибки

Импортировал seed в кошелёк с версией по умолчанию v5, а средства на v4 → создай/открой именно v4R2 (в Tonkeeper — выбор версии при импорте или отдельный аккаунт).

Восстанавливаешь mainnet-фразу на testnet RPC и наоборот → для v5 адреса расходятся из-за networkGlobalId; для v4 адрес тот же формат, но баланс в другой сети.

Переписал фразу с ошибкой в одном словеmnemonicValidate ловит часть случаев; сверяй слова со словарём BIP39, не «похожие» слова.


Что дальше

Материалы gramdocs.tech носят образовательный характер и не являются финансовой, юридической или инвестиционной рекомендацией. Работа с блокчейном TON и токеном Gram связана с рисками потери средств. Правовая информация