Подключение аккаунта и события кошелька

Пишем кнопку «Подключить кошелёк» правильно: запрос аккаунта, хранение адреса, реакция на смену аккаунта и сети.

Подключение кошелька — получение разрешения пользователя на чтение его адреса; это «вход» в dApp, но без пароля и без передачи приватного ключа.

Подключение — первое, что делает пользователь. Сделаете грубо — потеряете доверие на старте. Хорошее подключение учитывает три события: пользователь подключился, сменил аккаунт, сменил сеть.

Базовый поток подключения

async function connect() {
  if (!window.ethereum) throw new Error("Нет кошелька");
  const accounts = await window.ethereum.request({
    method: "eth_requestAccounts",
  });
  return accounts[0]; // активный адрес
}

После этого адрес кладут в состояние приложения (React-state, store) и показывают в шапке — «0x71C7…976F», кнопку «Подключить» меняют на «Отключить».

Три события кошелька

Кошелёк сам сообщает об изменениях через события EIP-1193. Подпишитесь на них, иначе UI начнёт врать:

// Пользователь сменил аккаунт в MetaMask
window.ethereum.on("accountsChanged", (accounts) => {
  if (accounts.length === 0) {
    // отключился — сбросить состояние
  } else {
    // обновить адрес в UI
  }
});

// Пользователь сменил сеть
window.ethereum.on("chainChanged", (chainId) => {
  // рекомендуется перезагрузить данные под новую сеть
  window.location.reload();
});

Почему это критично: пользователь может в любой момент в самом MetaMask переключить кошелёк с аккаунта A на B или с Ethereum на Polygon. Если вы не слушаете события, ваш фронт будет показывать баланс старого аккаунта в старой сети — и любая запись пойдёт «не туда».

Восстановление подключения при перезагрузке

Если пользователь уже подключал кошелёк, при следующем заходе не надо снова открывать окно. На старте тихо спросите eth_accounts:

// При монтировании приложения
const accounts = await window.ethereum.request({ method: "eth_accounts" });
if (accounts.length > 0) {
  // уже подключены — восстановить состояние без окна
}

Как работает под капотом

«Подключение» — это запись в кошельке разрешения для вашего домена видеть выбранные аккаунты. Никакой серверной сессии не создаётся: состояние «подключён» живёт в кошельке и в памяти вашего фронта. Поэтому после полной перезагрузки страницы вы заново читаете eth_accounts, чтобы восстановить UI. Отзыв доступа пользователь делает в настройках кошелька (Connected sites).

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

  • Не слушать accountsChanged/chainChanged. UI рассинхронизируется с реальным аккаунтом и сетью — источник опасных багов.
  • Хранить «подключён» в localStorage как истину. Истина — в кошельке; на старте перепроверяйте через eth_accounts.
  • Не сбрасывать состояние при пустом accountsChanged. Пустой массив = пользователь отключился, UI должен это отразить.

Итоги

  • Подключение — это разрешение видеть адрес, а не серверный логин.
  • Обязательно слушайте accountsChanged и chainChanged.
  • На старте восстанавливайте подключение через тихий eth_accounts.
Проверьте себя
1. Какое событие сообщает, что пользователь сменил аккаунт в MetaMask?
AchainChanged
BaccountsChanged
CblockMined
Dconnect
2. Как тихо восстановить подключение при перезагрузке, не открывая окно?
Aeth_requestAccounts
Beth_accounts
Ceth_chainId
Dpersonal_sign
3. Что обычно делают по событию chainChanged?
AИгнорируют его
BПерезагружают данные под новую сеть (часто reload)
CУдаляют приватный ключ
DОтправляют транзакцию