private void Button_Click(object sender, RoutedEventArgs e) { try { var user = username.Text; var walletConnection = new WalletConnector(host.Text, int.Parse(port.Text), username.Text, password.Text); var result = walletConnection.GenerateAddress("adam"); MessageBox.Show(result); var result2 = walletConnection.ValidateAddress(result); MessageBox.Show(result2.ToString()); var result3 = walletConnection.GetTransactions(); MessageBox.Show(result3.Count().ToString()); var result4 = walletConnection.GetTransactions("d5325c49c3c11a1907cf431f31b1295bf092406fd442d8a1119e43f4ea6b5cc6"); MessageBox.Show(result4.Count().ToString()); var result5 = walletConnection.GetBalance(); MessageBox.Show(result5.ToString("F8")); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
public async Task <List <WalletTransaction> > GetWalletTransactionsSince(TransactionDataType transactionDataType, int currencyId, int walletTimeoutMinutes, int searchBlockLength) { try { using (var context = _exchangeDataContextFactory.CreateReadOnlyContext()) { var currency = await context.Currency.FirstOrDefaultNoLockAsync(c => c.Id == currencyId); var walletConnection = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass, Math.Max(walletTimeoutMinutes, 1) * 60000); var blockHash = await walletConnection.GetBlockHashAsync(searchBlockLength); var walletTransactions = await walletConnection.GetTransactionsAsync(blockHash, transactionDataType); return(walletTransactions.Select(x => new WalletTransaction { Timestamp = x.Time.ToDateTime(), Account = x.Account, Amount = Math.Abs(x.Amount), Txid = x.Txid, Type = Extensions.ToTransactionType(x.Category), Address = x.Address, Confirmations = x.Confirmations }) .OrderByDescending(x => x.Timestamp).ToList()); } } catch (Exception e) { _log.Exception("[GetWalletTransactions] - An exception occured while Loading Wallet Transactions", e); } return(new List <WalletTransaction>()); }
public async Task <GetWalletFeeResponse> GetWalletFee(int currencyId, decimal amount) { try { using (var currencyRepo = new Repository <Currency>()) { var currency = await currencyRepo.GetOrDefaultAsync(x => x.Id == currencyId); if (currency == null) { return(null); } //var wallet = new WalletConnector("127.0.0.1", 33113, "sa_ddam213.3", "213bit"); var wallet = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass); if (wallet == null) { Log.Message(LogLevel.Error, "[CreateAddress] - Wallet '{0}' not found.", currencyId); return(null); } var fee = await wallet.GetTxFeeAsync(amount); return(new GetWalletFeeResponse { Fee = fee }); } } catch (Exception ex) { Log.Exception("[GetWalletFee] - An exception occured during GetWalletFee, CurrencyId: {0}.", ex, currencyId); } return(null); }
public async Task <GetWalletBlockResponse> GetBlock(GetWalletBlockRequest request) { using (var currencyRepo = new Repository <Currency>()) { var currency = await currencyRepo.GetOrDefaultAsync(x => x.Id == request.CurrencyId); if (currency == null) { Log.Message(LogLevel.Error, "[GetTransaction] - Currency '{0}' not found.", request.CurrencyId); return(null); } try { // var wallet = new WalletConnector("127.0.0.1", 33113, "sa_ddam213.3", "213bit"); var wallet = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass); var blockHash = request.BlockHash; if (string.IsNullOrEmpty(blockHash)) { blockHash = await wallet.GetBlockHashAsync(request.BlockHeight); } return(new GetWalletBlockResponse { BlockData = await wallet.GetBlockAsync(blockHash.Trim()) }); } catch (Exception ex) { Log.Exception("[GetBlock] - An exception occured during GetBlock, CurrencyId: {0}.", ex, request.CurrencyId); } return(null); } }
private decimal GetWithdrawFee(WalletConnector wallet, Currency currency, decimal amount) { try { switch (currency.WithdrawFeeType) { case WithdrawFeeType.Normal: return(currency.WithdrawFee); case WithdrawFeeType.Percent: return((amount / 100m) * currency.WithdrawFee); case WithdrawFeeType.Computed: return(0); default: break; } } catch (Exception ex) { LogError(ex, "GetWithdrawFee", "An exception occured processing Currency withdraw fee: {0}", ex, currency.Symbol); } return(-1m); }
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); } }
private GetInfoData GetInfo(Currency currency, int timeout) { try { var connector = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass, timeout); return(connector.GetInfo()); } catch (Exception) { Log.Message(LogLevel.Debug, "[GetTransactions] - Timeout: {0}ms", timeout); return(null); } }
private List <TransactionData> GetTransactions(Currency currency, int timeout) { try { var connector = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass, timeout); var deposits = new List <TransactionData>(connector.GetDeposits(currency.LastBlockHash)); return(deposits.Where(x => x.Amount > 0).ToList()); } catch (Exception) { Log.Message(LogLevel.Debug, "[GetTransactions] - Timeout: {0}ms", timeout); return(null); } }
private List <TransactionData> GetWalletTransactions(Currency currency, TransactionDataType type, int timeout) { try { var lastHash = type == TransactionDataType.Withdraw ? currency.LastWithdrawBlockHash : currency.LastBlockHash; var connector = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass, timeout); var deposits = new List <TransactionData>(connector.GetTransactions(lastHash, type)); return(deposits.Where(x => x.Amount > 0).ToList()); } catch (Exception ex) { Log.Exception("An exception occured querying wallet transactions. Currency: {0}", ex, currency.Symbol); } return(null); }
private GetInfoData GetInfo(Currency currency, int timeout) { try { var connector = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass, timeout); var info = connector.GetInfo(); var balance = connector.GetBalance(); info.Balance = balance; return(info); } catch (Exception ex) { Log.Exception("An exception occured querying wallet information. Currency: {0}", ex, currency.Symbol); } return(null); }
/// <summary> /// Creates an address for the specified wallet with the userid. /// </summary> /// <param name="walletId">The wallet id.</param> /// <param name="userId">The user id.</param> /// <returns>the new address and private key created in the wallet</returns> public async Task <string[]> CreateAddress(int walletId, Guid userId) { try { using (var currencyRepo = new Repository <Currency>()) { var currency = await currencyRepo.GetOrDefaultAsync(x => x.Id == walletId); if (currency == null) { return(null); } //var wallet = new WalletConnector("127.0.0.1", 33113, "sa_ddam213.3", "213bit"); var wallet = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass); if (wallet == null) { Log.Message(LogLevel.Error, "[CreateAddress] - Wallet '{0}' not found.", walletId); return(null); } string address = wallet.GenerateAddress(userId.ToString()); if (string.IsNullOrEmpty(address)) { Log.Message(LogLevel.Error, "[CreateAddress] - Wallet '{0}' failed to generate address.", walletId); return(null); } Log.Message(LogLevel.Debug, "[CreateAddress] - Address '{0}' generated for CurrencyId: {1}, UserId: {2}", address, walletId, userId); string privateKey = wallet.DumpPrivKey(address); if (string.IsNullOrEmpty(privateKey)) { Log.Message(LogLevel.Error, "[CreateAddress] - Wallet '{0}' failed to dump privatekey.", walletId); return(null); } Log.Message(LogLevel.Debug, "[CreateAddress] - Private key '{0}' dumped for CurrencyId: {1}, UserId: {2}", privateKey, walletId, userId); Log.Message(LogLevel.Info, "[CreateAddress] - New address '{0}' created for CurrencyId: {1}, UserId: {2}", address, walletId, userId); return(new string[] { address, privateKey }); } } catch (Exception ex) { Log.Exception("[CreateAddress] - An exception occured creating address, WalletId: {0}, UserId: {1}", ex, walletId, userId); } return(null); }
private async Task <string> CreateAddress(PaymentMethod paymentMethod) { try { var connector = new WalletConnector ( paymentMethod.Data, paymentMethod.Data2, paymentMethod.Data3 ); return(await connector.GenerateAddressAsync("", true)); } catch (Exception ex) { Log.Exception("Failed to create address.", ex); return(null); } }
private async Task <IEnumerable <TransactionData> > GetWalletDeposits(PaymentMethod paymentMethod) { try { var connector = new WalletConnector ( paymentMethod.Data, paymentMethod.Data2, paymentMethod.Data3 ); return(await connector.GetDepositsAsync(paymentMethod.Data5)); } catch (Exception ex) { Log.Exception("Failed to get transactions.", ex); return(Enumerable.Empty <TransactionData>()); } }
public async Task <AddressModel> GenerateAddress(string userId, string ipAddress, int port, string username, string password) { try { var wallerConnector = new WalletConnector(ipAddress, port, username, password); var address = wallerConnector.GenerateAddress(userId, true); var privateKey = await wallerConnector.DumpPrivKeyAsync(address); return(new AddressModel { Address = address, PrivateKey = privateKey }); } catch (Exception) { return(null); } }
private async Task <string> SendTransaction(PrizePayment prizePayment) { try { var connector = new WalletConnector ( prizePayment.Host, prizePayment.UserName, prizePayment.Password ); var result = await connector.SendToAddressAsync(prizePayment.Destination, decimal.Parse(prizePayment.Amount)); return(result.Txid); } catch (Exception ex) { Log.Exception("Failed to send transaction.", ex); return(null); } }
private async Task UpdateWithdrawConfirmations(IDataContext context, Currency currency) { try { Log.Message(LogLevel.Info, "Processing {0} withdrawals...", currency.Symbol); if (currency.Status == CurrencyStatus.Maintenance || currency.Status == CurrencyStatus.Offline) { return; // currency is skipped } var connector = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass); var walletTransactions = await connector.GetTransactionsAsync(currency.LastBlockHash, TransactionDataType.Withdraw); if (walletTransactions.IsNullOrEmpty()) { Log.Message(LogLevel.Info, "No {0} withdrawals.", currency.Symbol); return; // no deposits } var existingWithdraws = await context.Withdraw.Where(x => x.CurrencyId == currency.Id && x.WithdrawStatus == WithdrawStatus.Complete).ToListAsync(); foreach (var walletWithdraw in walletTransactions.OrderBy(x => x.Time)) { var existingWithdraw = existingWithdraws.FirstOrDefault(x => x.Txid == walletWithdraw.Txid); if (existingWithdraw != null && existingWithdraw.Confirmations != walletWithdraw.Confirmations) { existingWithdraw.Confirmations = walletWithdraw.Confirmations; if (existingWithdraw.Confirmations >= 20) { currency.LastWithdrawBlockHash = walletWithdraw.Blockhash; } } } await context.SaveChangesAsync(); Log.Message(LogLevel.Info, "Processing {0} withdrawals complete.", currency.Symbol); } catch (Exception ex) { Log.Exception("An exception occured updating withdraw confirmations.", ex); } }
private async Task PerformWalletTransactionsAndUpdateDepositsWithIds(List <string> transactionIds, IExchangeDataContext context) { Log.Message(LogLevel.Info, "PerformWalletTransactionsAndUpdateDepositsWithIds entered."); // send transactions to the wallets for System_User cefs payments and update the deposits with the real txId. var cefsDeposits = await context.Deposit.Where(x => transactionIds.Contains(x.Txid)).ToListAsync().ConfigureAwait(false); foreach (var txId in transactionIds) { try { var deposit = cefsDeposits.FirstOrDefault(x => x.Txid == txId); var currency = await context.Currency.FirstOrDefaultAsync(c => c.Id == deposit.CurrencyId).ConfigureAwait(false); var currencyAddress = await context.Address.FirstOrDefaultAsync(a => a.UserId == Constant.SYSTEM_USER_STAGING && a.CurrencyId == deposit.CurrencyId).ConfigureAwait(false); if (currencyAddress == null) { Log.Message(LogLevel.Error, $"No address exists for currency {currency.Symbol}. Unable to process CEF deposit."); continue; } var connector = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass, WALLET_TIMEOUT); var result = await connector.SendToAddressAsync(currencyAddress.AddressHash, deposit.Amount); if (result != null) { deposit.Txid = result.Txid; await context.SaveChangesAsync(); } } catch (Exception ex) { Log.Message(LogLevel.Error, $"Wallet Transaction blew up.\r\n{ex.Message}"); } } Log.Message(LogLevel.Info, "PerformWalletTransactionsAndUpdateDepositsWithIds exited."); }
public async Task <GetWalletInfoResponse> GetInfo(int currencyId) { using (var currencyRepo = new Repository <Currency>()) { var currency = await currencyRepo.GetOrDefaultAsync(x => x.Id == currencyId); if (currency == null) { Log.Message(LogLevel.Error, "[GetInfo] - Currency '{0}' not found.", currencyId); return(null); } try { //var wallet = new WalletConnector("127.0.0.1", 33113, "sa_ddam213.3", "213bit"); var wallet = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass); var info = await wallet.GetInfoAsync(); var miningInfo = await wallet.GetMiningInfoAsync(); return(new GetWalletInfoResponse { InfoData = new GetInfoData { Blocks = info.Blocks, Connections = info.Connections, Difficulty = info.Difficulty, Hashrate = miningInfo.NetworkHashrate }, PeerInfo = new List <PeerInfo>(await wallet.GetPeerInfoAsync()) }); } catch (Exception ex) { Log.Exception("[GetInfo] - An exception occured during GetInfo, CurrencyId: {0}.", ex, currencyId); } return(null); } }
private async Task LoadWalletTransactions(Wallet wallet) { WalletTransactions.Clear(); try { var walletConnection = new WalletConnector(wallet.Host, wallet.Port, wallet.User, wallet.Pass, 60000 * 4); var wallettransactions = await walletConnection.GetTransactionsAsync("", _selectedTransactionType); var transactions = wallettransactions.Select(x => new WalletTransaction { Timestamp = x.Time.ToDateTime(), Account = x.Account, Amount = Math.Abs(x.Amount), Txid = x.Txid, Type = Cryptopia.WalletAPI.Helpers.Extensions.ToTransactionType(x.Category), Address = x.Address, Confirmations = x.Confirmations }) .OrderByDescending(x => x.Timestamp); int refesh = 10; foreach (var item in transactions) { WalletTransactions.Add(item); refesh--; if (refesh < 0) { refesh = 10; await Task.Delay(1); } } } catch (Exception ex) { MessageBox.Show("Something went wrong \n" + ex.ToString()); } }
/// <summary> /// Validates the address against the wallet. /// </summary> /// <param name="walletId">The wallet id.</param> /// <param name="address">The address.</param> /// <returns>true if the address is a valid address for the wallet, otherwise false</returns> public async Task <bool> ValidateAddress(int walletId, string address) { try { using (var currencyRepo = new Repository <Currency>()) { var currency = await currencyRepo.GetOrDefaultAsync(x => x.Id == walletId); if (currency == null) { return(false); } var wallet = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass); if (wallet == null) { Log.Message(LogLevel.Error, "[CreateAddress] - Wallet '{0}' not found.", walletId); return(false); } if (!wallet.ValidateAddress(address)) { Log.Message(LogLevel.Error, "[ValidateAddress] - Address '{0}' is not a valid address for CurrencyId: {1}", address, walletId); return(false); } Log.Message(LogLevel.Info, "[ValidateAddress] - Address '{0}' successfully validated for CurrencyId: {1}", address, walletId); return(true); } } catch (Exception ex) { Log.Exception("[ValidateAddress] - An exception occured validating address, WalletId: {0}, Address: {1}", ex, walletId, address); } return(false); }
private async Task ProcessTransactions() { Log.Message(LogLevel.Info, "[ProcessNZDT] - Processing NZDT Transactions..."); List <NzdtTransaction> nzdtTransactions; using (var context = ExchangeDataContextFactory.CreateContext()) { nzdtTransactions = await context.NzdtTransaction .Where(x => x.TransactionStatus == NzdtTransactionStatus.ReadyForProcessing) .Where(x => DbFunctions.AddHours(x.CreatedOn, 1) <= DateTime.UtcNow) .ToListNoLockAsync(); Log.Message(LogLevel.Info, $"[ProcessNZDT] - {nzdtTransactions.Count()} transactions found, processing..."); foreach (var transaction in nzdtTransactions) { transaction.TransactionStatus = NzdtTransactionStatus.Processed; } await context.SaveChangesAsync(); } var wallet = new WalletConnector(_nzdtAssetWalletIp, _nzdtAssetWalletPort, _nzdtAssetWalletUserName, _nzdtAssetWalletPassword, 30000); foreach (var transaction in nzdtTransactions) { try { var sendResult = await wallet.SendToAddressAsync(Constant.NzdtBaseExchangeAddress, transaction.Amount); using (var context = ExchangeDataContextFactory.CreateContext()) { var deposit = new Deposit { Txid = string.IsNullOrEmpty(sendResult?.Txid) ? $"{transaction.Id}" : sendResult.Txid, Amount = transaction.Amount, TimeStamp = DateTime.UtcNow, CurrencyId = Constant.NZDT_ID, Status = DepositStatus.Confirmed, Confirmations = 20, UserId = transaction.UserId.Value, Type = DepositType.Normal }; var tx = await context.NzdtTransaction.FirstNoLockAsync(x => x.Id == transaction.Id); tx.Deposit = deposit; await context.SaveChangesAsync(); await context.AuditUserBalance(transaction.UserId.Value, Constant.NZDT_ID); await context.SaveChangesAsync(); } } catch (Exception ex) { Log.Exception($"[ProcessNZDT] Insert Deposit failed for transaction {transaction.Id}", ex); } } Log.Message(LogLevel.Info, $"[ProcessNZDT] - Processing NZDT Transactions complete."); }
/// <summary> /// Updates the confirmations. /// </summary> private async Task UpdateConfirmations() { using (var currencyRepo = new Repository <Currency>()) using (var withdrawRepo = new Repository <Withdraw>()) { var withdrawals = withdrawRepo.GetAll(x => x.Confirmations < _maxConfirmations).ToListNoLock(); if (!withdrawals.Any()) { Log.Message(LogLevel.Info, "[UpdateConfirmations] - No withdrawals found with less than {0} confirmations", _maxConfirmations); return; } var currencyGroups = withdrawals.GroupBy(x => x.CurrencyId); foreach (var currencyWithdrawals in currencyGroups) { try { if (!_isEnabled) { return; } var currency = await currencyRepo.GetOrDefaultAsync(x => x.Id == currencyWithdrawals.Key && x.IsEnabled); if (currency == null) { Log.Message(LogLevel.Info, "[UpdateConfirmations] - CurrencyId {0} not found or is disabled, skipping.", currencyWithdrawals.Key); continue; } if (!IsWalletOnline(currency.Status)) { Log.Message(LogLevel.Info, "[UpdateConfirmations] - {0} wallet current status is '{1}', skipping.", currency.Symbol, currency.Status); continue; } Log.Message(LogLevel.Info, "[UpdateConfirmations] - Updating {0} transaction confirmations", currency.Symbol); var wallet = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass); var transactions = await wallet.GetTransactionsAsync(currency.LastWithdrawBlockHash, TransactionDataType.Withdraw); foreach (var withdrawal in currencyWithdrawals) { try { if (!_isEnabled) { return; } var transaction = transactions.FirstOrDefault(x => x.Txid == withdrawal.Txid); if (transaction == null) { // LogError("UpdateConfirmations", "Withdraw transaction not found in wallet, WithdrawId: {0}, TxId: {1}", withdrawal.Id, withdrawal.Txid); continue; } if (withdrawal.Confirmations != transaction.Confirmations) { withdrawal.Confirmations = transaction.Confirmations; if (withdrawal.Confirmations >= _maxConfirmations) { currency.LastWithdrawBlockHash = transaction.Blockhash; } Log.Message(LogLevel.Debug, "[UpdateConfirmations] - Updated confirmations on transaction, Confirms: {0}, TxId: {1}", transaction.Confirmations, transaction.Txid); } } catch (Exception ex) { LogError(ex, "UpdateConfirmations", "An exception occured in processing {0} withdrawal, Id: {1}", currency.Symbol, withdrawal.Id); } } await currencyRepo.SaveOrMergeAsync(); await withdrawRepo.SaveAsync(); Log.Message(LogLevel.Info, "[UpdateConfirmations] - {0} transaction confirmation updates complete", currency.Symbol); } catch (Exception ex) { LogError(ex, "UpdateConfirmations", "An exception occured in processing withdrawals, CurrencyId: {0}", currencyWithdrawals.Key); } } } }
/// <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); } }
private async Task SendWithdrawals(IDataContext context, Currency currency) { try { Log.Message(LogLevel.Info, "Sending pending {0} withdrawals...", currency.Symbol); if (currency.Status == CurrencyStatus.Maintenance || currency.Status == CurrencyStatus.Offline) { return; // currency is skipped } var connector = new WalletConnector(currency.WalletHost, currency.WalletPort, currency.WalletUser, currency.WalletPass); var pendingWithdraws = await context.Withdraw.Where(x => x.CurrencyId == currency.Id && x.WithdrawStatus == WithdrawStatus.Pending && x.User.IsWithdrawEnabled).ToListAsync(); foreach (var pendingWithdraw in pendingWithdraws) { pendingWithdraw.WithdrawStatus = WithdrawStatus.Processing; } await context.SaveChangesAsync(); if (!pendingWithdraws.Any()) { Log.Message(LogLevel.Info, "No pending {0} withdrawals found.", currency.Symbol); return; } foreach (var pendingWithdraw in pendingWithdraws) { try { Log.Message(LogLevel.Info, "Processing pending withdrawal. Currency: {0}, Amount: {1}, Address: {2}", currency.Symbol, pendingWithdraw.Amount, pendingWithdraw.Address); var auditResult = await AuditUser(context, pendingWithdraw.CurrencyId, pendingWithdraw.UserId); if (!auditResult.Success) { Log.Message(LogLevel.Error, "Failed to audit user balance. Currency: {0}, User: {1}", currency.Symbol, pendingWithdraw.UserId); continue; } if (auditResult.Total <= 0 || auditResult.Total < pendingWithdraw.Amount || auditResult.PendingWithdraw < pendingWithdraw.Amount || auditResult.PendingWithdraw > auditResult.Total) { Log.Message(LogLevel.Error, "User has insufficiant funds for withdraw: Currency:{0}, User: {1}", currency.Symbol, pendingWithdraw.UserId); continue; } decimal withdrawFee = GetWithdrawFee(currency, pendingWithdraw.Amount); decimal amountExcludingFees = pendingWithdraw.Amount - withdrawFee; Log.Message(LogLevel.Info, "Sending wallet transaction. Currency: {0}, Host: {1}, Port: {2}", currency.Symbol, currency.WalletHost, currency.WalletPort); var withdrawResult = await connector.SendToAddressAsync(pendingWithdraw.Address, amountExcludingFees); if (withdrawResult == null || string.IsNullOrEmpty(withdrawResult.Txid)) { Log.Message(LogLevel.Error, "Received no response from wallet, CAUTION: Withdraw status unknown!"); continue; } // Update the withdraw with the txid and set to completed pendingWithdraw.Txid = withdrawResult.Txid; pendingWithdraw.WithdrawStatus = WithdrawStatus.Complete; await context.SaveChangesAsync(); Log.Message(LogLevel.Info, "Sending wallet transaction complete. Currency: {0}, TransactionId: {1}", currency.Symbol, withdrawResult.Txid); auditResult = await AuditUser(context, pendingWithdraw.CurrencyId, pendingWithdraw.UserId); await NotificationService.SendBalanceUpdate(GetBalanceNotification(auditResult)); } catch (Exception ex) { Log.Exception("An exception occured sending withdraw", ex); } } Log.Message(LogLevel.Info, "Sending pending {0} withdrawals complete.", currency.Symbol); } catch (Exception ex) { Log.Exception("An exception occured sending withdrawals", ex); } }