public async Task StartAsync()
        {
            if (!Directory.Exists(_Directory))
            {
                Directory.CreateDirectory(_Directory);
            }
            string chain          = NBXplorerDefaultSettings.GetFolderName(NetworkType.Regtest);
            string chainDirectory = Path.Combine(_Directory, chain);

            if (!Directory.Exists(chainDirectory))
            {
                Directory.CreateDirectory(chainDirectory);
            }

            StringBuilder config = new StringBuilder();

            config.AppendLine($"{chain.ToLowerInvariant()}=1");
            if (InContainer)
            {
                config.AppendLine($"bind=0.0.0.0");
            }
            config.AppendLine($"port={Port}");
            config.AppendLine($"chains={string.Join(',', Chains)}");
            if (Chains.Contains("BTC", StringComparer.OrdinalIgnoreCase))
            {
                config.AppendLine($"btc.explorer.url={NBXplorerUri.AbsoluteUri}");
                config.AppendLine($"btc.explorer.cookiefile=0");
            }

            if (UseLightning)
            {
                config.AppendLine($"btc.lightning={IntegratedLightning.AbsoluteUri}");
                var localLndBackupFile = Path.Combine(_Directory, "walletunlock.json");
                File.Copy(TestUtils.GetTestDataFullPath("LndSeedBackup/walletunlock.json"), localLndBackupFile, true);
                config.AppendLine($"btc.external.lndseedbackup={localLndBackupFile}");
            }

            if (Chains.Contains("LTC", StringComparer.OrdinalIgnoreCase))
            {
                config.AppendLine($"ltc.explorer.url={LTCNBXplorerUri.AbsoluteUri}");
                config.AppendLine($"ltc.explorer.cookiefile=0");
            }
            if (Chains.Contains("LBTC", StringComparer.OrdinalIgnoreCase))
            {
                config.AppendLine($"lbtc.explorer.url={LBTCNBXplorerUri.AbsoluteUri}");
                config.AppendLine($"lbtc.explorer.cookiefile=0");
            }
            if (AllowAdminRegistration)
            {
                config.AppendLine("allow-admin-registration=1");
            }

            config.AppendLine($"torrcfile={TestUtils.GetTestDataFullPath("Tor/torrc")}");
            config.AppendLine($"socksendpoint={SocksEndpoint}");
            config.AppendLine($"debuglog=debug.log");


            if (!string.IsNullOrEmpty(SSHPassword) && string.IsNullOrEmpty(SSHKeyFile))
            {
                config.AppendLine($"sshpassword={SSHPassword}");
            }
            if (!string.IsNullOrEmpty(SSHKeyFile))
            {
                config.AppendLine($"sshkeyfile={SSHKeyFile}");
            }
            if (!string.IsNullOrEmpty(SSHConnection))
            {
                config.AppendLine($"sshconnection={SSHConnection}");
            }

            if (TestDatabase == TestDatabases.MySQL && !String.IsNullOrEmpty(MySQL))
            {
                config.AppendLine($"mysql=" + MySQL);
            }
            else if (!String.IsNullOrEmpty(Postgres))
            {
                config.AppendLine($"postgres=" + Postgres);
            }
            var confPath = Path.Combine(chainDirectory, "settings.config");
            await File.WriteAllTextAsync(confPath, config.ToString());

            ServerUri              = new Uri("http://" + HostName + ":" + Port + "/");
            HttpClient             = new HttpClient();
            HttpClient.BaseAddress = ServerUri;
            Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development");
            var conf = new DefaultConfiguration()
            {
                Logger = Logs.LogProvider.CreateLogger("Console")
            }.CreateConfiguration(new[] { "--datadir", _Directory, "--conf", confPath, "--disable-registration", DisableRegistration ? "true" : "false" });

            _Host = new WebHostBuilder()
                    .UseConfiguration(conf)
                    .UseContentRoot(FindBTCPayServerDirectory())
                    .UseWebRoot(Path.Combine(FindBTCPayServerDirectory(), "wwwroot"))
                    .ConfigureServices(s =>
            {
                s.AddLogging(l =>
                {
                    l.AddFilter("System.Net.Http.HttpClient", LogLevel.Critical);
                    l.SetMinimumLevel(LogLevel.Information)
                    .AddFilter("Microsoft", LogLevel.Error)
                    .AddFilter("Hangfire", LogLevel.Error)
                    .AddProvider(Logs.LogProvider);
                });
            })
                    .ConfigureServices(services =>
            {
                services.TryAddSingleton <IFeeProviderFactory>(new BTCPayServer.Services.Fees.FixedFeeProvider(new FeeRate(100L, 1)));
            })
                    .UseKestrel()
                    .UseStartup <Startup>()
                    .Build();
            await _Host.StartWithTasksAsync();

            var urls = _Host.ServerFeatures.Get <IServerAddressesFeature>().Addresses;

            foreach (var url in urls)
            {
                Logs.Tester.LogInformation("Listening on " + url);
            }
            Logs.Tester.LogInformation("Server URI " + ServerUri);

            InvoiceRepository = (InvoiceRepository)_Host.Services.GetService(typeof(InvoiceRepository));
            StoreRepository   = (StoreRepository)_Host.Services.GetService(typeof(StoreRepository));
            Networks          = (BTCPayNetworkProvider)_Host.Services.GetService(typeof(BTCPayNetworkProvider));

            if (MockRates)
            {
                var rateProvider = (RateProviderFactory)_Host.Services.GetService(typeof(RateProviderFactory));
                rateProvider.Providers.Clear();

                var coinAverageMock = new MockRateProvider();
                coinAverageMock.ExchangeRates.Add(new PairRate(CurrencyPair.Parse("BTC_USD"), new BidAsk(5000m)));
                coinAverageMock.ExchangeRates.Add(new PairRate(CurrencyPair.Parse("BTC_CAD"), new BidAsk(4500m)));
                coinAverageMock.ExchangeRates.Add(new PairRate(CurrencyPair.Parse("BTC_LTC"), new BidAsk(162m)));
                coinAverageMock.ExchangeRates.Add(new PairRate(CurrencyPair.Parse("LTC_USD"), new BidAsk(500m)));
                rateProvider.Providers.Add("coingecko", coinAverageMock);

                var bitflyerMock = new MockRateProvider();
                bitflyerMock.ExchangeRates.Add(new PairRate(CurrencyPair.Parse("BTC_JPY"), new BidAsk(700000m)));
                rateProvider.Providers.Add("bitflyer", bitflyerMock);

                var quadrigacx = new MockRateProvider();
                quadrigacx.ExchangeRates.Add(new PairRate(CurrencyPair.Parse("BTC_CAD"), new BidAsk(6000m)));
                rateProvider.Providers.Add("quadrigacx", quadrigacx);

                var bittrex = new MockRateProvider();
                bittrex.ExchangeRates.Add(new PairRate(CurrencyPair.Parse("DOGE_BTC"), new BidAsk(0.004m)));
                rateProvider.Providers.Add("bittrex", bittrex);


                var bitfinex = new MockRateProvider();
                bitfinex.ExchangeRates.Add(new PairRate(CurrencyPair.Parse("UST_BTC"), new BidAsk(0.000136m)));
                rateProvider.Providers.Add("bitfinex", bitfinex);

                var bitpay = new MockRateProvider();
                bitpay.ExchangeRates.Add(new PairRate(CurrencyPair.Parse("ETB_BTC"), new BidAsk(0.1m)));
                rateProvider.Providers.Add("bitpay", bitpay);
            }


            Logs.Tester.LogInformation("Waiting site is operational...");
            await WaitSiteIsOperational();

            Logs.Tester.LogInformation("Site is now operational");
        }
