get_airdrops
Fetch and filter cryptocurrency airdrop data from DeFiLlama. Retrieve active airdrops, filter by blockchain, and refresh cached data for updated results.
Instructions
Buscar todos os airdrops disponíveis no DeFiLlama
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| chain | No | Filtrar por blockchain específica | |
| forceRefresh | No | Forçar atualização dos dados (ignorar cache) | |
| onlyActive | No | Retornar apenas airdrops ativos |
Implementation Reference
- src/index.ts:154-188 (handler)The main handler for the 'get_airdrops' tool. Manages caching with a 5-minute timeout, scrapes fresh data from DeFiLlama if needed using the scraper, applies optional filters for active airdrops and specific chains, and returns a JSON-formatted response with total count, last update time, and the list of airdrops.private async getAirdrops(args: { forceRefresh?: boolean; onlyActive?: boolean; chain?: string }) { const shouldRefresh = args.forceRefresh || !this.lastUpdate || (Date.now() - this.lastUpdate.getTime()) > this.cacheTimeout; if (shouldRefresh) { console.log('Atualizando cache de airdrops...'); this.cachedAirdrops = await this.scraper.scrapeAirdrops(); this.lastUpdate = new Date(); } let airdrops = [...this.cachedAirdrops]; // Aplicar filtros if (args.onlyActive) { airdrops = airdrops.filter(a => a.status?.toLowerCase().includes('active') || a.status?.toLowerCase().includes('ativo')); } if (args.chain) { airdrops = airdrops.filter(a => a.chain?.toLowerCase().includes(args.chain!.toLowerCase())); } return { content: [ { type: 'text', text: JSON.stringify({ total: airdrops.length, lastUpdate: this.lastUpdate?.toISOString(), airdrops: airdrops }, null, 2) } ] }; }
- src/index.ts:40-62 (registration)Registration of the 'get_airdrops' tool in the ListToolsRequestSchema handler, including name, description, and input schema definition.{ name: 'get_airdrops', description: 'Buscar todos os airdrops disponíveis no DeFiLlama', inputSchema: { type: 'object', properties: { forceRefresh: { type: 'boolean', description: 'Forçar atualização dos dados (ignorar cache)', default: false }, onlyActive: { type: 'boolean', description: 'Retornar apenas airdrops ativos', default: false }, chain: { type: 'string', description: 'Filtrar por blockchain específica' } } } },
- src/index.ts:125-126 (registration)Registration in the CallToolRequestSchema switch statement that routes calls to the getAirdrops handler.case 'get_airdrops': return await this.getAirdrops(args as any);
- src/types.ts:3-25 (schema)Zod schema defining the structure of Airdrop objects used throughout the codebase for type safety and validation.export const AirdropSchema = z.object({ name: z.string(), description: z.string().optional(), value: z.string().optional(), status: z.string(), deadline: z.string().optional(), requirements: z.array(z.string()).optional(), url: z.string().optional(), category: z.string().optional(), chain: z.string().optional(), estimatedValue: z.string().optional(), difficulty: z.string().optional(), lastUpdated: z.string().optional(), // Novos campos DeFiLlama tvl: z.string().optional(), listedAt: z.string().optional(), change1d: z.string().optional(), change7d: z.string().optional(), change1m: z.string().optional(), logo: z.string().optional(), symbol: z.string().optional(), mcap: z.string().optional() });
- src/scraper.ts:104-139 (helper)Core helper function scrapeAirdrops() called by the handler to fetch airdrop data. Attempts direct page scraping with Cheerio, falls back to DeFiLlama protocols API conversion, and uses hardcoded fallback data if all else fails.async scrapeAirdrops(options: ScrapingOptions = {}): Promise<Airdrop[]> { try { console.log('🚀 Fazendo scraping da página de airdrops DeFiLlama...'); // Tentar múltiplas abordagens para obter dados de airdrops let airdrops: Airdrop[] = []; try { // Primeira tentativa: scraping direto da página airdrops = await this.scrapeAirdropsPage(); if (airdrops.length > 0) { console.log(`✅ Extraídos ${airdrops.length} airdrops via scraping direto`); return airdrops; } } catch (error) { console.log('⚠️ Scraping direto falhou, tentando API alternativa...'); } try { // Segunda tentativa: usar API de protocolos e inferir airdrops const protocols = await this.scrapeProtocols(); airdrops = await this.convertProtocolsToAirdrops(protocols); console.log(`✅ Gerados ${airdrops.length} airdrops potenciais via API`); return airdrops; } catch (error) { console.log('⚠️ API de protocolos falhou, usando dados de exemplo...'); } // Fallback: dados conhecidos de airdrops reais return this.getFallbackAirdrops(); } catch (error) { console.error('❌ Erro durante scraping:', error); return this.getFallbackAirdrops(); } }