китаев.tech

Что такое viem и зачем он нужен, если я уже знаю ethers.js

Узнаешь, чем viem отличается от ethers.js, установишь пакет и прочитаешь баланс адреса через createPublicClient.

TypeScript-first SDK для Ethereum

viem — это TypeScript-библиотека для чтения Ethereum и отправки транзакций через JSON-RPC. Она решает те же задачи, что ethers.js, но устроена иначе: вместо классов Provider / Signer / Contract — клиенты и отдельные функции, плюс автовывод типов из ABI.

Учить второй SDK имеет смысл, если ты идёшь в wagmi, RainbowKit или свежие React-dApp: там viem уже стоит под капотом.


Установка и чтение баланса

bash
npm install viem
typescript
import { createPublicClient, http, formatEther } from "viem";
import { mainnet } from "viem/chains";

const publicClient = createPublicClient({
  chain: mainnet,
  transport: http("https://ethereum.publicnode.com"),
});

const vitalikAddress = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045";

const balance = await publicClient.getBalance({
  address: vitalikAddress,
});

console.log(formatEther(balance)); // например "1234.56"

Код только читает сеть. Приватный ключ не нужен.


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

createPublicClient() — создаёт клиент для чтения: баланс, блоки, eth_call. Это аналог JsonRpcProvider в ethers.

chain: mainnet — говорит клиенту, какая сеть ожидается (chainId 1). Неверная сеть на RPC даст ошибку раньше, чем ты отправишь транзакцию не туда.

http(...) — транспорт: как именно ходить в ноду. Здесь обычный HTTP JSON-RPC.

getBalance({ address }) — RPC eth_getBalance. Результат — нативный bigint в wei, не объект BigNumber.

formatEther() — wei → строка в ETH. Имя то же, что в ethers v6.


Если ты знаешь ethers.js

Та же задача на ethers v6:

typescript
import { ethers } from "ethers";

const provider = new ethers.JsonRpcProvider("https://ethereum.publicnode.com");
const balance = await provider.getBalance(
  "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
);
console.log(ethers.formatEther(balance));
ethers v6viem
new JsonRpcProvider(url)createPublicClient({ chain, transport: http(url) })
provider.getBalance(address)publicClient.getBalance({ address })
ethers.formatEther(balance)formatEther(balance)
BigNumber / bigintвсегда bigint

Главный сдвиг не в синтаксисе getBalance, а в модели: клиент + transport + явная chain вместо одного класса провайдера.


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

«Зачем ещё один SDK, если ethers уже умеет всё» → ethers умеет. viem нужен не потому что ethers сломан, а потому что экосистема React (wagmi v2) и TypeScript-инференс ABI сейчас строятся вокруг него.

Импорт только from "viem" для сетейmainnet, sepolia и остальные цепи лежат в viem/chains. Без этого импорта клиент не собрать.

Сравнение бандла «на глаз» по одному import → viem модульный: в бандл попадает то, что ты реально вызываешь. Выгода видна на tree-shaking в сборке, а не на размере node_modules.


Что дальше

Материалы китаev.tech публикуются в образовательных целях и не являются инвестиционной рекомендацией. Примеры кода и описания протоколов — для обучения; использование в продакшне на ваш собственный риск. Дисклеймер и политика конфиденциальности.