From a90b1707bbc3452e4bc5ad73ff11913cd093101b Mon Sep 17 00:00:00 2001 From: mstfyldz Date: Sat, 14 Mar 2026 00:49:48 +0300 Subject: [PATCH] fix: resolve solana rent exempt simulation error when sweeping native full balances --- debug_latest.js | 87 ++++++++++++++++++++++++++++++++++++++++++++ lib/crypto-engine.ts | 6 ++- test_sweep_api.js | 39 ++++++++++++++++++++ test_sweep_native.ts | 29 +++++++++++++++ 4 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 debug_latest.js create mode 100644 test_sweep_api.js create mode 100644 test_sweep_native.ts diff --git a/debug_latest.js b/debug_latest.js new file mode 100644 index 0000000..7ffbe63 --- /dev/null +++ b/debug_latest.js @@ -0,0 +1,87 @@ + +const { Client } = require('pg'); +const { Connection, PublicKey } = require('@solana/web3.js'); + +async function debugLatestPending() { + const client = new Client({ connectionString: process.env.DATABASE_URL }); + await client.connect(); + + const connection = new Connection('https://api.devnet.solana.com', 'confirmed'); + + // Get the most recent pending transaction + const res = await client.query(` + SELECT id, source_ref_id, amount, currency, metadata, created_at + FROM transactions + WHERE status IN ('pending', 'waiting') + ORDER BY created_at DESC + LIMIT 1 + `); + + if (res.rows.length === 0) { + console.log("No pending transactions found."); + await client.end(); + return; + } + + const tx = res.rows[0]; + console.log(`\n--- Most Recent Pending TX: ${tx.source_ref_id} (${tx.id}) ---`); + console.log(`Created At: ${tx.created_at}`); + console.log(`Amount: ${tx.amount} ${tx.currency}`); + + const solAddr = tx.metadata?.wallets?.SOLANA?.address; + + if (!solAddr) { + console.log("❌ No Solana wallet found for this transaction."); + await client.end(); + return; + } + console.log(`Wallet Address: ${solAddr}`); + + // Try to calculate expected amount + let expectedSolAmount = "Unknown"; + try { + const tryRes = await fetch(`https://api.binance.com/api/v3/ticker/price?symbol=USDTTRY`); + const tryData = await tryRes.json(); + const usdTryPrice = parseFloat(tryData.price); + + const solRes = await fetch(`https://api.binance.com/api/v3/ticker/price?symbol=SOLUSDT`); + const solData = await solRes.json(); + const solUsdPrice = parseFloat(solData.price); + + const priceInTry = solUsdPrice * usdTryPrice; + const rawExpected = parseFloat(tx.amount) / priceInTry; + expectedSolAmount = (rawExpected * 0.98).toFixed(6); + console.log(`Current SOL Price: ~${priceInTry.toFixed(2)} TRY`); + console.log(`Expected Min: ${expectedSolAmount} SOL`); + } catch (e) { + console.log("Price fetch failed"); + } + + // Check Actual Balance + try { + const pubKey = new PublicKey(solAddr); + const balance = await connection.getBalance(pubKey); + const actualSol = balance / 1e9; + console.log(`Actual Wallet Balance: ${actualSol} SOL`); + + if (actualSol >= parseFloat(expectedSolAmount || "0")) { + console.log("✅ VERIFICATION SHOULD PASS!"); + } else { + console.log("❌ VERIFICATION FAILED: Insufficient balance."); + } + + // Find recent signatures to see if a payment was attempted + const signatures = await connection.getSignaturesForAddress(pubKey, { limit: 5 }); + console.log(`Recent Signatures: ${signatures.length}`); + if(signatures.length > 0) { + console.log(signatures.map(s => s.signature).join('\n')); + } + + } catch(e) { + console.error("Error checking Solana balance:", e); + } + + await client.end(); +} + +debugLatestPending(); diff --git a/lib/crypto-engine.ts b/lib/crypto-engine.ts index c6036f2..1af367a 100644 --- a/lib/crypto-engine.ts +++ b/lib/crypto-engine.ts @@ -264,9 +264,11 @@ export class CryptoEngine { const destPubKey = new PublicKey(destinationAddress); if (tokenSymbol === 'SOL' || tokenSymbol === 'NATIVE') { - // Get balance and send almost all (leave 5000 lamports for rent) + // Get balance and send almost all (leave exactly 0 to avoid rent-exempt errors) + // A standard Solana signature costs exactly 5000 lamports const balance = await this.solConnection.getBalance(senderKeypair.publicKey); - const sendAmount = balance - 10000; // leave 0.00001 SOL for fees + const fee = 5000; + const sendAmount = balance - fee; if (sendAmount <= 0) { return { success: false, txHash: null, error: 'Insufficient SOL balance' }; diff --git a/test_sweep_api.js b/test_sweep_api.js new file mode 100644 index 0000000..0cd218e --- /dev/null +++ b/test_sweep_api.js @@ -0,0 +1,39 @@ + +const { CryptoEngine } = require('./lib/crypto-engine'); +const { Client } = require('pg'); + +async function testSweepAPI() { + const client = new Client({ connectionString: process.env.DATABASE_URL }); + await client.connect(); + + // Get the most recent pending tx + const res = await client.query("SELECT * FROM transactions WHERE status IN ('pending', 'waiting') ORDER BY created_at DESC LIMIT 1"); + if(res.rows.length === 0) return console.log("No pending"); + + const tx = res.rows[0]; + const wallets = tx.metadata?.wallets || {}; + const solWallet = wallets['SOLANA']; + + console.log("Found TX:", tx.id, "Address:", solWallet.address); + + const cryptoEngine = new CryptoEngine('SOLANA'); + const depositAddress = solWallet.address; + const depositPrivateKey = solWallet.privateKey; + + // Check verify explicitly + const actualVerification = await cryptoEngine.verifyPayment(depositAddress, "0.295226", "SOL"); + console.log("Verify result:", actualVerification); + + if(actualVerification.success) { + console.log("Attempting sweep..."); + try { + const platformAddress = "Ajr4nKieZJVu9q2d1eVF9pQPRCLoZ6v4tapB3iQn2SyQ"; + const sweepResult = await cryptoEngine.sweepFunds(depositPrivateKey, platformAddress, "SOL"); + console.log("Sweep result:", sweepResult); + } catch(e) { + console.error("Sweep threw error:", e); + } + } + await client.end(); +} +testSweepAPI(); diff --git a/test_sweep_native.ts b/test_sweep_native.ts new file mode 100644 index 0000000..cda520c --- /dev/null +++ b/test_sweep_native.ts @@ -0,0 +1,29 @@ + +import { CryptoEngine } from './lib/crypto-engine'; +import { db } from './lib/db'; + +async function testSweep() { + console.log("Starting test..."); + const result = await db.query("SELECT * FROM transactions WHERE status IN ('pending', 'waiting') ORDER BY created_at DESC LIMIT 1"); + if(result.rows.length === 0) return console.log("No pending"); + + const tx = result.rows[0]; + const wallets = tx.metadata?.wallets || {}; + const solWallet = wallets['SOLANA']; + + console.log("Found TX:", tx.id, "Address:", solWallet.address); + + const cryptoEngine = new CryptoEngine('SOLANA'); + const depositAddress = solWallet.address; + const depositPrivateKey = solWallet.privateKey; + + const verification = await cryptoEngine.verifyPayment(depositAddress, "0.295226", "SOL"); + console.log("Verify:", verification); + + if(verification.success) { + console.log("Sweeping..."); + const res = await cryptoEngine.sweepFunds(depositPrivateKey, "Ajr4nKieZJVu9q2d1eVF9pQPRCLoZ6v4tapB3iQn2SyQ", "SOL"); + console.log("Result:", res); + } +} +testSweep().then(() => process.exit(0)).catch(e => { console.error(e); process.exit(1); });