mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-18 14:34:23 +01:00
Use a drop down for preferred exchange list
This commit is contained in:
@@ -5,6 +5,7 @@ using BTCPayServer.HostedServices;
|
|||||||
using BTCPayServer.Models;
|
using BTCPayServer.Models;
|
||||||
using BTCPayServer.Models.StoreViewModels;
|
using BTCPayServer.Models.StoreViewModels;
|
||||||
using BTCPayServer.Services;
|
using BTCPayServer.Services;
|
||||||
|
using BTCPayServer.Services.Rates;
|
||||||
using BTCPayServer.Services.Stores;
|
using BTCPayServer.Services.Stores;
|
||||||
using BTCPayServer.Services.Wallets;
|
using BTCPayServer.Services.Wallets;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
@@ -47,7 +48,8 @@ namespace BTCPayServer.Controllers
|
|||||||
ExplorerClientProvider explorerProvider,
|
ExplorerClientProvider explorerProvider,
|
||||||
IFeeProviderFactory feeRateProvider,
|
IFeeProviderFactory feeRateProvider,
|
||||||
LanguageService langService,
|
LanguageService langService,
|
||||||
IHostingEnvironment env)
|
IHostingEnvironment env,
|
||||||
|
CoinAverageSettings coinAverage)
|
||||||
{
|
{
|
||||||
_Dashboard = dashboard;
|
_Dashboard = dashboard;
|
||||||
_Repo = repo;
|
_Repo = repo;
|
||||||
@@ -64,7 +66,9 @@ namespace BTCPayServer.Controllers
|
|||||||
_ServiceProvider = serviceProvider;
|
_ServiceProvider = serviceProvider;
|
||||||
_BtcpayServerOptions = btcpayServerOptions;
|
_BtcpayServerOptions = btcpayServerOptions;
|
||||||
_BTCPayEnv = btcpayEnv;
|
_BTCPayEnv = btcpayEnv;
|
||||||
|
_CoinAverage = coinAverage;
|
||||||
}
|
}
|
||||||
|
CoinAverageSettings _CoinAverage;
|
||||||
NBXplorerDashboard _Dashboard;
|
NBXplorerDashboard _Dashboard;
|
||||||
BTCPayServerOptions _BtcpayServerOptions;
|
BTCPayServerOptions _BtcpayServerOptions;
|
||||||
BTCPayServerEnvironment _BTCPayEnv;
|
BTCPayServerEnvironment _BTCPayEnv;
|
||||||
@@ -237,7 +241,7 @@ namespace BTCPayServer.Controllers
|
|||||||
model.SetCryptoCurrencies(_ExplorerProvider, model.DefaultCryptoCurrency);
|
model.SetCryptoCurrencies(_ExplorerProvider, model.DefaultCryptoCurrency);
|
||||||
model.SetLanguages(_LangService, model.DefaultLang);
|
model.SetLanguages(_LangService, model.DefaultLang);
|
||||||
|
|
||||||
if(!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
{
|
{
|
||||||
return View(model);
|
return View(model);
|
||||||
}
|
}
|
||||||
@@ -273,6 +277,7 @@ namespace BTCPayServer.Controllers
|
|||||||
|
|
||||||
var storeBlob = store.GetStoreBlob();
|
var storeBlob = store.GetStoreBlob();
|
||||||
var vm = new StoreViewModel();
|
var vm = new StoreViewModel();
|
||||||
|
vm.SetExchangeRates(GetSupportedExchanges(), storeBlob.PreferredExchange.IsCoinAverage() ? "coinaverage" : storeBlob.PreferredExchange);
|
||||||
vm.Id = store.Id;
|
vm.Id = store.Id;
|
||||||
vm.StoreName = store.StoreName;
|
vm.StoreName = store.StoreName;
|
||||||
vm.StoreWebsite = store.StoreWebsite;
|
vm.StoreWebsite = store.StoreWebsite;
|
||||||
@@ -283,7 +288,6 @@ namespace BTCPayServer.Controllers
|
|||||||
vm.InvoiceExpiration = storeBlob.InvoiceExpiration;
|
vm.InvoiceExpiration = storeBlob.InvoiceExpiration;
|
||||||
vm.RateMultiplier = (double)storeBlob.GetRateMultiplier();
|
vm.RateMultiplier = (double)storeBlob.GetRateMultiplier();
|
||||||
vm.LightningDescriptionTemplate = storeBlob.LightningDescriptionTemplate;
|
vm.LightningDescriptionTemplate = storeBlob.LightningDescriptionTemplate;
|
||||||
vm.PreferredExchange = storeBlob.PreferredExchange.IsCoinAverage() ? "coinaverage" : storeBlob.PreferredExchange;
|
|
||||||
return View(vm);
|
return View(vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,6 +329,7 @@ namespace BTCPayServer.Controllers
|
|||||||
[Route("{storeId}")]
|
[Route("{storeId}")]
|
||||||
public async Task<IActionResult> UpdateStore(string storeId, StoreViewModel model)
|
public async Task<IActionResult> UpdateStore(string storeId, StoreViewModel model)
|
||||||
{
|
{
|
||||||
|
model.SetExchangeRates(GetSupportedExchanges(), model.PreferredExchange);
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
{
|
{
|
||||||
return View(model);
|
return View(model);
|
||||||
@@ -371,14 +376,11 @@ namespace BTCPayServer.Controllers
|
|||||||
|
|
||||||
if (!blob.PreferredExchange.IsCoinAverage() && newExchange)
|
if (!blob.PreferredExchange.IsCoinAverage() && newExchange)
|
||||||
{
|
{
|
||||||
using (HttpClient client = new HttpClient())
|
|
||||||
|
if (!GetSupportedExchanges().Select(c => c.Name).Contains(blob.PreferredExchange, StringComparer.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
var rate = await client.GetAsync(model.RateSource);
|
ModelState.AddModelError(nameof(model.PreferredExchange), $"Unsupported exchange ({model.RateSource})");
|
||||||
if (rate.StatusCode == System.Net.HttpStatusCode.NotFound)
|
return View(model);
|
||||||
{
|
|
||||||
ModelState.AddModelError(nameof(model.PreferredExchange), $"Unsupported exchange ({model.RateSource})");
|
|
||||||
return View(model);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,6 +396,11 @@ namespace BTCPayServer.Controllers
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private (String DisplayName, String Name)[] GetSupportedExchanges()
|
||||||
|
{
|
||||||
|
return new[] { ("Coin Average", "coinaverage") }.Concat(_CoinAverage.AvailableExchanges).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
private DerivationStrategy ParseDerivationStrategy(string derivationScheme, Script hint, BTCPayNetwork network)
|
private DerivationStrategy ParseDerivationStrategy(string derivationScheme, Script hint, BTCPayNetwork network)
|
||||||
{
|
{
|
||||||
var parser = new DerivationSchemeParser(network.NBitcoinNetwork, network.DefaultSettings.ChainType);
|
var parser = new DerivationSchemeParser(network.NBitcoinNetwork, network.DefaultSettings.ChainType);
|
||||||
|
|||||||
@@ -63,9 +63,14 @@ namespace BTCPayServer.HostedServices
|
|||||||
}
|
}
|
||||||
Task RefreshCoinAverageSupportedExchanges(CancellationToken cancellation)
|
Task RefreshCoinAverageSupportedExchanges(CancellationToken cancellation)
|
||||||
{
|
{
|
||||||
return Timer(async () =>
|
return Timer(async () =>
|
||||||
{
|
{
|
||||||
var tickers = await new CoinAverageRateProvider("BTC").GetExchangeTickersAsync();
|
var tickers = await new CoinAverageRateProvider("BTC").GetExchangeTickersAsync();
|
||||||
|
_coinAverageSettings.AvailableExchanges = tickers
|
||||||
|
.Exchanges
|
||||||
|
.Select(c => (c.DisplayName, c.Name))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
await Task.Delay(TimeSpan.FromHours(5), cancellation);
|
await Task.Delay(TimeSpan.FromHours(5), cancellation);
|
||||||
}, cancellation);
|
}, cancellation);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ namespace BTCPayServer.Models.StoreViewModels
|
|||||||
{
|
{
|
||||||
public class StoreViewModel
|
public class StoreViewModel
|
||||||
{
|
{
|
||||||
|
class Format
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Value { get; set; }
|
||||||
|
}
|
||||||
public class DerivationScheme
|
public class DerivationScheme
|
||||||
{
|
{
|
||||||
public string Crypto { get; set; }
|
public string Crypto { get; set; }
|
||||||
@@ -44,6 +49,17 @@ namespace BTCPayServer.Models.StoreViewModels
|
|||||||
|
|
||||||
public List<StoreViewModel.DerivationScheme> DerivationSchemes { get; set; } = new List<StoreViewModel.DerivationScheme>();
|
public List<StoreViewModel.DerivationScheme> DerivationSchemes { get; set; } = new List<StoreViewModel.DerivationScheme>();
|
||||||
|
|
||||||
|
public void SetExchangeRates((String DisplayName, String Name)[] supportedList, string preferredExchange)
|
||||||
|
{
|
||||||
|
var defaultStore = preferredExchange ?? "coinaverage";
|
||||||
|
var choices = supportedList.Select(o => new Format() { Name = o.DisplayName, Value = o.Name }).ToArray();
|
||||||
|
var chosen = choices.FirstOrDefault(f => f.Value == defaultStore) ?? choices.FirstOrDefault();
|
||||||
|
Exchanges = new SelectList(choices, nameof(chosen.Value), nameof(chosen.Name), chosen);
|
||||||
|
PreferredExchange = chosen.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SelectList Exchanges { get; set; }
|
||||||
|
|
||||||
[Display(Name = "Preferred price source (eg. bitfinex, bitstamp...)")]
|
[Display(Name = "Preferred price source (eg. bitfinex, bitstamp...)")]
|
||||||
public string PreferredExchange { get; set; }
|
public string PreferredExchange { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace BTCPayServer.Services.Rates
|
|||||||
private static readonly DateTime _epochUtc = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
private static readonly DateTime _epochUtc = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||||
|
|
||||||
public (String PublicKey, String PrivateKey)? KeyPair { get; set; }
|
public (String PublicKey, String PrivateKey)? KeyPair { get; set; }
|
||||||
public string[] AvailableExchanges { get; set; } = Array.Empty<string>();
|
public (String DisplayName, String Name)[] AvailableExchanges { get; set; } = Array.Empty<(String DisplayName, String Name)>();
|
||||||
|
|
||||||
public Task AddHeader(HttpRequestMessage message)
|
public Task AddHeader(HttpRequestMessage message)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,10 +36,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label asp-for="PreferredExchange"></label>
|
<label asp-for="PreferredExchange"></label>
|
||||||
<input asp-for="PreferredExchange" class="form-control" />
|
<select asp-for="PreferredExchange" asp-items="Model.Exchanges" class="form-control"></select>
|
||||||
<span asp-validation-for="PreferredExchange" class="text-danger"></span>
|
<span asp-validation-for="PreferredExchange" class="text-danger"></span>
|
||||||
<p id="PreferredExchangeHelpBlock" class="form-text text-muted">
|
<p id="PreferredExchangeHelpBlock" class="form-text text-muted">
|
||||||
Current price source is <a href="@Model.RateSource" target="_blank">@Model.PreferredExchange</a>.<small> (using 1 minute cache)</small>
|
Current price source is <a href="@Model.RateSource" target="_blank">@Model.PreferredExchange</a>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -81,13 +81,13 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach (var scheme in Model.DerivationSchemes)
|
@foreach(var scheme in Model.DerivationSchemes)
|
||||||
{
|
{
|
||||||
<tr>
|
<tr>
|
||||||
<td>@scheme.Crypto</td>
|
<td>@scheme.Crypto</td>
|
||||||
<td style="max-width:300px;overflow:hidden;">@scheme.Value</td>
|
<td style="max-width:300px;overflow:hidden;">@scheme.Value</td>
|
||||||
<td style="text-align:right">
|
<td style="text-align:right">
|
||||||
@if (!string.IsNullOrWhiteSpace(scheme.Value))
|
@if(!string.IsNullOrWhiteSpace(scheme.Value))
|
||||||
{
|
{
|
||||||
<a asp-action="Wallet" asp-route-cryptoCode="@scheme.Crypto">Wallet</a><span> - </span>
|
<a asp-action="Wallet" asp-route-cryptoCode="@scheme.Crypto">Wallet</a><span> - </span>
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach (var scheme in Model.LightningNodes)
|
@foreach(var scheme in Model.LightningNodes)
|
||||||
{
|
{
|
||||||
<tr>
|
<tr>
|
||||||
<td>@scheme.CryptoCode</td>
|
<td>@scheme.CryptoCode</td>
|
||||||
|
|||||||
Reference in New Issue
Block a user