public async Task <IActionResult> Index(GeneralWithdrawModel model) { GeneralWithdrawModel m = new(); if (ModelState.IsValid) { var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); if (model.Currency == "ZEC") { m = await _zecService.SendToAddress(model, userId); } else if (model.Currency == "ETH") { m = await _etheriumService.SendToAddress(model, userId); } else { m = await _withdrawService.Send(model, userId); } return(View("GeneralWithdrawPage", m)); } return(View("GeneralWithdrawPage", m)); }
public async Task <GeneralWithdrawModel> SendToAddress(GeneralWithdrawModel model, string userId) { try { var wallet = await _walletsRepository.GetUserWalletAsync(userId, model.Currency); decimal?_amount = model.Amount.ConvertToDecimal(); if (wallet != null && _amount.Value > 0 && _amount.Value <= wallet.Value) { var result = await _balanceProvider.Withdraw(_amount.Value, wallet); wallet.Value = result.ResultBalanceSender; var tr = await _outcomeTransactionRepository.CreateOutcomeTransaction( new OutcomeTransactionTableModel() { FromWalletId = wallet.Id, ToAddress = model.Address, Value = _amount.Value, PlatformCommission = result.Commission, CurrencyAcronim = "ZEC", State = (int)OutcomeTransactionStateEnum.Finished }); // check if need to convert Amount var txId = _client.MakeRequest <string>(ZecRestMethods.sendtoaddress, model.Address, model.Amount); await _eventsRepository.CreateEventAsync(new EventTableModel() { UserId = userId, Type = (int)EventTypeEnum.Withdraw, Comment = model.Comment, Value = _amount.Value, StartBalance = result.StartBalanceSender, ResultBalance = result.ResultBalanceSender, WhenDate = DateTime.Now, CurrencyAcronim = model.Currency }); model.Status = "Success"; await _walletsRepository.UpdateWalletBalanceAsync(wallet); } else { model.Status = "Not enough coins"; } } catch (Exception e) { model.Status = "Error"; return(model); } return(model); }
public async Task <GeneralWithdrawModel> SendToAddress(GeneralWithdrawModel model, string userId) { // оставляем запас 0.001 на комисию блокчейна, можно вынесли в константы decimal fixedCommicion = 0.001m; try { var wallet = await _walletsRepository.GetUserWalletAsync(userId, model.Currency); decimal?_amount = model.Amount.ConvertToDecimal(); if (wallet != null && _amount.Value > 0 && _amount.Value + fixedCommicion <= wallet.Value) { var resultBalance = await _balanceProvider.Withdraw(_amount.Value, wallet); var tr = await _outcomeTransactionRepository.CreateOutcomeTransaction( new OutcomeTransactionTableModel() { FromWalletId = wallet.Id, ToAddress = model.Address, Value = _amount.Value, PlatformCommission = resultBalance.Commission, FixedCommission = fixedCommicion, CurrencyAcronim = "ETH", State = (int)OutcomeTransactionStateEnum.Created, }); var resultTr = await _ethRequestClient.ExecuteTransactionAsync(tr.Id); if (resultTr.IsSuccess) { wallet.Value = resultBalance.ResultBalanceSender - resultTr.CommissionBlockchain.Value; await _walletsRepository.UpdateWalletBalanceAsync(wallet); tr.State = resultTr.OutcomeTransactionState; tr.BlockchainCommission = resultTr.CommissionBlockchain; await _eventsRepository.CreateEventAsync(new EventTableModel() { UserId = userId, Type = (int)EventTypeEnum.Withdraw, Comment = model.Comment, Value = _amount.Value + resultTr.CommissionBlockchain.Value, StartBalance = resultBalance.StartBalanceSender, ResultBalance = resultBalance.ResultBalanceSender - resultTr.CommissionBlockchain.Value, WhenDate = DateTime.Now, CurrencyAcronim = model.Currency }); model.Status = "Success"; } else { tr.State = resultTr.OutcomeTransactionState; tr.BlockchainCommission = resultTr.CommissionBlockchain; tr.ErrorText = resultTr.ErrorText; await _eventsRepository.CreateEventAsync(new EventTableModel() { UserId = userId, Type = (int)EventTypeEnum.OutcomeTransactionError, Comment = resultTr.ErrorText + " (commission not deducted)", Value = _amount.Value, StartBalance = resultBalance.StartBalanceSender, ResultBalance = resultBalance.ResultBalanceSender, WhenDate = DateTime.Now, CurrencyAcronim = model.Currency }); model.Status = "Error, your transaction will be processed manually"; } await _outcomeTransactionRepository.UpdateTransactionAfterExecutioAsync(tr); } else { model.Status = "Not enough coins"; } } catch (Exception e) { model.Status = "Error"; return(model); } return(model); }
public virtual async Task <GeneralWithdrawModel> Send(GeneralWithdrawModel model, string userId) { try { var wallet = await _walletsRepository.GetUserWalletAsync(userId, model.Currency); decimal?_amount = model.Amount.ConvertToDecimal(); if (wallet != null && _amount.Value > 0 && _amount.Value <= wallet.Value) { var coinService = _coinManager .CoinServices .FirstOrDefault(x => x.CoinShortName == model.Currency); if (coinService == null) { model.Status = "Error"; return(model); } var result = await _balanceProvider.Withdraw(_amount.Value, wallet); wallet.Value = result.ResultBalanceSender; if (result.Commission.HasValue) { coinService.SendToAddress(model.Address, _amount.Value - result.Commission.Value, "", "", true); } else { coinService.SendToAddress(model.Address, _amount.Value, "", "", true); } var tr = await _outcomeTransactionRepository.CreateOutcomeTransaction( new OutcomeTransactionTableModel() { FromWalletId = wallet.Id, ToAddress = model.Address, Value = _amount.Value, CurrencyAcronim = model.Currency, State = (int)OutcomeTransactionStateEnum.Finished }); await _eventsRepository.CreateEventAsync(new EventTableModel() { UserId = userId, Type = (int)EventTypeEnum.Withdraw, Comment = model.Comment, Value = _amount.Value, StartBalance = result.StartBalanceSender, ResultBalance = result.ResultBalanceSender, WhenDate = DateTime.Now, CurrencyAcronim = model.Currency }); model.Status = "Success"; await _walletsRepository.UpdateWalletBalanceAsync(wallet); } else { model.Status = "Not enough coins"; } } catch { model.Status = "Error"; return(model); } return(model); }