coingecko

Par elophanto · elophanto

Intégration complète de l'API CoinGecko Solana pour les prix des tokens, les données de pool DEX, les graphiques OHLCV, les trades et l'analytique de marché. À utiliser pour créer des bots de trading, des suiveurs de portefeuille, des flux de prix et des applications de données on-chain.

npx skills add https://github.com/elophanto/elophanto --skill coingecko

Guide de développement de l'API CoinGecko Solana

Un guide complet pour intégrer l'API on-chain de CoinGecko pour Solana. Accédez aux prix des tokens en temps réel, aux données des pools DEX, aux graphiques OHLCV, à l'historique des trades et aux analyses de marché sur plus de 1 700 échanges décentralisés.

Aperçu

L'API Solana de CoinGecko fournit :

  • Prix des tokens : Prix en temps réel par adresse de contrat (simple ou par lot)
  • Données des pools : Informations sur les pools de liquidité, pools tendance, top pools
  • Graphiques OHLCV : Données en chandelier pour l'analyse technique
  • Historique des trades : Trades récents pour n'importe quel pool
  • Découverte DEX : Lister tous les DEXes opérant sur Solana
  • Recherche : Trouver les pools par nom de token, symbole ou adresse
  • Megafilter : Filtrage avancé sur les pools, tokens et DEXes

Fonctionnalités clés

Fonctionnalité Description
250+ réseaux Support multi-chaînes incluant Solana
1 700+ DEXes Raydium, Orca, Jupiter, Meteora, Pump.fun, etc.
15 M+ tokens Couverture complète des tokens
Données en temps réel Mises à jour toutes les 10-30 secondes
Données historiques Graphiques OHLCV et historique des trades

Démarrage rapide

Obtenir votre clé API

  1. API démo (gratuit) : Visitez coingecko.com/en/api
  2. API Pro (payant) : Visitez coingecko.com/en/api/pricing

Configuration de l'environnement

# .env file
COINGECKO_API_KEY=your_api_key_here
COINGECKO_API_TYPE=demo  # or 'pro'

Configuration de l'API

// Configuration for both Demo and Pro APIs
const CONFIG = {
  demo: {
    baseUrl: 'https://api.coingecko.com/api/v3/onchain',
    headerKey: 'x-cg-demo-api-key',
    rateLimit: 30, // calls per minute
  },
  pro: {
    baseUrl: 'https://pro-api.coingecko.com/api/v3/onchain',
    headerKey: 'x-cg-pro-api-key',
    rateLimit: 500, // calls per minute (varies by plan)
  },
};

const apiType = process.env.COINGECKO_API_TYPE || 'demo';
const apiKey = process.env.COINGECKO_API_KEY;

const BASE_URL = CONFIG[apiType].baseUrl;
const HEADER_KEY = CONFIG[apiType].headerKey;

// Solana network identifier
const NETWORK = 'solana';

Récupération basique du prix des tokens

async function getTokenPrice(tokenAddress: string): Promise<number | null> {
  const url = `${BASE_URL}/simple/networks/${NETWORK}/token_price/${tokenAddress}`;

  const response = await fetch(url, {
    headers: {
      [HEADER_KEY]: apiKey,
      'Accept': 'application/json',
    },
  });

  if (!response.ok) {
    throw new Error(`API error: ${response.status}`);
  }

  const data = await response.json();
  return data.data?.attributes?.token_prices?.[tokenAddress] ?? null;
}

// Usage
const USDC = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
const price = await getTokenPrice(USDC);
console.log(`USDC Price: $${price}`);

Référence des endpoints de l'API

Prix simple des tokens

Obtenir les prix des tokens par adresse de contrat.

Endpoint : GET /simple/networks/{network}/token_price/{addresses}

Paramètres : | Paramètre | Type | Requis | Description | |-----------|------|--------|-------------| | network | string | Oui | ID du réseau (solana) | | addresses | string | Oui | Adresses de tokens séparées par des virgules (max 30 démo, 100 Pro) | | include_market_cap | boolean | Non | Inclure les données de capitalisation boursière | | include_24hr_vol | boolean | Non | Inclure le volume 24h | | include_24hr_price_change | boolean | Non | Inclure le % de variation de prix 24h |

