public async Task <bool> ValidateAddress(string address, string ipAddress, int port, string username, string password) { try { var wallerConnector = new WalletConnector(ipAddress, port, username, password); return(await wallerConnector.ValidateAddressAsync(address)); } catch (Exception) { return(true); } }
/// <summary> /// Processes the withrawals. /// </summary> /// <returns></returns> private async Task ProcessWithrawals() { using (var dataAccess = new MsSqlDataAccess()) using (var balanceRepo = new Repository <Balance>()) using (var currencyRepo = new Repository <Currency>()) { var start = DateTime.Now; Log.Message(LogLevel.Info, "[ProcessWithrawals] - Processing pending withdrawals..."); var pendingWithdraws = GetPendingWithdraws(); if (!pendingWithdraws.Any()) { Log.Message(LogLevel.Info, "[ProcessWithrawals] - No pending withdraws found."); return; } Log.Message(LogLevel.Info, "[ProcessWithrawals] - {0} pending withdraws found, Processing...", pendingWithdraws.Count); foreach (var currency in await currencyRepo.GetAllAsync(x => x.IsEnabled)) { if (!_isEnabled) { return; } try { Log.Message(LogLevel.Info, "[ProcessWithrawals] - Processing pending withdraws for {0}...", currency.Symbol); if (!IsWalletOnline(currency.Status)) { Log.Message(LogLevel.Info, "[ProcessWithrawals] - {0} wallet current status is '{1}', skipping.", currency.Symbol, currency.Status); continue; } var wallet = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass, 60000 * 4); var withdraws = pendingWithdraws.Where(x => x.CurrencyId == currency.Id); if (withdraws.IsNullOrEmpty()) { Log.Message(LogLevel.Info, "[ProcessWithrawals] - No pending withdraws found for {0}...", currency.Symbol); continue; // next coin } foreach (var withdraw in withdraws) { Log.Message(LogLevel.Info, "[ProcessWithrawals] - Processing withdraw #{0}...", withdraw.Id); try { //await SendNotification(withdraw.UserId, "Processing {0} withdraw #{1}, {2}{0}", currency.Symbol, withdraw.Id, withdraw.Amount.ToString("F8")); //Run a balance order to ensure we have the correct balance information if (!await AuditUserBalance(dataAccess, withdraw.UserId, withdraw.CurrencyId)) { continue; } // get the users balance information has enough in locked in pending var balance = await balanceRepo.GetOrDefaultAsync(x => x.UserId == withdraw.UserId && x.CurrencyId == withdraw.CurrencyId); if (balance == null || balance.Total <= 0) { //await SendErrorNotification(withdraw.UserId, "{0} withdraw #{1}, Insufficient funds.", currency.Symbol, withdraw.Id); LogError("ProcessWithrawals", "Withdraw Failed, {0} withdraw #{1}, Insufficient funds.", currency.Symbol, withdraw.Id); continue; } if (balance.Total < withdraw.Amount || balance.PendingWithdraw < withdraw.Amount || balance.PendingWithdraw > balance.Total) { //await SendErrorNotification(withdraw.UserId, "{0} withdraw #{1}, Insufficient funds.", currency.Symbol, withdraw.Id); LogError("ProcessWithrawals", "Withdraw Failed, {0} withdraw #{1}, Insufficient funds.", currency.Symbol, withdraw.Id); continue; } // again check if its a valid address if (!await wallet.ValidateAddressAsync(withdraw.Address)) { LogError("ProcessWithrawals", "Withdraw Failed, Invalid {0} address, WithdrawId: {1}", currency.Symbol, withdraw.Id); continue; } //decimal amountExcludingFees = currency.WithdrawFeeType == WithdrawFeeType.Normal // ? withdraw.Amount - currency.WithdrawFee // : withdraw.Amount - ((withdraw.Amount / 100m) * currency.WithdrawFee); decimal withdrawFee = GetWithdrawFee(wallet, currency, withdraw.Amount); decimal amountExcludingFees = withdraw.Amount - withdrawFee; var withdrawResult = await wallet.SendToAddressAsync(withdraw.Address, amountExcludingFees); if (withdrawResult == null || string.IsNullOrEmpty(withdrawResult.Txid)) { LogError("ProcessWithrawals", "Withdraw Failed, Failed to send {0} transaction, WithdrawId: {1}", currency.Symbol, withdraw.Id); continue; } // Update the withdraw with the txid and set to completed if (await dataAccess.ExecuteAsync("WalletSetWithdrawTxId", new { WithdrawId = withdraw.Id, TxId = withdrawResult.Txid }, CommandType.StoredProcedure) <= 0) { LogError("ProcessWithrawals", "Withdraw Failed, Failed to update {0} withdraw transaction id, WithdrawId: {1}, TxId: {2}", currency.Symbol, withdraw.Id, withdrawResult.Txid); continue; } //Run a balance audit to ensure we have the correct balance information if (!await AuditUserBalance(dataAccess, withdraw.UserId, withdraw.CurrencyId)) { continue; } //await SendNotification(withdraw.UserId, "{0} withdrawal #{1} successfully processed.", currency.Symbol, withdraw.Id); //await SendBalanceNotification(withdraw.UserId, currency.Id, currency.Symbol); } catch (Exception ex) { LogError(ex, "ProcessWithrawals", "An exception occured processing Currency: {0}, WithdrawId: {1}", ex, currency.Symbol, withdraw.Id); continue; } Log.Message(LogLevel.Info, "[ProcessWithrawals] - Processing withdraw #{0} complete.", withdraw.Id); } } catch (Exception ex) { LogError(ex, "ProcessWithrawals", "An exception occured processing Currency: {0}", ex, currency.Symbol); continue; } Log.Message(LogLevel.Info, "[ProcessWithrawals] - Processing pending withdraws for {0} complete.", currency.Symbol); } Log.Message(LogLevel.Info, "[ProcessWithrawals] - Processing pending withdrawals complete. Elapsed: {0}", DateTime.Now - start); } }