diff --git a/supabase/functions/check-deposits/index.ts b/supabase/functions/check-deposits/index.ts index 214edef..184199f 100644 --- a/supabase/functions/check-deposits/index.ts +++ b/supabase/functions/check-deposits/index.ts @@ -24,6 +24,20 @@ const TRC20_FEE = 3; // $3 fee for TRC20 // API endpoints const TON_API = 'https://tonapi.io/v2'; const TRON_API = 'https://api.trongrid.io'; + +// Keyless TronGrid calls share a low public rate limit, so a missing key must +// show up in the logs rather than go out as an empty header. +let warnedNoTronKey = false; +function tronHeaders(): Record { + const key = Deno.env.get('TRONGRID_API_KEY'); + if (key) return { 'TRON-PRO-API-KEY': key }; + if (!warnedNoTronKey) { + console.warn('TRONGRID_API_KEY is not set; TronGrid calls are unauthenticated'); + warnedNoTronKey = true; + } + return {}; +} + const SUBSCAN_API = 'https://assethub-polkadot.api.subscan.io'; // Contract addresses - raw format from TonAPI @@ -274,7 +288,7 @@ async function checkTrc20Deposits( for (let i = 0; i < users.length; i += CONCURRENCY) { const batch = users.slice(i, i + CONCURRENCY); await Promise.all( - batch.map(async (user) => { + batch.map(async (user: { id: string; deposit_index: number }) => { try { const address = deriveTronAddress(hdMnemonic, user.deposit_index); @@ -282,11 +296,14 @@ async function checkTrc20Deposits( const response = await fetch( `${TRON_API}/v1/accounts/${address}/transactions/trc20?limit=20&contract_address=${TRON_USDT_CONTRACT}`, { - headers: { 'TRON-PRO-API-KEY': Deno.env.get('TRONGRID_API_KEY') || '' }, + headers: tronHeaders(), } ); - if (!response.ok) return; + if (!response.ok) { + console.error(`TronGrid ${response.status} for deposit index ${user.deposit_index}`); + return; + } const data = await response.json(); const transfers = data.data || []; diff --git a/supabase/functions/process-deposits/index.ts b/supabase/functions/process-deposits/index.ts index ef2db25..a4a449d 100644 --- a/supabase/functions/process-deposits/index.ts +++ b/supabase/functions/process-deposits/index.ts @@ -8,6 +8,20 @@ import { serve } from 'https://deno.land/std@0.177.0/http/server.ts'; import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'; const TRON_API = 'https://api.trongrid.io'; + +// Keyless TronGrid calls share a low public rate limit, so a missing key must +// show up in the logs rather than go out as an empty header. +let warnedNoTronKey = false; +function tronHeaders(): Record { + const key = Deno.env.get('TRONGRID_API_KEY'); + if (key) return { 'TRON-PRO-API-KEY': key }; + if (!warnedNoTronKey) { + console.warn('TRONGRID_API_KEY is not set; TronGrid calls are unauthenticated'); + warnedNoTronKey = true; + } + return {}; +} + const USDT_TRC20_CONTRACT = 'TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t'; // USDT TRC20 contract interface TRC20Transfer { @@ -78,7 +92,7 @@ serve(async (req) => { const response = await fetch( `${TRON_API}/v1/accounts/${tronAddress}/transactions/trc20?limit=50&contract_address=${USDT_TRC20_CONTRACT}`, { - headers: { 'TRON-PRO-API-KEY': Deno.env.get('TRONGRID_API_KEY') || '' }, + headers: tronHeaders(), } ); @@ -125,6 +139,8 @@ serve(async (req) => { results.trc20.processed++; } } + } else { + results.trc20.errors.push(`TronGrid HTTP ${response.status}`); } } catch (err) { results.trc20.errors.push(`TRC20 error: ${err}`);