async function getTokenPrices(addresses: string[]): Promise<Record<string, TokenPriceData>> {
  const addressList = addresses.join(',');
  const url = `${BASE_URL}/simple/networks/${NETWORK}/token_price/${addressList}`;

  const params = new URLSearchParams({
    include_market_cap: 'true',
    include_24hr_vol: 'true',
    include_24hr_price_change: 'true',
  });

  const response = await fetch(`${url}?${params}`, {
    headers: { [HEADER_KEY]: apiKey },
  });

  const data = await response.json();
  return data.data?.attributes || {};
}

Données des tokens par adresse

Obtenir les informations détaillées des tokens.

Endpoint : GET /networks/{network}/tokens/{address}

Paramètres : | Paramètre | Type | Requis | Description | |-----------|------|--------|-------------| | network | string | Oui | ID du réseau | | address | string | Oui | Adresse du contrat de token | | include | string | Non | Inclure top_pools pour les données de liquidité |

interface TokenData {
  address: string;
  name: string;
  symbol: string;
  decimals: number;
  image_url: string;
  price_usd: string;
  fdv_usd: string;
  market_cap_usd: string;
  total_supply: string;
  volume_usd: {
    h24: string;
  };
  price_change_percentage: {
    h24: string;
  };
}

async function getTokenData(address: string): Promise<TokenData> {
  const url = `${BASE_URL}/networks/${NETWORK}/tokens/${address}?include=top_pools`;

  const response = await fetch(url, {
    headers: { [HEADER_KEY]: apiKey },
  });

  const data = await response.json();
  return data.data?.attributes;
}

Données multi-tokens

Récupérer plusieurs tokens par lot.

Endpoint : GET /networks/{network}/tokens/multi/{addresses}

async function getMultipleTokens(addresses: string[]): Promise<TokenData[]> {
  const addressList = addresses.join(',');
  const url = `${BASE_URL}/networks/${NETWORK}/tokens/multi/${addressList}`;

  const response = await fetch(url, {
    headers: { [HEADER_KEY]: apiKey },
  });

  const data = await response.json();
  return data.data?.map((item: any) => item.attributes) || [];
}

Données des pools par adresse

Obtenir les informations détaillées des pools.

Endpoint : GET /networks/{network}/pools/{address}

Paramètres : | Paramètre | Type | Requis | Description | |-----------|------|--------|-------------| | include | string | Non | base_token, quote_token, dex | | include_volume_breakdown | boolean | Non | Ventilation du volume par période |

interface PoolData {
  address: string;
  name: string;
  pool_created_at: string;
  base_token_price_usd: string;
  quote_token_price_usd: string;
  base_token_price_native_currency: string;
  fdv_usd: string;
  market_cap_usd: string;
  reserve_in_usd: string;
  price_change_percentage: {
    m5: string;
    h1: string;
    h6: string;
    h24: string;
  };
  transactions: {
    m5: { buys: number; sells: number };
    h1: { buys: number; sells: number };
    h24: { buys: number; sells: number };
  };
  volume_usd: {
    m5: string;
    h1: string;
    h6: string;
    h24: string;
  };
}

async function getPoolData(poolAddress: string): Promise<PoolData> {
  const url = `${BASE_URL}/networks/${NETWORK}/pools/${poolAddress}`;

  const params = new URLSearchParams({
    include: 'base_token,quote_token,dex',
  });

  const response = await fetch(`${url}?${params}`, {
    headers: { [HEADER_KEY]: apiKey },
  });

  const data = await response.json();
  return data.data?.attributes;
}

Pools tendance

Obtenir les pools tendance sur tous les réseaux ou filtrés par réseau.

Endpoint : GET /networks/trending_pools

Paramètres : | Paramètre | Type | Défaut | Description | |-----------|------|--------|-------------| | include | string | base_token | Attributs à inclure | | page | integer | 1 | Numéro de page | | duration | string | 24h | 5m, 1h, 6h, 24h |

async function getTrendingPools(duration: '5m' | '1h' | '6h' | '24h' = '24h'): Promise<PoolData[]> {
  const url = `${BASE_URL}/networks/trending_pools`;

  const params = new URLSearchParams({
    include: 'base_token,quote_token,dex,network',
    duration,
    page: '1',
  });

  const response = await fetch(`${url}?${params}`, {
    headers: { [HEADER_KEY]: apiKey },
  });

  const data = await response.json();
  return data.data?.map((item: any) => item.attributes) || [];
}