示例#2
0
        public async Task <IActionResult> Rates(RatesViewModel model, string command = null, string storeId = null, CancellationToken cancellationToken = default)
        {
            if (command == "scripting-on")
            {
                return(RedirectToAction(nameof(ShowRateRules), new { scripting = true, storeId = model.StoreId }));
            }
            else if (command == "scripting-off")
            {
                return(RedirectToAction(nameof(ShowRateRules), new { scripting = false, storeId = model.StoreId }));
            }

            var exchanges = GetSupportedExchanges();

            model.SetExchangeRates(exchanges, model.PreferredExchange);
            model.StoreId = storeId ?? model.StoreId;
            CurrencyPair[] currencyPairs = null;
            try
            {
                currencyPairs = model.DefaultCurrencyPairs?
                                .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                .Select(p => CurrencyPair.Parse(p))
                                .ToArray();
            }
            catch
            {
                ModelState.AddModelError(nameof(model.DefaultCurrencyPairs), "Invalid currency pairs (should be for example: BTC_USD,BTC_CAD,BTC_JPY)");
            }
            if (!ModelState.IsValid)
            {
                return(View(model));
            }
            if (model.PreferredExchange != null)
            {
                model.PreferredExchange = model.PreferredExchange.Trim().ToLowerInvariant();
            }

            var blob = CurrentStore.GetStoreBlob();

            model.DefaultScript      = blob.GetDefaultRateRules(_NetworkProvider).ToString();
            model.AvailableExchanges = exchanges;

            blob.PreferredExchange    = model.PreferredExchange;
            blob.Spread               = (decimal)model.Spread / 100.0m;
            blob.DefaultCurrencyPairs = currencyPairs;
            if (!model.ShowScripting)
            {
                if (!exchanges.Any(provider => provider.Id.Equals(model.PreferredExchange, StringComparison.InvariantCultureIgnoreCase)))
                {
                    ModelState.AddModelError(nameof(model.PreferredExchange), $"Unsupported exchange ({model.RateSource})");
                    return(View(model));
                }
            }
            RateRules rules = null;

            if (model.ShowScripting)
            {
                if (!RateRules.TryParse(model.Script, out rules, out var errors))
                {
                    errors = errors ?? new List <RateRulesErrors>();
                    var errorString = String.Join(", ", errors.ToArray());
                    ModelState.AddModelError(nameof(model.Script), $"Parsing error ({errorString})");
                    return(View(model));
                }
                else
                {
                    blob.RateScript = rules.ToString();
                    ModelState.Remove(nameof(model.Script));
                    model.Script = blob.RateScript;
                }
            }
            rules = blob.GetRateRules(_NetworkProvider);

            if (command == "Test")
            {
                if (string.IsNullOrWhiteSpace(model.ScriptTest))
                {
                    ModelState.AddModelError(nameof(model.ScriptTest), "Fill out currency pair to test for (like BTC_USD,BTC_CAD)");
                    return(View(model));
                }
                var splitted = model.ScriptTest.Split(',', StringSplitOptions.RemoveEmptyEntries);

                var pairs = new List <CurrencyPair>();
                foreach (var pair in splitted)
                {
                    if (!CurrencyPair.TryParse(pair, out var currencyPair))
                    {
                        ModelState.AddModelError(nameof(model.ScriptTest), $"Invalid currency pair '{pair}' (it should be formatted like BTC_USD,BTC_CAD)");
                        return(View(model));
                    }
                    pairs.Add(currencyPair);
                }

                var fetchs      = _RateFactory.FetchRates(pairs.ToHashSet(), rules, cancellationToken);
                var testResults = new List <RatesViewModel.TestResultViewModel>();
                foreach (var fetch in fetchs)
                {
                    var testResult = await(fetch.Value);
                    testResults.Add(new RatesViewModel.TestResultViewModel()
                    {
                        CurrencyPair = fetch.Key.ToString(),
                        Error        = testResult.Errors.Count != 0,
                        Rule         = testResult.Errors.Count == 0 ? testResult.Rule + " = " + testResult.BidAsk.Bid.ToString(CultureInfo.InvariantCulture)
                                                            : testResult.EvaluatedRule
                    });
                }
                model.TestRateRules = testResults;
                return(View(model));
            }
            else // command == Save
            {
                if (CurrentStore.SetStoreBlob(blob))
                {
                    await _Repo.UpdateStore(CurrentStore);

                    TempData[WellKnownTempData.SuccessMessage] = "Rate settings updated";
                }
                return(RedirectToAction(nameof(Rates), new
                {
                    storeId = CurrentStore.Id
                }));
            }
        }
