window.ethereum и EIP-1193
Что такое window.ethereum, стандарт EIP-1193 и почему все кошельки разговаривают одним языком.
EIP-1193 — стандарт интерфейса провайдера кошелька: единый объект
window.ethereumс методомrequest()и событиями, через который dApp общается с любым кошельком.
Когда пользователь устанавливает MetaMask, расширение внедряет в каждую страницу объект window.ethereum. Это и есть мост между вашим фронтом и кошельком. Благодаря стандарту EIP-1193 не важно, какой именно кошелёк стоит — интерфейс один.
Главный метод: request
Всё общение с кошельком идёт через один метод ethereum.request({ method, params }), возвращающий Promise. Имена методов — те же JSON-RPC плюс «кошельковые» расширения:
// Запросить подключение аккаунтов (откроет окно MetaMask)
const accounts = await window.ethereum.request({
method: "eth_requestAccounts"
});
console.log("адрес:", accounts[0]);
// Узнать текущую сеть (chainId в hex)
const chainId = await window.ethereum.request({ method: "eth_chainId" });
console.log("chainId:", chainId); // напр. "0x1" для Ethereum mainnetНа практике вы редко зовёте request вручную — ethers.js и wagmi оборачивают его в удобные методы. Но понимать базовый слой важно: всё в итоге сводится к этому вызову.
eth_accounts против eth_requestAccounts
Тонкий, но важный момент:
eth_accounts— тихо вернёт уже подключённые аккаунты (или пустой массив). Окно не открывает. Используется при загрузке, чтобы понять «а мы уже подключены?».eth_requestAccounts— активно просит доступ: открывает окно кошелька. Зовите только по клику пользователя на кнопку «Подключить».
Как работает под капотом
Объект window.ethereum — это прокси, который сериализует ваш вызов и через защищённый канал передаёт его в фоновый процесс расширения. Расширение решает, показать ли пользователю окно (для чувствительных методов вроде подключения и подписи) или ответить сразу (для безобидных чтений). Ответ возвращается обратно в Promise. Сам приватный ключ никогда не пересекает границу страницы — наружу выходит только результат (адрес, подпись, хеш транзакции).
Проверка наличия кошелька
Если кошелька нет, window.ethereum будет undefined. Всегда проверяйте перед использованием и предлагайте установить кошелёк:
if (typeof window.ethereum === "undefined") {
// показать кнопку "Установить MetaMask"
} else {
// кошелёк есть — можно подключаться
}Частые ошибки
- Звать eth_requestAccounts при загрузке страницы. Это навязчиво и блокируется браузерами; делайте только по клику.
- Не проверять наличие window.ethereum. У части пользователей кошелька нет — приложение упадёт.
- Считать, что кошелёк один. Несколько расширений могут конфликтовать за window.ethereum; стандарт EIP-6963 решает это, но базово помните о проблеме.
Итоги
window.ethereum— единый объект кошелька по стандарту EIP-1193.- Всё общение — через
request({ method, params }). eth_accountsчитает тихо,eth_requestAccountsоткрывает окно (только по клику).