// Filter for Solana pools
async function getSolanaTrendingPools(): Promise<PoolData[]> {
  const allPools = await getTrendingPools();
  return allPools.filter(pool => pool.network === 'solana');
}

Top pools du réseau

Obtenir les top pools par volume sur Solana.

Endpoint : GET /networks/{network}/pools

async function getTopPools(page: number = 1): Promise<PoolData[]> {
  const url = `${BASE_URL}/networks/${NETWORK}/pools`;

  const params = new URLSearchParams({
    include: 'base_token,quote_token,dex',
    page: page.toString(),
  });

  const response = await fetch(`${url}?${params}`, {
    headers: { [HEADER_KEY]: apiKey },
  });

  const data = await response.json();
  return data.data?.map((item: any) => item.attributes) || [];
}

Rechercher des pools

Rechercher des pools par nom de token, symbole ou adresse.

Endpoint : GET /search/pools

Paramètres : | Paramètre | Type | Description | |-----------|------|-------------| | query | string | Terme de recherche (nom, symbole, adresse) | | network | string | Filtrer par réseau | | page | integer | Numéro de page |

async function searchPools(query: string): Promise<PoolData[]> {
  const url = `${BASE_URL}/search/pools`;

  const params = new URLSearchParams({
    query,
    network: NETWORK,
    include: 'base_token,quote_token,dex',
  });

  const response = await fetch(`${url}?${params}`, {
    headers: { [HEADER_KEY]: apiKey },
  });

  const data = await response.json();
  return data.data?.map((item: any) => item.attributes) || [];
}

// Search for SOL pools
const solPools = await searchPools('SOL');

Graphique OHLCV des pools

Obtenir les données en chandelier pour l'analyse technique.

Endpoint : GET /networks/{network}/pools/{pool_address}/ohlcv/{timeframe}

Périodes : day, hour, minute

Paramètres : | Paramètre | Type | Description | |-----------|------|-------------| | aggregate | integer | Agrégation en chandelier (1, 5, 15 pour minute ; 1, 4, 12 pour hour) | | before_timestamp | integer | Timestamp Unix pour la pagination | | limit | integer | Nombre de chandeliers (max 1 000) | | currency | string | usd ou token |

interface OHLCVData {
  timestamp: number;
  open: number;
  high: number;
  low: number;
  close: number;
  volume: number;
}

async function getPoolOHLCV(
  poolAddress: string,
  timeframe: 'day' | 'hour' | 'minute' = 'hour',
  aggregate: number = 1,
  limit: number = 100
): Promise<OHLCVData[]> {
  const url = `${BASE_URL}/networks/${NETWORK}/pools/${poolAddress}/ohlcv/${timeframe}`;

  const params = new URLSearchParams({
    aggregate: aggregate.toString(),
    limit: limit.toString(),
    currency: 'usd',
  });

  const response = await fetch(`${url}?${params}`, {
    headers: { [HEADER_KEY]: apiKey },
  });

  const data = await response.json();

  return data.data?.attributes?.ohlcv_list?.map((candle: number[]) => ({
    timestamp: candle[0],
    open: candle[1],
    high: candle[2],
    low: candle[3],
    close: candle[4],
    volume: candle[5],
  })) || [];
}

// Get hourly candles
const hourlyCandles = await getPoolOHLCV(poolAddress, 'hour', 1, 24);

// Get 5-minute candles
const fiveMinCandles = await getPoolOHLCV(poolAddress, 'minute', 5, 100);

Trades récents

Obtenir les trades récents d'une pool.

Endpoint : GET /networks/{network}/pools/{pool_address}/trades

interface TradeData {
  block_number: number;
  block_timestamp: string;
  tx_hash: string;
  tx_from_address: string;
  from_token_amount: string;
  to_token_amount: string;
  price_from_in_currency_token: string;
  price_to_in_currency_token: string;
  price_from_in_usd: string;
  price_to_in_usd: string;
  kind: 'buy' | 'sell';
  volume_in_usd: string;
}

