From e66264219d71e20ec76d817146144b8e28555e82 Mon Sep 17 00:00:00 2001 From: mstfyldz Date: Fri, 13 Mar 2026 05:39:47 +0300 Subject: [PATCH] fix: improve price fetching reliability in sync worker with Binance API and fallbacks --- check_status.js | 10 ++++++ lib/sync-worker.ts | 41 ++++++++++++++++------- simulate_sync.js | 81 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 check_status.js create mode 100644 simulate_sync.js diff --git a/check_status.js b/check_status.js new file mode 100644 index 0000000..7d3bcc9 --- /dev/null +++ b/check_status.js @@ -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(); diff --git a/lib/sync-worker.ts b/lib/sync-worker.ts index e3ae630..97a6360 100644 --- a/lib/sync-worker.ts +++ b/lib/sync-worker.ts @@ -87,23 +87,40 @@ export async function syncPendingPayments() { let expectedCryptoAmount = tx.amount.toString(); try { - const coinIdMap: Record = { - 'SOL': 'solana', 'MATIC': 'matic-network', 'POLYGON': 'matic-network', - 'USDC': 'usd-coin', 'USDT': 'tether', 'TRX': 'tron', 'BTC': 'bitcoin' + const symbolMap: Record = { + 'SOL': 'SOLUSDT', 'MATIC': 'MATICUSDT', 'POLYGON': 'MATICUSDT', + 'USDC': 'USDCUSDT', 'USDT': 'USDTUSDT', 'TRX': 'TRXUSDT' }; - 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']; + const pair = symbolMap[tokenSymbol] || 'SOLUSDT'; + + // 1. Get USD/TRY rate + const tryRes = await fetch(`https://api.binance.com/api/v3/ticker/price?symbol=USDTTRY`); + const tryData = await tryRes.json(); + const usdTryPrice = parseFloat(tryData.price) || 32.5; - if (priceInCurrency) { - const rawExpected = parseFloat(tx.amount) / priceInCurrency; + // 2. Get Crypto/USD rate + 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); + console.log(`[SyncWorker] Price for ${tokenSymbol}: ${priceInTarget.toFixed(2)} ${currency} | Expected: ${expectedCryptoAmount}`); } } 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 = { '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); diff --git a/simulate_sync.js b/simulate_sync.js new file mode 100644 index 0000000..78f2034 --- /dev/null +++ b/simulate_sync.js @@ -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();