示例#3
0
        private async Task LoadMarketSummaryAsync()
        {
            try
            {
                if (MarketService.Instance().MarketList != null)
                {
                    if (MarketService.Instance().MarketList.Any())
                    {
                        await this.Dispatcher.Invoke(async() =>
                        {
                            {
                                if (cbCurrency.SelectedValue != null)
                                {
                                    selectedCurrency = string.Concat(string.Concat(currentExchangeCoin, "_"), cbCurrency.SelectedValue.ToString());
                                }

                                dtgExchange.Items.Clear();
                                foreach (var market in MarketService.Instance().MarketList.Where(x => x.Key.ToString().Contains(string.Concat(currentExchangeCoin, "_")) && x.Value.Volume24HourBase > exchangeBTCVolumeMinimun).OrderByDescending(x => x.Value.Volume24HourBase))
                                {
                                    if (currencyItems != null)
                                    {
                                        if (!currencyItems.Any(x => x.Equals(market.Key.ToString().Replace(string.Concat(currentExchangeCoin, "_"), ""))))
                                        {
                                            currencyItems.Add(market.Key.ToString().Replace(string.Concat(currentExchangeCoin, "_"), ""));
                                        }
                                    }

                                    double spreadRateBase     = market.Value.OrderSpread / 2;
                                    double volumeRateBase     = market.Value.Volume24HourBase * 3;
                                    double changeRateBase     = market.Value.PriceChangePercentage * 2;
                                    market.Value.indiceMaluco = Math.Round((spreadRateBase *volumeRateBase *changeRateBase * 100) / 3, 5).Normalize();

                                    market.Value.isHave = false;
                                    if (Service.WalletService.Instance().WalletList != null)
                                    {
                                        market.Value.isHave = Service.WalletService.Instance().WalletList.Any(x => x.Key.Equals(market.Key.ToString().Replace(string.Concat(currentExchangeCoin, "_"), "")) && x.Value.btcValue > 0);
                                    }

                                    market.Value.isPositiveChange = (market.Value.PriceChangePercentage > 0);

                                    dtgExchange.Items.Add(market);
                                }

                                if (currencyItems != null)
                                {
                                    if (currencyItems.Count() != cbCurrency.Items.Count)
                                    {
                                        cbCurrency.ItemsSource  = currencyItems.OrderBy(x => x);
                                        cbCurrency.SelectedItem = selectedCurrency.Replace(string.Concat(currentExchangeCoin, "_"), "");
                                    }
                                }


                                var OpenOrdersAsync = await PoloniexClient.Markets.GetOpenOrdersAsync(CurrencyPair.Parse(selectedCurrency), 100);

                                if (OpenOrdersAsync != null)
                                {
                                    if (OpenOrdersAsync.SellOrders != null)
                                    {
                                        dtgTradeHistorySells.Items.Clear();
                                        foreach (var sell in OpenOrdersAsync.SellOrders)
                                        {
                                            dtgTradeHistorySells.Items.Add(sell);
                                        }
                                    }

                                    if (OpenOrdersAsync.BuyOrders != null)
                                    {
                                        dtgTradeHistoryBuys.Items.Clear();
                                        foreach (var buy in OpenOrdersAsync.BuyOrders)
                                        {
                                            dtgTradeHistoryBuys.Items.Add(buy);
                                        }
                                    }
                                }
                            }
                        });
                        await OpenThreadTradeHistory();
                    }
                }
            }
            catch { }
        }