async function getRecentTrades(poolAddress: string): Promise<TradeData[]> {
  const url = `${BASE_URL}/networks/${NETWORK}/pools/${poolAddress}/trades`;

  const response = await fetch(url, {
    headers: { [HEADER_KEY]: apiKey },
  });

  const data = await response.json();
  return data.data?.map((item: any) => item.attributes) || [];
}

Lister les DEXes sur Solana

Obtenir tous les échanges décentralisés sur Solana.

Endpoint : GET /networks/{network}/dexes

interface DexData {
  id: string;
  name: string;
}

async function getSolanaDexes(): Promise<DexData[]> {
  const url = `${BASE_URL}/networks/${NETWORK}/dexes`;

  const response = await fetch(url, {
    headers: { [HEADER_KEY]: apiKey },
  });

  const data = await response.json();
  return data.data?.map((item: any) => ({
    id: item.id,
    name: item.attributes.name,
  })) || [];
}

Megafilter (avancé)

Filtrage avancé pour les pools sur tous les réseaux, DEXes et tokens.

Endpoint : GET /pools/megafilter

Paramètres : | Paramètre | Type | Description | |-----------|------|-------------| | networks | string | Filtrer par réseau(x) | | dexes | string | Filtrer par DEX(es) | | sort | string | Ordre de tri (ex., pool_created_at_desc) | | min_reserve_in_usd | number | Liquidité minimale | | min_h24_volume_usd | number | Volume 24h minimum |

async function getMegafilterPools(options: {
  dexes?: string[];
  minLiquidity?: number;
  minVolume?: number;
  sort?: string;
}): Promise<PoolData[]> {
  const url = `${BASE_URL}/pools/megafilter`;

  const params = new URLSearchParams({
    networks: NETWORK,
    page: '1',
  });

  if (options.dexes) {
    params.set('dexes', options.dexes.join(','));
  }
  if (options.minLiquidity) {
    params.set('min_reserve_in_usd', options.minLiquidity.toString());
  }
  if (options.minVolume) {
    params.set('min_h24_volume_usd', options.minVolume.toString());
  }
  if (options.sort) {
    params.set('sort', options.sort);
  }

  const response = await fetch(`${url}?${params}`, {
    headers: { [HEADER_KEY]: apiKey },
  });

  const data = await response.json();
  return data.data?.map((item: any) => item.attributes) || [];
}

// Get newest Pump.fun pools
const pumpfunPools = await getMegafilterPools({
  dexes: ['pump-fun'],
  sort: 'pool_created_at_desc',
});

// Get high-volume Raydium pools
const raydiumPools = await getMegafilterPools({
  dexes: ['raydium'],
  minVolume: 100000,
  minLiquidity: 50000,
});

Identifiants courants des DEXes Solana

DEX ID Description
Raydium raydium Leading AMM on Solana
Orca orca User-friendly DEX
Jupiter jupiter Aggregator with pools
Meteora meteora Dynamic AMM
Pump.fun pump-fun Memecoin launchpad
OpenBook openbook Order book DEX
Lifinity lifinity Proactive market maker
Phoenix phoenix On-chain order book

Adresses de tokens courants

Token Adresse
USDC EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
USDT Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB
SOL (Wrapped) So11111111111111111111111111111111111111112
JUP JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN
BONK DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263
WIF EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm
PYTH HZ1JovNiVvGrGNiiYvEozEVgZ58xaU3RKwX8eACQBCt3
RAY 4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R
ORCA orcaEKTdK7LKz57vaAYr9QeNsVEPfiu6QeMU1kektZE

Limites de débit

Plan Appels/minute Max adresses/requête
Démo (gratuit) 30 30
Analyst 500 50
Lite 500 50
Pro 1 000 100
Enterprise Personnalisé Personnalisé

Gestion des limites de débit

class RateLimiter {
  private calls: number[] = [];
  private maxCalls: number;
  private windowMs: number = 60000; // 1 minute

  constructor(maxCallsPerMinute: number) {
    this.maxCalls = maxCallsPerMinute;
  }

