Я занимаюсь блокчейн-разработкой и давно хочу запустить свой проект. В январе проходил курс 12DaysOfDune (по результатам которого писал хабр статью) на платформе блокчейн-аналитики Dune Analytics. Dune – это сервис, который содержит в своей БД данные множества блокчейнов, и для получения статистики – например, посчитать объем торгов на бирже Uniswap за день – можно просто написать SQL запрос.

В процессе работы над SQL запросами было неудобно разбираться, какие данные или схема у таблиц (а их там более 700 000!). Постоянно делать запросы "SELECT * FROM tbl LIMIT 10" – или находить таблицу в панели слева – уходит много времени. Возникла мысль – а почему бы не сделать расширение, которое будет решать эту задачу – установил курсор на название таблицы, нажал hotkey – и видишь схему или превью данных. Вот так, как на картинке ниже (это уже готовый продукт).

Проект я в итоге реализовал, работая месяц фулл-тайм. В процессе вырастил аудиторию Твиттера, получил много хороших отзывов и опыт запуска проекта (хоть и небольшого), чем и хочу поделиться.
Напишу про то, с какими техническими сложностями сталкивался (первый проект на React+TypeScript), как продвигал в соцсетях, и про достигнутые результаты. И, конечно же, про ChatGPT.

Минутка саморекламы — веду тг‑канал Web3 разработчик. Пишу небольшие заметки о задачах по блокчейну/крипте, которые решаю. Буду рад видеть среди подписчиков!

Разработка

API для получения схем и превью таблиц

Dune не предоставляет официального API для получения схем таблиц и их превьюшек. Чтобы понять, какие запросы нужно делать для получения этих данных, пришлось проанализировать в Chrome Developer tools, какие запросы идут на сервер (вкладка network), выбирая таблицы и их схему в панели слева:

Тут не было чего-то сверхординарного – просто открываешь таблицу и изучаешь, какой запрос отправляется на сервер.

Авторизация

Для авторизации используется https://jwt.io. Чтобы сервер мог проверить авторизацию запроса, в каждый HTTP запрос нужно включить 2 заголовка с токенами: authorization и x-dune-access-token.

Чтобы получить эти токены, нужно вызвать https://dune.com/api/auth/session с параметром "credentials": "include". Это работает так: (1) страница авторизована (2) вызов /api/auth/session запрашивает jwt токен, передавая все credentials в запросе (cookies, заголовки аутент��фикации, TLS сертификаты) (3) jwt токены возвращаются сервером (4) полученные токены используются при дальнейших вызовах бекенда. Если осталось меньше 30 секунд до истечения срока жизни токена, то https://dune.com/api/auth/session вызывается повторно.

Архитектура расширения

HTTP запросы к беку нужно делать, как будто бы это делала страница Dune. Это определило архитектуру расширения:

Content script (скрипт, который внедряется расширением в страницу), имеет доступ только к DOM документа, но не к переменным страницы. Чтобы делать запросы к бекенду Dune от имени страницы, а также чтобы отлавливать события редактора, нужен еще один скрипт (injected), который внедряется content скриптом. Они "шарят" одно окно, и обмениваются данными через механизм сообщений (window.postMessage/window.addEventListener).

Расширение и сборка

Boilerplate расширения, который я взял, оказался в целом неплохим – TypeScript+React. Пришлось поправить ошибки касательно сборки через Webpack – отключить chunks, т.к. собранные файлы расширения должны быть одним файлом. Также, перевести на React hooks + functional components. Поэтому можно использовать код расширения как основу.

Верстка и React

Я не фронтенд-разработчик, поэтому это была самая заковыристая часть. Очень сильно помогал ChatGPT, которому я задавал вопросы по верстке, React, TypeScript. Вот некоторые примеры моих запросов:

  • write a HTML code for a button with rounded corners ("напиши HTML код, чтобы нарисовать кнопку с закругленными краями")

  • in typescript how to create new array from first x elements of array ("как в TS создать новый элемент из x первых элементов массива").

  • how to add tooltip to html button ("как добавить тултип к кнопке")

  • how to create a React component that might contain another component. Example for TypeScript -> Can you do the same but without inheriting from FC and defining additional interface? ("как создать Реакт компонент, который может содержать другой компонент" -> "Можешь сделать то же самое, но без наследования от FC и доп интерфейса")