示例#4
0
        private async Task OpenThreadTradeHistory()
        {
            await Task.Run(async() =>
            {
                ITrade highOrderRate = null;
                ITrade lowOrderRate  = null;

                try
                {
                    DateTime startTime = DateTime.Now.AddHours(3);

                    int tempoMinutoPeriodo;

                    this.Dispatcher.Invoke(DispatcherPriority.Background, (ThreadStart) delegate
                    {
                        if (!int.TryParse(txtMinutos.Text, out tempoMinutoPeriodo))
                        {
                            tempoMinutoPeriodo = 20;
                        }

                        startTime = startTime.AddMinutes(-tempoMinutoPeriodo);

                        if (TradeHistoryWindow != null)
                        {
                            TradeHistoryWindow.Minutos      = tempoMinutoPeriodo;
                            TradeHistoryWindow.CurrencyPair = CurrencyPair.Parse(selectedCurrency);
                        }
                    });

                    var endTime = DateTime.Now.AddHours(3);

                    if (PoloniexClient != null)
                    {
                        MarketService.Instance().TradesHistoryList = await PoloniexClient.Markets.GetTradesAsync(CurrencyPair.Parse(selectedCurrency), startTime, endTime);
                    }

                    if (MarketService.Instance().TradesHistoryList != null)
                    {
                        if (TradeHistoryWindow != null)
                        {
                            await TradeHistoryWindow.Dispatcher.Invoke(async() =>
                            {
                                await TradeHistoryWindow.LoadTradeSummaryAsync();
                            });
                        }

                        if (MarketService.Instance().TradesHistoryList.Any())
                        {
                            highOrderRate        = MarketService.Instance().TradesHistoryList.OrderByDescending(o => o.PricePerCoin).First();
                            lowOrderRate         = MarketService.Instance().TradesHistoryList.OrderBy(o => o.PricePerCoin).First();
                            var averageOrderRate = MarketService.Instance().TradesHistoryList.Average(x => x.PricePerCoin);

                            this.Dispatcher.Invoke(DispatcherPriority.Background, (ThreadStart) delegate
                            {
                                if (MarketService.Instance().TradesHistoryList != null)
                                {
                                    if (MarketService.Instance().TradesHistoryList.Any())
                                    {
                                        if (highOrderRate != null)
                                        {
                                            lblHighPrice.Content = string.Format("High Price ({0}):", highOrderRate.Time.ToShortTimeString());
                                            txtHighPrice.Text    = highOrderRate.PricePerCoin.ToString("0.00000000") + " (" + highOrderRate.Type + ")";
                                        }

                                        if (lowOrderRate != null)
                                        {
                                            lblLowPrice.Content = string.Format("Low Price ({0}):", lowOrderRate.Time.ToShortTimeString());
                                            txtLowPrice.Text    = string.Format("{0} ({1})", lowOrderRate.PricePerCoin.ToString("0.00000000"), lowOrderRate.Type);
                                        }

                                        txtPriceAverage.Text = averageOrderRate.ToString("0.00000000");


                                        var lastPrice = MarketService.Instance().TradesHistoryList.OrderByDescending(x => x.Time).First();
                                        if (lastPrice != null)
                                        {
                                            lblLastPrice.Content = string.Format("Last Trade ({0}):", lastPrice.Time.ToShortTimeString());
                                            txtLastPrice.Text    = lastPrice.PricePerCoin.ToString("0.00000000") + " (" + lastPrice.Type + ")";
                                        }

                                        var buys  = MarketService.Instance().TradesHistoryList.Where(x => x.Type == OrderType.Buy);
                                        var sells = MarketService.Instance().TradesHistoryList.Where(x => x.Type == OrderType.Sell);

                                        lblOrdersTotal.Content = "Total Trades (" + (buys.Count() + sells.Count()) + ") :";
                                        txtTotalBuy.Text       = buys.Count().ToString() + " buys.";
                                        txtTotalSell.Text      = sells.Count().ToString() + " sells.";

                                        if (buys.Any())
                                        {
                                            lblFirstBid.Content = "1st. Buy: " + buys.First().Time;
                                        }

                                        if (sells.Any())
                                        {
                                            lblFirstAsk.Content = "1st. Sell: " + sells.First().Time;
                                        }

                                        if (buys.Any() && sells.Any())
                                        {
                                            lblGapSenconds.Content = "Trade Gap: " + (sells.First().Time - buys.First().Time).TotalSeconds + "s.";
                                        }
                                    }
                                }
                            });
                        }
                        else
                        {
                            ResetDetailsFields();
                        }
                    }
                }
                catch
                {
                    ResetDetailsFields();
                }
                finally
                {
                    highOrderRate = null;
                    lowOrderRate  = null;
                }
            });
        }
        public async Task <IActionResult> Rates(RatesViewModel model, string command = null, string storeId = null, CancellationToken cancellationToken = default)
        {
            model.SetExchangeRates(GetSupportedExchanges(), model.PreferredExchange);
            model.StoreId = storeId ?? model.StoreId;
            CurrencyPair[] currencyPairs = null;
            try
            {
                currencyPairs = model.DefaultCurrencyPairs?
                                .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                .Select(p => CurrencyPair.Parse(p))
                                .ToArray();
            }
            catch
            {
                ModelState.AddModelError(nameof(model.DefaultCurrencyPairs), "Pares de divisas no válidos (deben ser, por ejemplo: BTC_USD, BTC_CAD, BTC_JPY)");
            }
            if (!ModelState.IsValid)
            {
                return(View(model));
            }
            if (model.PreferredExchange != null)
            {
                model.PreferredExchange = model.PreferredExchange.Trim().ToLowerInvariant();
            }

            var blob = StoreData.GetStoreBlob();

            model.DefaultScript      = blob.GetDefaultRateRules(_NetworkProvider).ToString();
            model.AvailableExchanges = GetSupportedExchanges();

            blob.PreferredExchange    = model.PreferredExchange;
            blob.Spread               = (decimal)model.Spread / 100.0m;
            blob.DefaultCurrencyPairs = currencyPairs;
            if (!model.ShowScripting)
            {
                if (!GetSupportedExchanges().Select(c => c.Name).Contains(blob.PreferredExchange, StringComparer.OrdinalIgnoreCase))
                {
                    ModelState.AddModelError(nameof(model.PreferredExchange), $"Intercambio no soportado ({model.RateSource})");
                    return(View(model));
                }
            }
            RateRules rules = null;

            if (model.ShowScripting)
            {
                if (!RateRules.TryParse(model.Script, out rules, out var errors))
                {
                    errors = errors ?? new List <RateRulesErrors>();
                    var errorString = String.Join(", ", errors.ToArray());
                    ModelState.AddModelError(nameof(model.Script), $"Error de sintáxis ({errorString})");
                    return(View(model));
                }
                else
                {
                    blob.RateScript = rules.ToString();
                    ModelState.Remove(nameof(model.Script));
                    model.Script = blob.RateScript;
                }
            }
            rules = blob.GetRateRules(_NetworkProvider);

            if (command == "Test")
            {
                if (string.IsNullOrWhiteSpace(model.ScriptTest))
                {
                    ModelState.AddModelError(nameof(model.ScriptTest), "Complete el par de divisas para probar (como BTC_USD, BTC_CAD)");
                    return(View(model));
                }
                var splitted = model.ScriptTest.Split(',', StringSplitOptions.RemoveEmptyEntries);

                var pairs = new List <CurrencyPair>();
                foreach (var pair in splitted)
                {
                    if (!CurrencyPair.TryParse(pair, out var currencyPair))
                    {
                        ModelState.AddModelError(nameof(model.ScriptTest), $"Par de divisas no válido '{pair}' (debe ser formateado como BTC_USD,BTC_CAD)");
                        return(View(model));
                    }
                    pairs.Add(currencyPair);
                }

                var fetchs      = _RateFactory.FetchRates(pairs.ToHashSet(), rules, cancellationToken);
                var testResults = new List <RatesViewModel.TestResultViewModel>();
                foreach (var fetch in fetchs)
                {
                    var testResult = await(fetch.Value);
                    testResults.Add(new RatesViewModel.TestResultViewModel()
                    {
                        CurrencyPair = fetch.Key.ToString(),
                        Error        = testResult.Errors.Count != 0,
                        Rule         = testResult.Errors.Count == 0 ? testResult.Rule + " = " + testResult.BidAsk.Bid.ToString(CultureInfo.InvariantCulture)
                                                            : testResult.EvaluatedRule
                    });
                }
                model.TestRateRules = testResults;
                return(View(model));
            }
            else // command == Save
            {
                if (StoreData.SetStoreBlob(blob))
                {
                    await _Repo.UpdateStore(StoreData);

                    StatusMessage = "Configuraciones de tarifas actualizadas";
                }
                return(RedirectToAction(nameof(Rates), new
                {
                    storeId = StoreData.Id
                }));
            }
        }
