Привет, Хабр! В этой статье я расскажу о возможностях API Magic Eden - одного из крупнейших NFT-маркетплейсов, в статье затрону непосредственно методы соланы, и покажу, как с его помощью можно создавать интересные проекты.
Введение
Magic Eden является ведущим NFT-маркетплейсом с ежемесячным объемом торгов более $100 миллионов. API платформы открывает широкие возможности для разработчиков, позволяя создавать различные приложения: от простых NFT-трекеров до сложных торговых ботов.
Обзор API
Magic Eden API предоставляет доступ к следующим основным категориям данных:
Информация о NFT и коллекциях
Данные о листингах и предложениях
Статистика торгов
Информация о кошельках
Инструкции для торговых операций
Метаданные и аналитика
Базовые эндпоинты
BASE_URL_MAINNET = "https://api-mainnet.magiceden.dev/v2"
BASE_URL_DEVNET = "https://api-devnet.magiceden.dev/v2"
ENDPOINTS = {
# NFT и коллекции
"collections": "/collections",
"collection_stats": "/collections/{symbol}/stats",
"collection_listings": "/collections/{symbol}/listings",
# Токены
"token_metadata": "/tokens/{token_mint}",
"token_listings": "/tokens/{token_mint}/listings",
"token_offers": "/tokens/{token_mint}/offers",
# Кошельки
"wallet_tokens": "/wallets/{wallet_address}/tokens",
"wallet_activities": "/wallets/{wallet_address}/activities",
# Торговые операции
"create_listing": "/instructions/sell",
"buy_now": "/instructions/buy_now",
"place_bid": "/instructions/buy",
}
Настройка и авторизация
Получение API ключа
Для работы с API необходимо получить ключ. Процесс регистрации:
import requests
class MagicEdenClient:
def __init__(self, api_key: str = None):
self.base_url = "https://api-mainnet.magiceden.dev/v2"
self.session = requests.Session()
if api_key:
self.session.headers.update({
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
})
def _make_request(self, method: str, endpoint: str, **kwargs):
try:
response = self.session.request(
method,
f"{self.base_url}{endpoint}",
**kwargs
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
logger.error(f"API Error: {e}")
return None
Основные возможности
1. Работа с коллекциями
class CollectionManager:
def __init__(self, client: MagicEdenClient):
self.client = client
def get_collection_stats(self, symbol: str):
"""Получение статистики коллекции"""
return self.client._make_request('GET', f'/collections/{symbol}/stats')
def get_floor_price(self, symbol: str) -> float:
"""Получение минимальной цены в коллекции"""
stats = self.get_collection_stats(symbol)
return stats.get('floorPrice', 0) / 1e9 if stats else 0
def monitor_floor_price(self, symbol: str, interval: int = 60):
"""Мониторинг изменения минимальной цены"""
while True:
price = self.get_floor_price(symbol)
logger.info(f"Floor price for {symbol}: {price} SOL")
time.sleep(interval)
2. Работа с токенами
class TokenManager:
def __init__(self, client: MagicEdenClient):
self.client = client
def get_token_metadata(self, mint_address: str):
"""Получение метаданных токена"""
return self.client._make_request('GET', f'/tokens/{mint_address}')
def get_token_listings(self, mint_address: str):
"""Получение активных листингов токена"""
return self.client._make_request('GET', f'/tokens/{mint_address}/listings')
async def monitor_token_price(self, mint_address: str):
"""Асинхронный мониторинг цены токена"""
while True:
listings = self.get_token_listings(mint_address)
if listings:
min_price = min(listing['price'] for listing in listings)
logger.info(f"Lowest price for {mint_address}: {min_price} SOL")
await asyncio.sleep(30)
Идеи для проектов
1. NFT Арбитражный бот
Идея: Поиск ценовых различий между Magic Eden и другими маркетплейсами.
class ArbitrageBot:
def __init__(self, me_client: MagicEdenClient, other_marketplace_client):
self.me_client = me_client
self.other_client = other_marketplace_client
self.min_profit = 0.5 # Минимальная прибыль в SOL
async def find_opportunities(self, collection_symbol: str):
me_listings = await self.me_client.get_collection_listings(collection_symbol)
other_listings = await self.other_client.get_collection_listings(collection_symbol)
for me_listing in me_listings:
for other_listing in other_listings:
if me_listing['tokenMint'] == other_listing['tokenMint']:
profit = other_listing['price'] - me_listing['price']
if profit > self.min_profit:
await self.execute_arbitrage(me_listing, other_listing)
2. NFT Снайпер
Идея: Автоматическая покупка NFT по заданным критериям.
class NFTSniper:
def __init__(self, client: MagicEdenClient):
self.client = client
self.target_collections = []
self.max_prices = {}
async def add_target(self, collection: str, max_price: float):
self.target_collections.append(collection)
self.max_prices[collection] = max_price
async def monitor_listings(self):
while True:
for collection in self.target_collections:
listings = await self.client.get_collection_listings(collection)
for listing in listings:
if listing['price'] <= self.max_prices[collection]:
await self.buy_nft(listing)
await asyncio.sleep(1)
async def buy_nft(self, listing):
try:
instruction = await self.client.get_buy_instruction(listing['tokenMint'])
# Выполнение транзакции покупки
transaction = await self.execute_transaction(instruction)
logger.info(f"Successfully bought NFT: {listing['tokenMint']}")
except Exception as e:
logger.error(f"Failed to buy NFT: {e}")
Все выше перечисленное, является примером части какого-то большого кода приложения и тут описан лишь примерный алгоритм, что бы дать вам почву для размышлений.
Лучшие практики
Обработка ошибок и повторные попытки:
from tenacity import retry, stop_after_attempt, wait_exponential
class RobustClient:
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
async def make_request(self, endpoint: str):
try:
response = await self.session.get(f"{self.base_url}{endpoint}")
response.raise_for_status()
return response.json()
except Exception as e:
logger.error(f"Request failed: {e}")
raise
Кэширование данных:
from functools import lru_cache
import time
class CachedClient:
@lru_cache(maxsize=100)
def get_collection_stats(self, symbol: str):
return self.client._make_request('GET', f'/collections/{symbol}/stats')
def clear_cache(self):
self.get_collection_stats.cache_clear()
Управление rate limits:
class RateLimitedClient:
def __init__(self, max_requests_per_minute: int = 120):
self.requests = []
self.max_requests = max_requests_per_minute
async def make_request(self, endpoint: str):
now = time.time()
# Очистка старых запросов
self.requests = [req for req in self.requests if now - req < 60]
if len(self.requests) >= self.max_requests:
wait_time = 60 - (now - self.requests[0])
await asyncio.sleep(wait_time)
self.requests.append(now)
return await self._make_request(endpoint)
Заключение
Magic Eden API предоставляет мощные инструменты для создания различных NFT-приложений. Мы рассмотрели основные возможности API и примеры их использования, а также поделились идеями для создания проектов.
Полезные ссылки:
P.S.
Если у вас есть вопросы или вы хотите поделиться своим опытом работы с Magic Eden API, пишите в комментариях.