Я у мамы криптотрейдер

Или как за один день написать бота для снайпинга (информирования) и автоснайпинга (покупки) NFT.

P.S. Картинку купил бот специально для меня <3

cb83b54bf00fe5231bd65d6443535cad.png

Скучная теория

Solana — высокоскоростная сеть с низкой стоимостью транзакции. Поэтому она быстро снискала себе популярность среди NFT-скамеров (в этой шутке есть доля шутки). На самом деле OpenSea тоже забит скам-релизами, но я не хочу уходить в печаль по этому поводу. У меня была другая задача — написать бота, который сможет следить за стоимостью токенов на какой-нибудь популярной площадке и выкупать их, как только стоимость такого токена упадёт ниже установленного порога. И сделать это за один выходной.

С этого и начнём.

Выбираем цель

Среди двух крупных площадок (OpenSea/MagicEden) я выбрал второй. У меня был план, и я его придерживался ключ для API OpenSea, но на гитхабе достаточно много готовых примеров для этой площадки, поэтому такой челлендж был бы просто неинтересным. С другой стороны, для «Райского садика» нет ни одного нормального клиента/бота. GitHub откровенно говоря, завален десятками странных реализаций через puppeteer + Phantom, большинство из которых подозрительно смахивают на лёгкий способ увести ваши денежки (возможно, их распространяют продвинутые сотрудники службы безопасности Сбербанка, но это не точно). И ни один из них не работает. Даже победители прошлогоднего хакатона с автоснайпером (автопокупкой) Solset.io за целый год не выкатили ничего более-менее стоящего. Поэтому было решено сделать всё самостоятельно. Яжпрограммист, в конце концов.

Прицеливаемся

Как я уже говорил, Солана — сеть, где количество транзакций исчисляется тысячами в секунду. Анализировать всё — просто нереально. С другой стороны, уже есть готовые решения, которые позволяют получать свежие транзакции напрямую через сокет. Один из них — QuickNode (и это даже не реклама). Можно очень просто прицепится к его сокету, читать оттуда всю необходимую информацию и радоваться жизни.

Но как фильтровать только необходимые транзакции? Тут на помощь приходить знание, что все операции, которые осуществляются через MagicEden, задействуют его кошелёк (потому что он должен начислять себе комиссию). А значит, мы можем установить «прослушку» на публично доступный MEv2 адрес: M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K и смотреть только те транзакции, в которых он участвует. На практике это выглядит примерно так:

7a587b9deea15159b324f9c9bedaa3a1.png

И вот тут я получил по носу в первый раз. Транзакция, которую присылает нам Magic Eden, имеет нестандартные смещения. То есть там, где мы ожидаем увидеть одни данные — нам приходят другие. Поиск в открытых источниках дал расшифровку только для первой версии программы (MEv1), но эти смещения не подходят для второй версии, которая используется с ноября 2021. Поэтому берём в руки борщ и начинаем искать. После примерно получаса брутфорсного подбора я нашёл последовательность данных в транзакции от MEv2:

5fc3fb9c8b72cf1040aea6d8e7d21776.png

Итак, у нас есть адрес адрес токена и зашифрованная цена. С ценой оказалось очень просто: для неё уже есть готовый сдвиг, поэтому здесь я не потратил много времени:

c1e23cd224d92b74b40bf8d45352e6a8.png

Победа! У нас на руках есть адрес токена, на который только что изменилась цена, операция (листинг/ставка) и собственно цена вопроса. Если цена нас устраивает, давайте попробуем купить.

Стреляем

(Заголовки, конечно, так себе, но это издержки нашего времени).

Итак, мы знаем, что на наш NFT поменялась цена. Или кто-то поставил нужную нам цену. Теперь нам нужно сформировать транзакцию и отправить её на одобрение. И вот тут меня ожидало второе разочарование. У меня никак не получалось правильно собрать транзакцию вручную. А MagicEden позволял генерировать инструкцию для покупки только с ключом API. Но проблема разрешилась совершенно внезапно: Discord-админ с ником Dolphin после недолгих уговоров выдал мне ключ! И теперь мне не нужно было самому составлять транзакцию, а достаточно только было запросить её через Magic Eden API и подписать (да, мне пришлось создать новый кошелёк и экспортнуть из него приватный ключ, но это — необходимый риск. Никогда не используйте свой основной кошелёк для таких целей! Всегда создавайте пустой новый и экспериментируйте только на нём!).

9779c4c6f6bd9fe5ff25880f7efc86f4.png

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

Ах да, ещё одна проблема: для каждого NFT токена внутри Solana нужно находить ATA — ассоциированный адрес аккаунта. К счастью, такая программа уже есть и нужно было только вовремя вызвать её с параметрами mintAddress и sellerAddress, где seller — это собственно наш любимый MagicEden:

6be361d7f52ddb483f6fab097d10e560.png

Ну вот пожалуй и всё. Бот был отправлен в боевое тестирование и успешно купил мне NFT картинку из заголовка, когда её цена упала в 2 раза.

P.S. Перед тем, как выложить на гитхаб, я добавил от себя стандартные расшифровки MetaPlex Data, чтобы можно было выводить дополнительную информацию о токене (картинку, теги и т.п.) при его покупке, но это уже больше для красоты, чем для пользы.

P.S2: Пока писал этот текст, обнаружил, что средняя стоимость такого проекта на фриланс-биржах — $500. Неплохо для одного выходного.

Ссылка для изучения/закидывания багами помидорами: https://github.com/jfkz/magic-eden-sniper

© Habrahabr.ru