示例#1
0
        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);
        }
示例#6
0
 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);
     }
 }
示例#7
0
 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);
     }
 }
示例#8
0
 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);
     }
 }
示例#9
0
 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);
 }
示例#10
0
 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);
        }
示例#12
0
 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);
     }
 }
示例#13
0
 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>());
     }
 }
示例#14
0
        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);
            }
        }
示例#15
0
        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);
            }
        }
示例#16
0
        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);
            }
        }
示例#17
0
        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);
            }
        }
示例#19
0
        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);
        }
示例#21
0
        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);
                    }
        }
示例#24
0
        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);
            }
        }