public static Dictionary <string, Balance> GetUsedBalances(ExchangeSettings settings, ViaJsonRpc via, Exchange xch) { var balances = via.BalanceQuery(xch.Id); foreach (var key in balances.Keys.ToList()) { if (!settings.Assets.ContainsKey(key)) { balances.Remove(key); } } return(balances); }
public static (bool success, string error) ValidateOrderParams(ExchangeSettings settings, ApiOrderCreateMarket model, string price, bool marketOrder = false) { // check market exists if (model.Market == null || !settings.Markets.ContainsKey(model.Market)) { return(false, "Market does not exist"); } // check amount exists if (model.Amount == null) { return(false, "Amount not present"); } // initialize amount vars for further validation var amount = decimal.Parse(model.Amount); var amountInterval = decimal.Parse(settings.Markets[model.Market].AmountInterval); // check amount is greater then amountInterval if (amount < amountInterval) { return(false, $"Amount is less then {amountInterval}"); } // check amonut is a multiple of the amount interval if ((amount / amountInterval) % 1 != 0) { return(false, $"Amount is not a multiple of {amountInterval}"); } if (!marketOrder) { // check price exists if (price == null) { return(false, "Price not present"); } // initialize price vars for further validation var priceDec = decimal.Parse(price); var priceInterval = decimal.Parse(settings.Markets[model.Market].PriceInterval); // check price is greater then priceInterval if (priceDec < priceInterval) { return(false, $"Price is less then {priceInterval}"); } // check price is a multiple of the price interval if ((priceDec / priceInterval) % 1 != 0) { return(false, $"Price is not a multiple of {priceInterval}"); } } return(true, null); }
public static viafront3.Models.ApiViewModels.ApiFiatPayoutRequest CreateFiatPayoutRequest(ILogger logger, ExchangeSettings settings, FiatProcessorSettings fiatSettings, string token, string asset, decimal amount, string account_number, string email) { var cents = amount * Utils.IntPow(10, settings.Assets[asset].Decimals); var centsInt = Convert.ToInt64(cents); // call payment server to create request var jsonBody = JsonConvert.SerializeObject(new { api_key = fiatSettings.FiatServerApiKey, token = token, asset = asset, amount = centsInt, account_number = account_number, account_name = email, reference = fiatSettings.PayoutsReference, code = token }); var response = ServiceRequest(fiatSettings.FiatServerUrl, "payout_create", fiatSettings.FiatServerSecret, jsonBody); if (response.IsSuccessful) { var json = JsonConvert.DeserializeObject <Dictionary <string, string> >(response.Content); if (json.ContainsKey("status")) { var status = json["status"]; // return to user var model = new viafront3.Models.ApiViewModels.ApiFiatPayoutRequest { Token = token, Status = status, Asset = asset, Amount = amount, }; return(model); } } else { logger.LogError($"fiat payment request ({fiatSettings.FiatServerUrl}) failed with http statuscode: {response.StatusCode}"); } return(null); }
static void ProcessOrder(ApplicationDbContext context, UserManager <ApplicationUser> userManager, ExchangeSettings settings, IEmailSender emailSender, string json) { // parse order event var parts = JsonConvert.DeserializeObject <Dictionary <string, object> >(json); var evt = (OrderEvent)(long)parts["event"]; var stock = (string)parts["stock"]; var money = (string)parts["money"]; var order = JsonConvert.DeserializeObject <Order>(((Newtonsoft.Json.Linq.JObject)parts["order"]).ToString()); Console.WriteLine($":: order event :: {evt} - {stock}/{money} (user id: {order.user}, id: {order.id}, type: {order.type}, side: {order.side}, amount: {order.amount}, price: {order.price}, left: {order.left}"); // find user who owns the order var user = ApplicationUser.GetUserFromExchangeId(context, userManager, order.user); if (user == null) { Console.WriteLine($":: ERROR :: user for exchange id {order.user} not found"); return; } // send email to user if (user.Email != null) { try { switch (evt) { case OrderEvent.ORDER_EVENT_PUT: if (order.type == OrderType.Limit) { emailSender.SendEmailLimitOrderCreatedAsync(user.Email, order.market, order.side.ToString(), order.amount, stock, order.price, money); } else { emailSender.SendEmailMarketOrderCreatedAsync(user.Email, order.market, order.side.ToString(), order.amount, stock); } break; case OrderEvent.ORDER_EVENT_UPDATE: if (order.type == OrderType.Limit) { emailSender.SendEmailLimitOrderUpdatedAsync(user.Email, order.market, order.side.ToString(), order.amount, stock, order.price, money, order.left); } else { emailSender.SendEmailMarketOrderUpdatedAsync(user.Email, order.market, order.side.ToString(), order.amount, stock, order.left); } break; case OrderEvent.ORDER_EVENT_FINISH: var amountInterval = decimal.Parse(settings.Markets[order.market].AmountInterval); if (order.type == OrderType.Limit) { emailSender.SendEmailLimitOrderFinishedAsync(user.Email, order.market, order.side.ToString(), order.amount, stock, order.price, money, order.left, amountInterval); } else { emailSender.SendEmailMarketOrderFinishedAsync(user.Email, order.market, order.side.ToString(), order.amount, stock, order.left, amountInterval); } break; } } catch (Exception ex) { Console.WriteLine($":: ERROR sending email - '{ex.Message}'"); } Console.WriteLine($":: email sent to {user.Email}"); } }
public static async Task <AddressIncommingTxs> CheckAddressIncommingTxsAndUpdateWalletAndExchangeBalance(IEmailSender emailSender, ExchangeSettings settings, string asset, IWallet wallet, ChainAssetSettings chainAssetSettings, ApplicationUser user, WalletAddr addr) { // create and test backend connection var via = new ViaJsonRpc(settings.AccessHttpUrl); //TODO: move this to a ViaRpcProvider in /Services (like IWalletProvider) via.BalanceQuery(1); // get wallet transactions var newlySeenTxs = new List <WalletTx>(); var incommingTxs = wallet.GetAddrTransactions(addr.Address); if (incommingTxs != null) { incommingTxs = incommingTxs.Where(t => t.Direction == WalletDirection.Incomming); } else { incommingTxs = new List <WalletTx>(); } foreach (var tx in incommingTxs) { if (tx.State == WalletTxState.None) { // send email: deposit detected wallet.SeenTransaction(tx); newlySeenTxs.Add(tx); if (!string.IsNullOrEmpty(user.Email)) { await emailSender.SendEmailChainDepositDetectedAsync(user.Email, asset, wallet.AmountToString(tx.AmountOutputs()), tx.ChainTx.TxId); } } } var unackedTxs = wallet.GetAddrUnacknowledgedTransactions(addr.Address); if (unackedTxs != null) { unackedTxs = unackedTxs.Where(t => t.Direction == WalletDirection.Incomming && t.ChainTx.Confirmations >= chainAssetSettings.MinConf); } else { unackedTxs = new List <WalletTx>(); } BigInteger newDeposits = 0; foreach (var tx in unackedTxs) { newDeposits += tx.AmountOutputs(); // send email: deposit confirmed await emailSender.SendEmailChainDepositConfirmedAsync(user.Email, asset, wallet.AmountToString(tx.AmountOutputs()), tx.ChainTx.TxId); } // ack txs and save wallet IEnumerable <WalletTx> justAckedTxs = unackedTxs; if (unackedTxs.Any()) { justAckedTxs = new List <WalletTx>(unackedTxs); // wallet.Save will kill unackedTxs because they are no longer unacked wallet.AcknowledgeTransactions(unackedTxs); wallet.Save(); } else if (newlySeenTxs.Any()) { wallet.Save(); } // register new deposits with the exchange backend foreach (var tx in justAckedTxs) { var amount = wallet.AmountToString(tx.AmountOutputs()); var source = new Dictionary <string, object>(); source["txid"] = tx.ChainTx.TxId; var businessId = tx.Id; via.BalanceUpdateQuery(user.Exchange.Id, asset, "deposit", businessId, amount, source); } return(new AddressIncommingTxs { IncommingTxs = incommingTxs, NewlySeenTxs = newlySeenTxs, JustAckedTxs = justAckedTxs, NewDeposits = newDeposits }); }