Конечно же, он не может, как рассказывают в твиттере, написать "приложение за час вместо разработчика за неделю", но Гугл заменяет отлично. Нужно знать, что спросить, и иметь опыт программирования, чтобы понимать, что за решение тебе предлагается. Очень экономит время (по сравнению с гуглом) получение запроса по конкретно интересующему вопросу. В особенно сложных вопросах, конечно, не обошлось без "звонка другу-фронтендеру".

Публикация

Публикация в Chrome Web Store – довольно тривиальна, в моем случае первая заняла примерно полсуток, в дальнейшем при небольших правках – пара часов.

Запуск продукта я решил сделать в Твиттере. Там где тусуются все крипто-разработчики и аналитики. Вот мой launch-твит–тред (по состоянию на 20 марта).

Launch-твит. Если перейти по ссылке, то можно прочитать весь тред
Launch-твит. Если перейти по ссылке, то можно прочитать весь тред

Сделал видео, чтобы сразу было видно, что делает расширение. Запись экрана через QuickTime Player на Маке. Много провозился с тем, чтобы было правильное разрешение у видео (в данном случае 720x720, читайте доки Твиттера, какие разрешения поддерживаются), чтобы был крупный шрифт, для этого пришлось поколдовать с версткой в DevTools и зумом страницы. У Твиттера нет превью твитов, поэтому пришлось создать тестовый аккаунт и тестить под ним – смотреть, как будет выглядеть видео. Совет – делать все максимально приближено к реальности, смотреть как получится, и добиваться хорошего качества. Чтобы подгонять размеры окна под видео/скрины использовал экранную линейку Free Ruler для Мака.

В твиттере отметил 8 аккаунтов из тусовки web3 аналитиков данных с примерно 2-20 тыс. подписчиков (кроме Dune, где 100 тыс, но я не надеялся на репост от них). Кого-то из этих ребят я читал, кого-то видел в комментах. Мой вывод, если запускаться, то нужно иметь список людей, кому потенциально могло бы быть интересно.

После первого твита в течение недели я сделал еще несколько, чтобы подогреть аудиторию:

  • Пост благодарности, что хорошо приняли и отправили багрепорты.

  • Пост про бекстейдж (сколько времени на что потратил).

  • Про исправленные баги и новые фичи (то, что мне накидали люди).

  • Про то, что открыл исходный код расширения.

Сроки

  • 1я не��еля – PoC, проверка, что данные по таблицам можно получить, авторизация

  • 2я неделя – первая работающая версия с версткой, схемой таблицы

  • 3я неделя – превью данных, попап страница, логгинг, доработки для "реальной жизни".

  • 4я неделя – инструмент поиска методов Solidity по четырем байтам keccak256 сигнатуры, правка багов, подготовка к релизу (видео/материалы).

  • 5я неделя – продвижение в соцсетях, правка багов, релиз в виде опенсорс.

Полностью трудозатраты на продукт составили пять недель, включая публикацию и продвижение. Я сделал возможность принимать донаты, но никто пока не ничего не прислал :) По итогу, решил опубликовать как open source на гитхабе, чтобы продукт развивался без меня.

Результаты и выводы

Сразу получил довольно много отзывов от Data-аналитиков:

Всего 110 лайков оригинального поста, 19 тыс. охвата (с другими постами больше). За неделю в твиттер добавилось +40 человек (было 35, стало 74 фолловера). Моя гипотеза, если бы было больше подписчиков, то рост бы тоже был на 100%, т.к. на маленьком объеме рынка он далеко не исчерпывается. Но, самое главное, у меня появились "живые", лояльные подписчики – я, сколько до этого не твитил, не мог найти алгоритм роста аудитории.

Через 10 дней после публикации в Chrome Web Store количество пользователей расширения составляет 45. Посмотрим, будет ли расти.

В личку уже постучались из команды Dune и просто люди со стороны, приглашая поработать вместе. А вот это уже получился классный нетворкинг, когда к тебе сами приходят знакомиться люди с желанием с тобой поработать.

Да, я не заработал денег, но получил классный опыт в технологиях и продвижении, сделал чуть более удобной работу небольшого количества веб3-аналитиков. Но самое главное, получил классную мотивацию запустить свой продукт (то, что я хочу сделать в этом году), и просто потренировался "в песочнице". Надеюсь, вы также найдете что-то полезное в этой статье, или получите мотивацию на создание своих pet-проектов.