fix: improve price fetching reliability in sync worker with Binance API and fallbacks
This commit is contained in:
10
check_status.js
Normal file
10
check_status.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
const { Client } = require('pg');
|
||||||
|
async function checkStatus() {
|
||||||
|
const client = new Client({ connectionString: process.env.DATABASE_URL });
|
||||||
|
await client.connect();
|
||||||
|
const res = await client.query("SELECT id, source_ref_id, status FROM transactions WHERE source_ref_id IN ('TEST_ORDER_999', 'TEST_ORDER_1000')");
|
||||||
|
console.log(JSON.stringify(res.rows, null, 2));
|
||||||
|
await client.end();
|
||||||
|
}
|
||||||
|
checkStatus();
|
||||||
@@ -87,23 +87,40 @@ export async function syncPendingPayments() {
|
|||||||
|
|
||||||
let expectedCryptoAmount = tx.amount.toString();
|
let expectedCryptoAmount = tx.amount.toString();
|
||||||
try {
|
try {
|
||||||
const coinIdMap: Record<string, string> = {
|
const symbolMap: Record<string, string> = {
|
||||||
'SOL': 'solana', 'MATIC': 'matic-network', 'POLYGON': 'matic-network',
|
'SOL': 'SOLUSDT', 'MATIC': 'MATICUSDT', 'POLYGON': 'MATICUSDT',
|
||||||
'USDC': 'usd-coin', 'USDT': 'tether', 'TRX': 'tron', 'BTC': 'bitcoin'
|
'USDC': 'USDCUSDT', 'USDT': 'USDTUSDT', 'TRX': 'TRXUSDT'
|
||||||
};
|
};
|
||||||
const coinId = coinIdMap[tokenSymbol] || 'solana';
|
const pair = symbolMap[tokenSymbol] || 'SOLUSDT';
|
||||||
const priceUrl = `https://api.coingecko.com/api/v3/simple/price?ids=${coinId}&vs_currencies=usd,try`;
|
|
||||||
const priceRes = await fetch(priceUrl);
|
// 1. Get USD/TRY rate
|
||||||
const priceData = await priceRes.json();
|
const tryRes = await fetch(`https://api.binance.com/api/v3/ticker/price?symbol=USDTTRY`);
|
||||||
const currencyKey = (tx.currency || 'TRY').toLowerCase();
|
const tryData = await tryRes.json();
|
||||||
const priceInCurrency = priceData[coinId][currencyKey] || priceData[coinId]['usd'];
|
const usdTryPrice = parseFloat(tryData.price) || 32.5;
|
||||||
|
|
||||||
if (priceInCurrency) {
|
// 2. Get Crypto/USD rate
|
||||||
const rawExpected = parseFloat(tx.amount) / priceInCurrency;
|
let cryptoUsdPrice = 1.0;
|
||||||
|
if (pair !== 'USDTUSDT' && pair !== 'USDCUSDT') {
|
||||||
|
const cryptoRes = await fetch(`https://api.binance.com/api/v3/ticker/price?symbol=${pair}`);
|
||||||
|
const cryptoData = await cryptoRes.json();
|
||||||
|
cryptoUsdPrice = parseFloat(cryptoData.price) || 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const priceInTry = cryptoUsdPrice * usdTryPrice;
|
||||||
|
const currency = (tx.currency || 'TRY').toUpperCase();
|
||||||
|
const priceInTarget = currency === 'USD' ? cryptoUsdPrice : priceInTry;
|
||||||
|
|
||||||
|
if (priceInTarget > 0) {
|
||||||
|
const rawExpected = parseFloat(tx.amount) / priceInTarget;
|
||||||
expectedCryptoAmount = (rawExpected * 0.98).toFixed(6);
|
expectedCryptoAmount = (rawExpected * 0.98).toFixed(6);
|
||||||
|
console.log(`[SyncWorker] Price for ${tokenSymbol}: ${priceInTarget.toFixed(2)} ${currency} | Expected: ${expectedCryptoAmount}`);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn(`[SyncWorker] Price fetch failed for ${tokenSymbol}, using raw amount.`);
|
console.warn(`[SyncWorker] Price fetch failed for ${tokenSymbol}, using backup static rates.`);
|
||||||
|
// Absolute fallback for safety
|
||||||
|
const staticRates: Record<string, number> = { 'SOL': 4000, 'USDT': 33, 'USDC': 33, 'TRX': 5, 'MATIC': 25 };
|
||||||
|
const rate = staticRates[tokenSymbol] || 1;
|
||||||
|
expectedCryptoAmount = (parseFloat(tx.amount) / rate * 0.95).toFixed(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
const verification = await cryptoEngine.verifyPayment(depositAddress, expectedCryptoAmount, tokenSymbol);
|
const verification = await cryptoEngine.verifyPayment(depositAddress, expectedCryptoAmount, tokenSymbol);
|
||||||
|
|||||||
81
simulate_sync.js
Normal file
81
simulate_sync.js
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
const { Client } = require('pg');
|
||||||
|
const { Connection, PublicKey } = require('@solana/web3.js');
|
||||||
|
const { CryptoEngine } = require('./lib/crypto-engine');
|
||||||
|
|
||||||
|
async function simulateSync() {
|
||||||
|
const client = new Client({ connectionString: process.env.DATABASE_URL });
|
||||||
|
await client.connect();
|
||||||
|
|
||||||
|
const res = await client.query(`
|
||||||
|
SELECT * FROM transactions
|
||||||
|
WHERE source_ref_id IN ('TEST_ORDER_999', 'TEST_ORDER_1000')
|
||||||
|
`);
|
||||||
|
|
||||||
|
console.log(`Simulating sync for ${res.rows.length} transactions...`);
|
||||||
|
|
||||||
|
for (const tx of res.rows) {
|
||||||
|
console.log(`\n>> Processing TX: ${tx.id} (${tx.source_ref_id}) | Current Status: ${tx.status}`);
|
||||||
|
const metadata = tx.metadata || {};
|
||||||
|
const wallets = metadata.wallets || {};
|
||||||
|
|
||||||
|
console.log("Wallets in metadata:", Object.keys(wallets));
|
||||||
|
|
||||||
|
const scanningMatrix = [
|
||||||
|
{ network: 'SOLANA', tokens: ['SOL', 'USDT', 'USDC'] },
|
||||||
|
{ network: 'POLYGON', tokens: ['MATIC', 'USDT', 'USDC'] },
|
||||||
|
{ network: 'TRON', tokens: ['TRX', 'USDT', 'USDC'] }
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const scan of scanningMatrix) {
|
||||||
|
const networkId = scan.network;
|
||||||
|
const walletConfig = wallets[networkId] || (networkId === 'POLYGON' ? wallets['EVM'] : null);
|
||||||
|
|
||||||
|
if (!walletConfig) {
|
||||||
|
console.log(`[${networkId}] Skiped: No wallet config found.`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[${networkId}] Found wallet config. Address: ${typeof walletConfig === 'string' ? walletConfig : walletConfig.address}`);
|
||||||
|
|
||||||
|
const cryptoEngine = new CryptoEngine(networkId);
|
||||||
|
|
||||||
|
for (const tokenSymbol of scan.tokens) {
|
||||||
|
console.log(` [${networkId}/${tokenSymbol}] Verifying...`);
|
||||||
|
|
||||||
|
let expectedCryptoAmount = tx.amount.toString();
|
||||||
|
try {
|
||||||
|
const coinIdMap = {
|
||||||
|
'SOL': 'solana', 'MATIC': 'matic-network', 'POLYGON': 'matic-network',
|
||||||
|
'USDC': 'usd-coin', 'USDT': 'tether', 'TRX': 'tron', 'BTC': 'bitcoin'
|
||||||
|
};
|
||||||
|
const coinId = coinIdMap[tokenSymbol] || 'solana';
|
||||||
|
const priceUrl = `https://api.coingecko.com/api/v3/simple/price?ids=${coinId}&vs_currencies=usd,try`;
|
||||||
|
const priceRes = await fetch(priceUrl);
|
||||||
|
const priceData = await priceRes.json();
|
||||||
|
const currencyKey = (tx.currency || 'TRY').toLowerCase();
|
||||||
|
const priceInCurrency = priceData[coinId][currencyKey] || priceData[coinId]['usd'];
|
||||||
|
|
||||||
|
if (priceInCurrency) {
|
||||||
|
const rawExpected = parseFloat(tx.amount) / priceInCurrency;
|
||||||
|
expectedCryptoAmount = (rawExpected * 0.98).toFixed(6);
|
||||||
|
console.log(` Expected Min: ${expectedCryptoAmount} ${tokenSymbol} (Price: ${priceInCurrency})`);
|
||||||
|
}
|
||||||
|
} catch (e) { console.log(" Price fetch failed."); }
|
||||||
|
|
||||||
|
const depositAddress = typeof walletConfig === 'string' ? walletConfig : walletConfig.address;
|
||||||
|
const verification = await cryptoEngine.verifyPayment(depositAddress, expectedCryptoAmount, tokenSymbol);
|
||||||
|
|
||||||
|
if (verification.success) {
|
||||||
|
console.log(` ✅ PAYMENT DETECTED!`);
|
||||||
|
} else {
|
||||||
|
console.log(` ❌ No payment found.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await client.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
simulateSync();
|
||||||
Reference in New Issue
Block a user