
В этом блоге мы рассмотрели интеграцию MetaMask Gas API в существующее dApp для продажи билетов, созданное с помощью Next.js и ShadcnUI.

Понимание цены газа перед покупкой билетов на мероприятия на основе блокчейна имеет ключевое значение как для прозрачности затрат, так и для эффективного финансового планирования. В контексте блокчейн-транзакций «газ» — это комиссия, необходимая для успешного проведения транзакции или выполнения контракта в блокчейне.
Размер этой комиссии варьируется в зависимости от нагрузки на сеть. Зная цену газа заранее, покупатели билетов могут принимать более взвешенные решения об итоговой стоимости покупки. Это особенно важно, поскольку комиссия за газ может существенно увеличить общую стоимость билета, особенно в периоды высокой загруженности сети.
В этом руководстве мы интегрируем MetaMask Gas API в существующий dapp для продажи билетов на мероприятия, чтобы пользователи могли видеть цены на газ при покупке билетов.
Действующий Web3 API key и API key secret.
Установленные Node.js и npm или yarn.
Знакомство с Next.js и React.
В качестве фронтенд-фреймворка мы будем использовать Next.js, а для UI — ShadcnUI. Установим следующие компоненты ShadcnUI:
Приведённый выше код добавит компонент hover-card, который мы будем использовать для отображения цен на газ, а также установит библиотеку React-хуков SWR. Библиотека Stale-While-Revalidate (SWR) упрощает получение данных из интернета: сначала она использует сохранённые старые данные, затем запрашивает новые и в итоге заменяет устаревшие данные актуальными. Это делает сайты быстрее и актуальнее.
Далее установим компонент react-circular-progressbar для отображения круговых индикаторов прогресса — они удобны для визуализации хода выполнения задач или состояния загрузки в веб-приложениях. Компонент настраиваем и реализован на основе SVG для высококачественной графики.
npm i react-circular-progressbarВ директории app/web создадим следующую папку: app/api/gas. Внутри создадим файл route.ts и добавим следующий код:
Разберём, что мы сделали:
Извлечение параметров запроса: const { searchParams } = new URL(request.url); — извлекает параметры поиска из URL запроса.
const chainId = searchParams.get("chainId"); — получает параметр chainId из URL, который используется для указания сети Ethereum.
Настройка авторизации: переменные окружения INFURA_API_KEY и INFURA_API_SECRET объединяются в Buffer, затем кодируются в строку Base64. Эта строка используется для базовой HTTP-аутентификации при запросах к Infura API.
Получение цен на газ и данных о процентиле базовой комиссии: к Infura API выполняются два асинхронных fetch-запроса:
gasPricesResp получает рекомендуемые комиссии за газ для указанной сети Ethereum (chainId).
baseFeePercentileRes получает процентиль базовой комиссии для той же сети.
В заголовке Authorization передаются учётные данные, закодированные в Base64.
Парсинг и возврат данных: ответы обоих fetch-запросов преобразуются в JSON. NextResponse.json({...}) формирует и возвращает JSON-ответ со следующими данными:
estimatedBaseFee — расчётная базовая комиссия за транзакции.
baseFeeTrend — тенденция изменения базовой комиссии (например, рост или снижение).
baseFeePercentile — процентильное распределение базовых комиссий.
Создадим компонент GasFeeCard.tsx и добавим в него следующий код:
Разберём, что мы сделали:
Константы: REFETCH_INTERVAL, STEP_INTERVAL, NETWORK_LATENCY — константы для управления интервалом получения данных, шаговым интервалом обновления обратного отсчёта и расчётной задержкой сети.
Вспомогательная функция: formatGweiValues — функция для форматирования значений цены газа в читаемый вид: экспоненциальная запись для малых значений или запись с фиксированной точкой для больших.
Компонент GasFeeCard:
Использует useSDK для получения текущего chainId Ethereum.
Инициализируются переменные состояния countdown и currentChainId.
Первый хук useEffect обновляет текущий ID цепочки и запускает повторное получение данных (mutate) при его изменении, а также сбрасывает таймер обратного отсчёта.
Второй хук useEffect устанавливает интервал, уменьшающий обратный отсчёт и запускающий повторный запрос данных при достижении нуля. При размонтировании интервал очищается.
fetcher — функция, получающая данные о газе из серверного API-эндпоинта с передачей текущего ID цепочки в качестве параметра запроса.
useSWR — хук для получения данных о газе с помощью функции fetcher, предоставляющий состояния данных, загрузки и ошибки.
Логика рендеринга:
Компонент условно отображает состояния загрузки и ошибки.
trendingUp и trendingDown — булевы значения, определяемые по baseFeeTrend из полученных данных о газе.
Основной UI состоит из HoverCard с CircularProgressbarWithChildren, отображающим прогресс обратного отсчёта, и иконкой стрелки, показывающей тенденцию цены газа. Отображается расчётная базовая комиссия в Gwei.
HoverCardContent показывает более подробную информацию о расчётной базовой комиссии и историческом процентиле базовой комиссии.
Стилизация:
В коде используются классы Tailwind CSS (например, text-red-500, cursor-pointer).
CircularProgressbarWithChildren стилизован так, чтобы менять цвет в зависимости от тенденции цены газа (красный — при росте, зелёный — при снижении).
Также мы использовали иконки ArrowUp, ArrowDown и InfoIcon из lucide-react. Осталось только импортировать этот компонент в компонент GetTicket.tsx, чтобы он отображался под итоговой стоимостью билетов.
Осведомлённость о цене газа позволяет покупателям выбирать наиболее выгодное время для совершения покупки, потенциально экономя средства за счёт проведения транзакций в периоды низких цен на газ. Для платформы продажи билетов на мероприятия предоставление этой информации повышает прозрачность и удовлетворённость пользователей: они чувствуют больший контроль над своими расходами и могут избежать неожиданных комиссий.
Мы интегрировали Gas API в существующий dapp для продажи билетов на мероприятия. Код для этого руководства можно найти здесь.
Также рекомендую ознакомиться со следующими ресурсами:
Документация Gas API: https://docs.infura.io/infura-expansion-apis/gas-api
Шаблон Gas API: https://github.com/meowyx/GasAPI-Template
Удачной разработки 🚀
Переведено ИИ. Может содержать ошибки. Пожалуйста, всегда проверяйте информацию.