import 'dotenv/config';
const API_KEY = process.env.GIGABRAIN_API_KEY;
const BASE_URL = "https://api.gigabrain.gg";
async function getFundingRates() {
const response = await fetch(`${BASE_URL}/v1/chat`, {
method: "POST",
headers: {
"Authorization": `Bearer ${API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
message: "Get funding rates for top 20 perpetual contracts. Respond as JSON array with: symbol, funding_rate, open_interest, long_short_ratio"
}),
signal: AbortSignal.timeout(600000),
});
if (response.status === 200) {
const data = await response.json();
return JSON.parse(data.content);
} else if (response.status === 429) {
const retryAfter = response.headers.get("Retry-After") || 60;
console.log(`Rate limited. Retrying after ${retryAfter}s`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
return getFundingRates();
} else {
throw new Error(`API Error: ${response.status}`);
}
}
function checkExtremeFunding(fundingData, threshold = 0.03) {
const alerts = [];
for (const token of fundingData) {
const rate = token.funding_rate;
if (Math.abs(rate) > threshold) {
const direction = rate > 0 ? "LONG" : "SHORT";
alerts.push({
symbol: token.symbol,
funding_rate: rate,
direction,
open_interest: token.open_interest,
long_short_ratio: token.long_short_ratio
});
}
}
return alerts;
}
async function main() {
console.log("🧠 Gigabrain Funding Rate Monitor");
console.log("=".repeat(50));
const fundingData = await getFundingRates();
const alerts = checkExtremeFunding(fundingData, 0.02);
if (alerts.length > 0) {
console.log(`\n⚠️ ${alerts.length} EXTREME FUNDING ALERTS:`);
for (const alert of alerts) {
console.log(`\n${alert.symbol}:`);
console.log(` Funding Rate: ${(alert.funding_rate * 100).toFixed(4)}%`);
console.log(` Direction: ${alert.direction} crowded`);
console.log(` Open Interest: $${alert.open_interest.toLocaleString()}`);
console.log(` Long/Short Ratio: ${alert.long_short_ratio || 'N/A'}`);
}
} else {
console.log("\n✅ No extreme funding rates detected");
}
}
main().catch(console.error);