diff --git a/src/services/wallets/factories/USDTWalletFactory.ts b/src/services/wallets/factories/USDTWalletFactory.ts index 2b2744abf..46f3fd2f8 100644 --- a/src/services/wallets/factories/USDTWalletFactory.ts +++ b/src/services/wallets/factories/USDTWalletFactory.ts @@ -262,29 +262,40 @@ export const syncUSDTWalletTransactions = async (wallet: USDTWallet) => { }) ); + const existingTransactionsCache: { [txid: string]: number } = {}; // Cache for existing transactions by txId, helps to search by txId quickly + updatedExistingTransactions.forEach((existingTx, idx) => { + if (existingTx.txId) { + existingTransactionsCache[existingTx.txId] = idx; + } + }); + // Step 2: Fetch new transactions from USDT service - const { transactions: newTransactions } = await USDT.getUSDTTransactions( + const { transactions: latestTransactions } = await USDT.getUSDTTransactions( wallet.accountStatus.gasFreeAddress, wallet.networkType ); - // Step 3: Merge transactions using updated existing transactions - const mergedTransactions = [...updatedExistingTransactions]; - - // Process each new transaction - newTransactions.forEach((newTx) => { + // Step 3: Filter out gas-free fee transactions + // We will keep these transactions separately to avoid duplicates + const newGasFreeFeeTransactions: { [key: string]: USDTTransaction } = {}; + const newTransactions: USDTTransaction[] = []; // contains new transactions that are not gas-free fee transfers + for (let newTx of latestTransactions) { if ( newTx.from === wallet.accountStatus.gasFreeAddress && newTx.to === USDT.getUSDTGasFreeFeeAddress(wallet.networkType) ) { // Skip transactions that are just gas-free fees transfer to service provider(duplicate) - return; + newGasFreeFeeTransactions[newTx.txId] = newTx; + } else { + newTransactions.push(newTx); } + } - const existingIndex = updatedExistingTransactions.findIndex((existingTx) => { - return newTx.txId && existingTx.txId && newTx.txId === existingTx.txId; - }); - + // Step 4: Merge transactions using updated existing transactions + const mergedTransactions = [...updatedExistingTransactions]; + // Process each new transaction and create a unified transaction list + newTransactions.forEach((newTx) => { + const existingIndex = existingTransactionsCache[newTx.txId]; if (existingIndex >= 0) { // Transaction exists - update it if the new one has more complete info const existingTx = updatedExistingTransactions[existingIndex]; @@ -312,13 +323,27 @@ export const syncUSDTWalletTransactions = async (wallet: USDTWallet) => { } } else { // New transaction - add it to the list + if (newGasFreeFeeTransactions[newTx.txId]) { + // If there's a corresponding gas-free fee transaction, we should derive the fee from it(case: syncing TRC-20 transactions during USDT wallet import) + const totalFee = parseFloat(newGasFreeFeeTransactions[newTx.txId].amount); + let transferFee = 0; + let activateFee = 0; + + if (totalFee > 1) { + activateFee = 1; + transferFee = totalFee - activateFee; + } else transferFee = totalFee; + + newTx.fee = totalFee.toFixed(3); + newTx.transferFee = parseFloat(transferFee.toFixed(3)); + newTx.activateFee = activateFee; + } mergedTransactions.push(newTx); } }); // Sort transactions by timestamp (newest first) mergedTransactions.sort((a, b) => b.timestamp - a.timestamp); - return mergedTransactions; };