fix(deposits): stop sending an empty TronGrid key and log TronGrid failures (#32)

Both TRC20 deposit functions sent `TRON-PRO-API-KEY: ''` when the key was
unset, and check-deposits returned silently on any non-2xx TronGrid
response, so a 401 or 429 skipped a user's deposits with nothing in the
logs.

- send the key header only when TRONGRID_API_KEY is set; warn once if not
- check-deposits logs the status and deposit index on a failed call
- process-deposits records the TronGrid status in results.trc20.errors
- type the batch item in check-deposits (deno check TS7006, pre-existing)
This commit is contained in:
SatoshiQaziMuhammed authored and GitHub committed 2026-10-17 20:46:08 +04:00
1 parent 92b4a70cca
commit a08754f705
2 files changed
+37 -4

No files matched your search

+20 -3
View File
@@ -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<string, string> {
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 || [];
+17 -1
View File
@@ -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<string, string> {
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}`);