示例#6
0
        public void Start()
        {
            if (!Directory.Exists(_Directory))
            {
                Directory.CreateDirectory(_Directory);
            }
            string chain          = NBXplorerDefaultSettings.GetFolderName(NetworkType.Regtest);
            string chainDirectory = Path.Combine(_Directory, chain);

            if (!Directory.Exists(chainDirectory))
            {
                Directory.CreateDirectory(chainDirectory);
            }


            StringBuilder config = new StringBuilder();

            config.AppendLine($"{chain.ToLowerInvariant()}=1");
            config.AppendLine($"port={Port}");
            config.AppendLine($"chains=btc,ltc");

            config.AppendLine($"btc.explorer.url={NBXplorerUri.AbsoluteUri}");
            config.AppendLine($"btc.explorer.cookiefile=0");

            config.AppendLine($"ltc.explorer.url={LTCNBXplorerUri.AbsoluteUri}");
            config.AppendLine($"ltc.explorer.cookiefile=0");
            config.AppendLine($"btc.lightning={IntegratedLightning.AbsoluteUri}");

            if (TestDatabase == TestDatabases.MySQL && !String.IsNullOrEmpty(MySQL))
            {
                config.AppendLine($"mysql=" + MySQL);
            }
            else if (!String.IsNullOrEmpty(Postgres))
            {
                config.AppendLine($"postgres=" + Postgres);
            }
            var confPath = Path.Combine(chainDirectory, "settings.config");

            File.WriteAllText(confPath, config.ToString());

            ServerUri              = new Uri("http://" + HostName + ":" + Port + "/");
            HttpClient             = new HttpClient();
            HttpClient.BaseAddress = ServerUri;
            Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development");
            var conf = new DefaultConfiguration()
            {
                Logger = Logs.LogProvider.CreateLogger("Console")
            }.CreateConfiguration(new[] { "--datadir", _Directory, "--conf", confPath, "--disable-registration", "false" });

            _Host = new WebHostBuilder()
                    .UseConfiguration(conf)
                    .UseContentRoot(FindBTCPayServerDirectory())
                    .ConfigureServices(s =>
            {
                s.AddLogging(l =>
                {
                    l.AddFilter("System.Net.Http.HttpClient", LogLevel.Critical);
                    l.SetMinimumLevel(LogLevel.Information)
                    .AddFilter("Microsoft", LogLevel.Error)
                    .AddFilter("Hangfire", LogLevel.Error)
                    .AddProvider(Logs.LogProvider);
                });
            })
                    .UseKestrel()
                    .UseStartup <Startup>()
                    .Build();
            _Host.Start();
            InvoiceRepository = (InvoiceRepository)_Host.Services.GetService(typeof(InvoiceRepository));
            StoreRepository   = (StoreRepository)_Host.Services.GetService(typeof(StoreRepository));
            var dashBoard = (NBXplorerDashboard)_Host.Services.GetService(typeof(NBXplorerDashboard));

            while (!dashBoard.IsFullySynched())
            {
                Thread.Sleep(10);
            }

            if (MockRates)
            {
                var rateProvider = (RateProviderFactory)_Host.Services.GetService(typeof(RateProviderFactory));
                rateProvider.Providers.Clear();

                var coinAverageMock = new MockRateProvider();
                coinAverageMock.ExchangeRates.Add(new Rating.ExchangeRate()
                {
                    Exchange     = "coinaverage",
                    CurrencyPair = CurrencyPair.Parse("BTC_USD"),
                    BidAsk       = new BidAsk(5000m)
                });
                coinAverageMock.ExchangeRates.Add(new Rating.ExchangeRate()
                {
                    Exchange     = "coinaverage",
                    CurrencyPair = CurrencyPair.Parse("BTC_CAD"),
                    BidAsk       = new BidAsk(4500m)
                });
                coinAverageMock.ExchangeRates.Add(new Rating.ExchangeRate()
                {
                    Exchange     = "coinaverage",
                    CurrencyPair = CurrencyPair.Parse("LTC_BTC"),
                    BidAsk       = new BidAsk(0.001m)
                });
                coinAverageMock.ExchangeRates.Add(new Rating.ExchangeRate()
                {
                    Exchange     = "coinaverage",
                    CurrencyPair = CurrencyPair.Parse("LTC_USD"),
                    BidAsk       = new BidAsk(500m)
                });
                rateProvider.Providers.Add("coinaverage", coinAverageMock);

                var bitflyerMock = new MockRateProvider();
                bitflyerMock.ExchangeRates.Add(new Rating.ExchangeRate()
                {
                    Exchange     = "bitflyer",
                    CurrencyPair = CurrencyPair.Parse("BTC_JPY"),
                    BidAsk       = new BidAsk(700000m)
                });
                rateProvider.Providers.Add("bitflyer", bitflyerMock);

                var quadrigacx = new MockRateProvider();
                quadrigacx.ExchangeRates.Add(new Rating.ExchangeRate()
                {
                    Exchange     = "quadrigacx",
                    CurrencyPair = CurrencyPair.Parse("BTC_CAD"),
                    BidAsk       = new BidAsk(6000m)
                });
                rateProvider.Providers.Add("quadrigacx", quadrigacx);

                var bittrex = new MockRateProvider();
                bittrex.ExchangeRates.Add(new Rating.ExchangeRate()
                {
                    Exchange     = "bittrex",
                    CurrencyPair = CurrencyPair.Parse("DOGE_BTC"),
                    BidAsk       = new BidAsk(0.004m)
                });
                rateProvider.Providers.Add("bittrex", bittrex);
            }
        }
        public void Start()
        {
            if (!Directory.Exists(_Directory))
            {
                Directory.CreateDirectory(_Directory);
            }
            string chain          = NBXplorerDefaultSettings.GetFolderName(NetworkType.Regtest);
            string chainDirectory = Path.Combine(_Directory, chain);

            if (!Directory.Exists(chainDirectory))
            {
                Directory.CreateDirectory(chainDirectory);
            }


            StringBuilder config = new StringBuilder();

            config.AppendLine($"{chain.ToLowerInvariant()}=1");
            config.AppendLine($"port={Port}");
            config.AppendLine($"chains=btc,ltc");

            config.AppendLine($"btc.explorer.url={NBXplorerUri.AbsoluteUri}");
            config.AppendLine($"btc.explorer.cookiefile=0");

            config.AppendLine($"ltc.explorer.url={LTCNBXplorerUri.AbsoluteUri}");
            config.AppendLine($"ltc.explorer.cookiefile=0");

            config.AppendLine($"btc.lightning={IntegratedLightning.AbsoluteUri}");

            if (Postgres != null)
            {
                config.AppendLine($"postgres=" + Postgres);
            }
            var confPath = Path.Combine(chainDirectory, "settings.config");

            File.WriteAllText(confPath, config.ToString());

            ServerUri = new Uri("http://" + HostName + ":" + Port + "/");

            Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development");
            var conf = new DefaultConfiguration()
            {
                Logger = Logs.LogProvider.CreateLogger("Console")
            }.CreateConfiguration(new[] { "--datadir", _Directory, "--conf", confPath });

            _Host = new WebHostBuilder()
                    .UseConfiguration(conf)
                    .ConfigureServices(s =>
            {
                s.AddLogging(l =>
                {
                    l.SetMinimumLevel(LogLevel.Information)
                    .AddFilter("Microsoft", LogLevel.Error)
                    .AddFilter("Hangfire", LogLevel.Error)
                    .AddProvider(Logs.LogProvider);
                });
            })
                    .UseKestrel()
                    .UseStartup <Startup>()
                    .Build();
            _Host.Start();
            InvoiceRepository = (InvoiceRepository)_Host.Services.GetService(typeof(InvoiceRepository));

            var rateProvider = (BTCPayRateProviderFactory)_Host.Services.GetService(typeof(BTCPayRateProviderFactory));

            rateProvider.DirectProviders.Clear();

            var coinAverageMock = new MockRateProvider();

            coinAverageMock.ExchangeRates.Add(new Rating.ExchangeRate()
            {
                Exchange     = "coinaverage",
                CurrencyPair = CurrencyPair.Parse("BTC_USD"),
                Value        = 5000m
            });
            coinAverageMock.ExchangeRates.Add(new Rating.ExchangeRate()
            {
                Exchange     = "coinaverage",
                CurrencyPair = CurrencyPair.Parse("BTC_CAD"),
                Value        = 4500m
            });
            coinAverageMock.ExchangeRates.Add(new Rating.ExchangeRate()
            {
                Exchange     = "coinaverage",
                CurrencyPair = CurrencyPair.Parse("LTC_USD"),
                Value        = 500m
            });
            rateProvider.DirectProviders.Add("coinaverage", coinAverageMock);
        }