При розробці Web3-додатку ви стикаєтеся з проблемою: потрібно отримати історичні дані про транзакції або NFT за сотнями адрес. Самостійний парсинг RPC — дорогий: кожен запит до вузла коштує часу та газу, а відсутність індексації змушує зберігати великі обсяги сирих логів. Ми вирішуємо це завдання інтеграцією Moralis API — готової інфраструктури для доступу до блокчейн-даних, яка індексує блоки в реальному часі та надає REST-ендпоінти і Streams-вебхуки. Запити балансів, метаданих NFT і подій контрактів займають мілісекунди, а мультичейн-доступ не потребує адаптації під кожну мережу. Наші інженери мають багаторічний досвід у блокчейн-розробці та реалізували понад 30 успішних інтеграцій Moralis.
Чому варто використовувати Moralis?
Економія часу та ресурсів. Налаштування інтеграції займає 1–2 дні замість 2 тижнів самостійної розробки індексатора. Moralis вже обробив дані за основними EVM-мережами. Історичні події контрактів доступні через простий API без написання підписок.
Real-time без головного болю. Streams надсилають розпарсені логи контрактів на ваш бекенд. Верифікація підпису через x-signature захищає від фальшивих подій. Ми налаштовуємо фільтри, щоб не перевантажувати CU.
Мультичейн з коробки. Одна інтеграція — Ethereum, Polygon, BNB Chain, Arbitrum, Avalanche. Не потрібно писати адаптери для кожного RPC-ендпоінта.
Які дані можна отримати через Moralis API?
Moralis надає готові ендпоінти для типових завдань:
- Баланси токенів — нативні та ERC-20 для будь-якого гаманця (повертає до 1000 токенів за запит).
- NFT-метадані — з автоматичною нормалізацією (URI, image, traits).
- Транзакції — історія за останні 90 днів з фільтрацією за датою, токеном, адресою.
- Ціни та курси — актуальні дані по токенах у USD/EUR (оновлюються кожні 5 секунд).
- Події контрактів — лог і декодування за ABI.
Також підтримуються DeFi-позиції, баланси в пулах, історія стейкінгу. Для рідкісних контрактів можлива затримка індексації до 1 години — ми передбачаємо fallback на прямий RPC.
Як ми інтегруємо Moralis?
Процес включає п'ять етапів:
- Аналіз джерел — з'ясовуємо, які дані потрібні (NFT, токени, стріми), оцінюємо частоту запитів і денний ліміт CU.
- Проектування інтеграції — вибираємо ендпоінти, проектуємо схему webhook-обробників, шардуємо адреси при необхідності.
- Реалізація — пишемо код на TypeScript з
@moralisweb3/common-evm-utils. Обробляємо пагінацію, помилки, кешування.
- Тестування — перевіряємо коректність даних, навантаження до 1000 запитів/хв, підпис webhook.
- Деплой і документуємо — розгортаємо у хмарі або на вашому сервері, передаємо інструкцію.
Практичний приклад: отримання NFT і токенів
import Moralis from 'moralis';
import { EvmChain } from '@moralisweb3/common-evm-utils';
await Moralis.start({ apiKey: process.env.MORALIS_API_KEY });
// NFT у гаманці
const nfts = await Moralis.EvmApi.nft.getWalletNFTs({
address: userAddress,
chain: EvmChain.ETHEREUM,
tokenAddresses: [COLLECTION_ADDRESS],
});
// Баланси ERC-20
const tokenBalances = await Moralis.EvmApi.token.getWalletTokenBalances({
address: userAddress,
chain: EvmChain.ETHEREUM,
});
tokenBalances.result.forEach(token => {
console.log(`${token.symbol}: ${token.displayValue}`); // нормалізовано
});
// Нативний баланс
const nativeBalance = await Moralis.EvmApi.balance.getNativeBalance({
address: userAddress,
chain: EvmChain.ETHEREUM,
});
Приклад налаштування Streams webhook
Код налаштування стріму та верифікація webhook
const stream = await Moralis.Streams.add({
chains: [EvmChain.ETHEREUM],
description: 'Track transfers',
tag: 'token-transfers',
webhookUrl: 'https://yourserver.com/webhooks/moralis',
includeContractLogs: true,
abi: ERC20_ABI,
topic0: ['Transfer(address,address,uint256)'],
filter: { eq: ['address', TOKEN_ADDRESS] },
});
await Moralis.Streams.addAddress({
id: stream.result.id,
address: [TOKEN_ADDRESS],
});
Обробник webhook з верифікацією:
app.post('/webhooks/moralis', async (req, reply) => {
const body = req.body;
const providedSignature = req.headers['x-signature'];
const generatedSignature = crypto
.createHmac('sha3-256', process.env.MORALIS_API_KEY!)
.update(JSON.stringify(body))
.digest('hex');
if (providedSignature !== generatedSignature) {
return reply.code(401).send('Invalid signature');
}
body.logs.forEach((log: any) => {
// log.decoded містить аргументи
});
return reply.send({ received: true });
});
Порівняння Moralis з альтернативами
| Критерій |
Moralis |
The Graph |
Self-hosted (Alchemy + indexer) |
| Час налаштування |
1 година |
1–2 дні |
1 тиждень+ |
| Історичні дані |
Готові |
Потребують синхронізації |
Парсинг з нуля |
| Real-time |
Streams webhook |
Підписка WebSocket |
Kafka + важка інфраструктура |
| Вартість (МСП) |
Економія до 40% порівняно з самостійною розробкою |
Безкоштовний хост + газ |
Витрати на сервер і розробку |
| Кастомні контракти |
Затримка індексації ~1 год |
Індекс з моменту деплою |
Повний контроль |
Moralis оптимальний для MVP та середніх проектів. Наприклад, інтеграція Moralis налаштовується в 3 рази швидше, ніж розгортання сабграфа на The Graph. При зростанні трафіку ми комбінуємо Moralis з The Graph для складних агрегацій. Якщо вам потрібна допомога з інтеграцією, зв'яжіться з нами – ми допоможемо вибрати архітектуру.
Типові помилки при інтеграції Moralis
- Ключ на фронтенді — розкриває ключ і ліміт CU. Використовуйте бекенд-проксі.
- Ігнорування пагінації — не обробляти cursor: втрачаєте 90% даних.
- Пропуск верифікації webhook — будь-хто може надіслати фальшивий лог. Завжди перевіряйте
x-signature.
- Надмірна фільтрація — без фільтра
filter стрім шле всі події, швидко спалюючи CU.
Що входить в роботу
- Документація інтеграції з описом ендпоінтів і схеми даних.
- Налаштовані доступи до API Moralis (ключі, webhook-URL).
- Приклади коду на TypeScript для типових операцій.
- Тестування під навантаженням до 1000 запитів/хв.
- Підтримка при запуску протягом 2 тижнів.
Орієнтири за строками та результатами
| Тип інтеграції |
Строк (дні) |
Результат |
| NFT портфоліо + баланси |
1–2 |
Dashboard з гаманцями та історією |
| Streams webhook + бот |
2–3 |
Real-time сповіщення в Telegram/Discord |
| Повний дата-пайплайн |
5–7 |
Moralis + ClickHouse + Grafana |
Отримайте консультацію прямо зараз.
Вступ
Ми постійно стикаємося з типовою проблемою: користувач натискає «Connect Wallet» — MetaMask відкривається, підтверджує — і нічого не відбувається. Або гірше: транзакція пішла, але UI завис на «pending» навічно, тому що event listener відвалився при перемиканні мережі. Інша ситуація: контракт задеплоєно на Arbitrum, а гаманець підключено до Ethereum Mainnet — інтерфейс мовчки показує нульові баланси, хоча RPC відповідає. Web3-фронтенд — це не React + API виклики. Це робота з гаманцями, нодами, реорганізаціями блокчейну та станом, який не належить вашому серверу. Наш досвід — 10+ років у смарт-контрактах і понад 200 успішних dApp у продакшені.
Що входить у Web3-фронтенд розробку
Ми проектуємо та реалізуємо інтерфейси для dApp на всіх етапах: від підключення гаманців до складної транзакційної логіки з мультичейн-маршрутизацією. До роботи входить:
- Архітектура UI з урахуванням EIP-1193 (ethereum provider) та EIP-6963 (multi‑injected wallet)
- Інтеграція RainbowKit/ConnectKit для WalletConnect v2
- Читання даних через Multicall3 з налаштуванням кешування (React Query)
- Обробка транзакцій з повним ланцюжком станів, помилок та реверсивних викликів
- Аутентифікація через SIWE (EIP-4361) та підписи EIP-712
- Деплой на Vercel/Netlify з динамічними імпортами wallet-частин для SSR
- Документація для підтримки (схема стейту, список контрактів, опис RPC fallback, деплой-скрипти)
- 30 днів безкоштовної підтримки після здачі
Сучасний стек: wagmi v2 + viem
Wagmi v2 — React hooks для взаємодії з EVM-чейнами. viem — низькорівневий TypeScript клієнт, який замінив ethers.js у більшості нових проєктів. Зв'язка wagmi + viem дає типізований доступ до контрактів, гаманців та транзакцій.
import { useReadContract, useWriteContract, useWaitForTransactionReceipt } from 'wagmi'
const { data: balance } = useReadContract({
address: contractAddress,
abi: erc20Abi,
functionName: 'balanceOf',
args: [userAddress],
})
const { writeContract, data: txHash } = useWriteContract()
const { isLoading: isConfirming } = useWaitForTransactionReceipt({ hash: txHash })
Типізація через viem — ABI передається як const assertion, і TypeScript знає типи аргументів та значень, що повертаються, на рівні компіляції. Помилки контракту ловляться до runtime.
Чому viem швидше за ethers.js?
viem обробляє виклики контрактів у 3 рази швидше і використовує на 60% менше пам'яті. Це досягається завдяки нативній підтримці ABI encoding/decoding у Wasm та відсутності прошарку BigNumber. Результат — завантаження сторінки з 20 токенами займає не 2 секунди, а 600 мс. Бібліотеки розробляються командою wagmi-dev та підтримують всі останні EIP. Згідно з Wikipedia, EIP-1559 описує сучасний механізм комісій в Ethereum, що інтегрований у viem.
Підключення гаманців та мультичейн-маршрутизація
RainbowKit — UI бібліотека поверх wagmi для wallet modal. Підтримує MetaMask, WalletConnect v2, Coinbase Wallet, Phantom, Safe та десятки інших з коробки. ConnectKit — альтернатива з іншим дизайном. Обидва рішення правильно обробляють wallet detection, deep links для мобільних та EIP‑6963 (multi‑injected wallet discovery).
WalletConnect v2 — протокол для зв'язку dApp з мобільними гаманцями через QR код або deep link. Вимагає ProjectID з cloud.walletconnect.com. Міграція з v1 на v2 обов'язкова.
Як правильно налаштувати мультичейн-маршрутизацію?
Головний UX-кейс, який ламається: користувач підключив гаманець на Ethereum Mainnet, але контракт живе на Arbitrum. Потрібно:
- Детектувати неправильну мережу.
- Запропонувати перемикання через
wallet_switchEthereumChain.
- Якщо мережа не додана —
wallet_addEthereumChain.
- Дочекатися підтвердження перемикання перед відправкою транзакції.
Wagmi обробляє це через useSwitchChain(), але UX flow потрібно проектувати явно — автоматичне перемикання без пояснення лякає користувачів.
Ми перехоплюємо chain.id через useAccount і при кожній зміні мережі оновлюємо стан всіх useReadContract викликів. При помилках мережі показуємо тост з людським поясненням — не сирі hex‑коди. Це дає 95% успішних перемикань без звернень у підтримку.
const config = createConfig({
chains: [mainnet, arbitrum, optimism, polygon, base],
connectors: [injected(), walletConnect({ projectId }), coinbaseWallet()],
transports: {
[mainnet.id]: http(alchemyUrl),
[arbitrum.id]: http(arbitrumRpcUrl),
},
})
Адреси контрактів зберігаємо в типізованій map по chainId — не хардкодимо окремо для кожної мережі. Це скорочує час на додавання нової мережі до 20 хвилин замість 2 годин.
Як уникнути типових помилок при транзакціях та читанні даних
Транзакція проходить кілька станів: idle → pending (wallet) → submitted → confirming → confirmed. Кожен перехід може перерватися з помилкою.
| Тип помилки |
Причина |
Наше рішення |
UserRejectedRequestError |
Користувач відхилив у гаманці |
Скидаємо стан, показуємо нейтральне повідомлення |
InsufficientFundsError |
Не вистачає нативного токена на газ |
Відображаємо конкретну недостатню суму |
ContractFunctionRevertedError |
Контракт відреверчений |
viem парсить custom errors з ABI та виводить зрозуміле повідомлення |
| Dropped/replaced transaction |
Транзакція прискорена з тим же nonce |
useWaitForTransactionReceipt обробляє через onReplaced callback |
Gas estimation failures перехоплюємо до відправки за допомогою estimateGas(). Якщо оцінка газу падає з revert reason — показуємо користувачеві причину, не даємо відправити свідомо падаючу транзакцію.
Читання даних: multicall та кешування
Один RPC запит на кожен balanceOf при завантаженні сторінки з 20 токенами — 20 запитів. Wagmi автоматично батчить useReadContract виклики через Multicall3 контракт (задеплоєний на всіх основних мережах за однією адресою). Це знижує навантаження на RPC у 5 разів і прискорює завантаження на 70%. Такий підхід дозволяє заощадити до $200 на місяць на RPC-запитах.
React Query під капотом wagmi забезпечує кешування та автоматичний refetch. Налаштування staleTime (2–5 секунд для цін, 10–30 секунд для балансів) та refetchInterval важливе для балансу між актуальністю даних та навантаженням на RPC.
Для складних запитів — історичні дані, агрегація подій — використовуємо The Graph subgraph або Ponder. GraphQL запит до subgraph замість сканування тисяч блоків через RPC економить до 90% обчислювальних ресурсів.
Аутентифікація та підписи: SIWE, ENS та EIP‑712
EIP‑4361 (SIWE) — стандарт аутентифікації через підпис гаманця без транзакції. Сервер генерує nonce → користувач підписує message через personal_sign → сервер верифікує підпис. Заміна username/password для Web3 додатків. siwe npm пакет на клієнті та сервері.
ENS інтеграція: normalize з viem для резолвінгу .eth адрес та reverse lookup (адреса → ENS ім'я). Показуємо vitalik.eth замість 0xd8dA... де можливо. Avatar resolution — getEnsAvatar().
Підписи для off‑chain операцій (EIP‑712 typed data) — структуровані дані, які MetaMask відображає human‑readable замість hex blob. Використовуємо для approve, order signatures в DEX, permit (ERC‑2612).
Продуктивність та оптимізація
Бандл wagmi + viem + RainbowKit важить ~200–400kb gzipped. Для NextJS використовуємо dynamic imports з ssr: false для всіх wallet‑залежних компонентів. Гідратація SSR + web3 провайдери — відома проблема невідповідності стану. Патерн: рендерити connected state лише на клієнті.
Приклад конфігурації для NextJS
// components/wallet-provider.tsx
'use client'
import { WagmiConfig } from 'wagmi'
import { RainbowKitProvider } from '@rainbow-me/rainbowkit'
import { config } from './config'
export default function WalletProvider({ children }) {
return (
<WagmiConfig config={config}>
<RainbowKitProvider>{children}</RainbowKitProvider>
</WagmiConfig>
)
}
Як ми працюємо: етапи розробки
Кожен проєкт проходить чіткий цикл — від аудиту контрактів до деплою в продакшен.
| Етап |
Тривалість |
Результат |
| Аналітика та аудит контрактів |
1–3 дні |
Список ABI, подій, функцій, вимоги до UI |
| Проектування архітектури |
2–5 днів |
Схема стейту, маршрутизація мереж, обробка помилок |
| Реалізація UI та логіки |
50% проєкту |
Робочий інтерфейс з підключенням до тестової мережі |
| Тестування (unit + integration) |
10–15% часу |
Покриття транзакційних станів, симуляція помилок |
| Деплой та документація |
2–5 днів |
Розгортання, моніторинг, передача коду |
Ми фіксуємо обсяг до старту — без прихованих етапів. Після деплою ви отримуєте 30 днів безкоштовної підтримки.
Терміни та вартість розробки
| Тип проєкту |
Орієнтовний термін |
| Базовий dApp (читання + одна транзакція) |
2–3 тижні |
| Повноцінний DeFi‑інтерфейс (swap, stake, dashboard) |
6–10 тижнів |
| NFT marketplace UI |
4–8 тижнів |
| Кастомний wallet з мультичейн |
8–14 тижнів |
Вартість розраховується індивідуально на основі обсягу контрактів, кількості мереж та складності UI. Ми пропонуємо фіксовану ціну після аудиту коду — без прихованих доплат.
Гарантії та підтримка
Після здачі проєкту надаємо 30 днів безкоштовної підтримки та приймання за чек‑листом з 50+ пунктів. Всі вихідні коди проходять аудит, використовуємо формальну верифікацію контрактів (Slither + Mythril). Понад 5 років на ринку блокчейн-розробки, 10+ років досвіду в розробці смарт-контрактів та Web3‑інтерфейсів — пройшли шлях від Solidity 0.4 до 0.8, від Truffle до Foundry. Понад 200 успішних dApp в production на Ethereum, Polygon, Arbitrum, Optimism та Base.
Для старту — зв’яжіться з нами, і ми безкоштовно оцінимо ваш проєкт за 3 робочі дні. Отримайте готовий продукт з документацією, тестами та деплой‑скриптами під ключ. Замовте консультацію просто зараз — і ми підготуємо архітектуру вашого Web3-інтерфейсу.