  async waitForSlot(): Promise<void> {
    const now = Date.now();
    this.calls = this.calls.filter(t => now - t < this.windowMs);

    if (this.calls.length >= this.maxCalls) {
      const oldestCall = this.calls[0];
      const waitTime = this.windowMs - (now - oldestCall);
      await new Promise(resolve => setTimeout(resolve, waitTime));
    }

    this.calls.push(Date.now());
  }
}

// Usage
const rateLimiter = new RateLimiter(30); // Demo API

async function fetchWithRateLimit(url: string): Promise<any> {
  await rateLimiter.waitForSlot();
  const response = await fetch(url, {
    headers: { [HEADER_KEY]: apiKey },
  });
  return response.json();
}

Gestion des erreurs

async function safeApiCall<T>(url: string): Promise<T | null> {
  try {
    const response = await fetch(url, {
      headers: { [HEADER_KEY]: apiKey },
    });

    if (response.status === 401) {
      throw new Error('Invalid API key');
    }
    if (response.status === 429) {
      throw new Error('Rate limit exceeded - wait before retrying');
    }
    if (response.status === 404) {
      console.warn('Resource not found');
      return null;
    }
    if (!response.ok) {
      throw new Error(`API error: ${response.status}`);
    }

    return response.json();
  } catch (error) {
    console.error('CoinGecko API error:', error);
    throw error;
  }
}

Codes d'erreur courants

Code Signification Solution
401 Clé API invalide Vérifier votre clé API
429 Limite de débit dépassée Attendre et relancer, ou augmenter le plan
404 Ressource non trouvée Vérifier l'adresse/ID réseau
500+ Erreur serveur Relancer avec backoff exponentiel

Bonnes pratiques

Sécurité

  • Ne jamais valider les clés API vers git
  • Utiliser des variables d'environnement
  • Rotation des clés périodiquement
  • Utiliser des clés séparées pour dev/prod

Performance

  • Regrouper les requêtes de tokens si possible
  • Mettre en cache les données fréquemment accessibles
  • Utiliser les bonnes périodes pour l'OHLCV
  • Implémenter une mise en file d'attente des requêtes pour les limites de débit

Qualité des données

  • Vérifier les données de capitalisation boursière (peut être null si non vérifié)
  • Vérifier la liquidité des pools avant de faire confiance aux prix
  • Utiliser plusieurs périodes pour l'analyse des prix
  • Surveiller le timestamp du dernier trade pour l'activité

Ressources


Structure des compétences

coingecko/
├── SKILL.md                      # This file
├── resources/
│   ├── api-reference.md          # Complete API endpoint reference
│   ├── network-dex-ids.md        # Solana network and DEX identifiers
│   └── token-addresses.md        # Common Solana token addresses
├── examples/
│   ├── token-prices/
│   │   └── get-token-price.ts    # Token price examples
│   ├── pools/
│   │   └── pool-data.ts          # Pool data examples
│   ├── ohlcv/
│   │   └── ohlcv-charts.ts       # OHLCV chart examples
│   ├── trades/
│   │   └── recent-trades.ts      # Trade history examples
│   └── integration/
│       └── full-client.ts        # Complete client example
├── templates/
│   └── coingecko-client.ts       # Production-ready client template
└── docs/
    └── troubleshooting.md        # Common issues and solutions

Vérifier

  • Un appel RPC/SDK réel a été émis (mainnet, devnet ou validateur local) et la charge utile de réponse est capturée dans la transcription, non seulement paraphrasée
  • Chaque transaction a été simulée (simulateTransaction ou équivalent) avant toute étape de signature/envoi ; les journaux de simulation sont joints
  • Pour toute transaction signée/envoyée, la signature résultante est enregistrée et confirmée en chaîne (statut renvoyé par getSignatureStatuses ou une URL explorateur)
  • Le slippage, les frais de priorité et les limites d'unités de calcul ont été définis explicitement avec des valeurs numériques concrètes, et non laissés aux défauts de la bibliothèque
  • Les adresses de comptes, les mints et les ID de programmes utilisés dans l'exécution correspondent aux adresses coingecko-market-data documentées pour le cluster ciblé (pas de mélange mainnet/devnet)
  • Le chemin d'échec a été exercé au moins une fois (solde insuffisant, oracle obsolète, blockhash expiré, etc.) et la gestion des erreurs de l'agent a produit un message lisible

Skills similaires