Recommended exchange to be resolved during Invoice Creation (#5976)

* Recommended Exchange Rate Selection during Invoice Creation

* Make Recommended exchanges pluginifiable
This commit is contained in:
Nicolas Dorier
2024-05-13 22:29:42 +09:00
committed by GitHub
parent b0da802abe
commit d96b066658
26 changed files with 255 additions and 166 deletions

View File

@@ -14,6 +14,7 @@ using BTCPayServer.Rating;
using BTCPayServer.Services.Rates;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using static BTCPayServer.Lightning.Eclair.Models.ChannelResponse;
namespace BTCPayServer.Controllers;
@@ -22,17 +23,9 @@ public partial class UIStoresController
[HttpGet("{storeId}/rates")]
public IActionResult Rates()
{
var exchanges = GetSupportedExchanges().ToList();
var storeBlob = CurrentStore.GetStoreBlob();
var vm = new RatesViewModel();
vm.SetExchangeRates(exchanges, storeBlob.PreferredExchange ?? storeBlob.GetRecommendedExchange());
vm.Spread = (double)(storeBlob.Spread * 100m);
vm.StoreId = CurrentStore.Id;
vm.Script = storeBlob.GetRateRules(_defaultRates).ToString();
vm.DefaultScript = storeBlob.GetDefaultRateRules(_defaultRates).ToString();
vm.AvailableExchanges = exchanges;
vm.DefaultCurrencyPairs = storeBlob.GetDefaultCurrencyPairString();
vm.ShowScripting = storeBlob.RateScripting;
FillFromStore(vm, storeBlob);
return View(vm);
}
@@ -48,9 +41,6 @@ public partial class UIStoresController
{
return RedirectToAction(nameof(ShowRateRules), new { scripting = false, storeId = model.StoreId });
}
var exchanges = GetSupportedExchanges().ToList();
model.SetExchangeRates(exchanges, model.PreferredExchange ?? HttpContext.GetStoreData().GetStoreBlob().GetRecommendedExchange());
model.StoreId = storeId ?? model.StoreId;
CurrencyPair[]? currencyPairs = null;
try
@@ -70,22 +60,10 @@ public partial class UIStoresController
}
if (model.PreferredExchange != null)
model.PreferredExchange = model.PreferredExchange.Trim().ToLowerInvariant();
if (string.IsNullOrEmpty(model.PreferredExchange))
model.PreferredExchange = null;
var blob = CurrentStore.GetStoreBlob();
model.DefaultScript = blob.GetDefaultRateRules(_defaultRates).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;
if (model.ShowScripting)
{
@@ -94,17 +72,20 @@ public partial class UIStoresController
errors ??= [];
var errorString = string.Join(", ", errors.ToArray());
ModelState.AddModelError(nameof(model.Script), $"Parsing error ({errorString})");
FillFromStore(model, blob);
return View(model);
}
else
{
blob.RateScript = rules.ToString();
ModelState.Remove(nameof(model.Script));
model.Script = blob.RateScript;
}
}
rules = blob.GetRateRules(_defaultRates);
blob.PreferredExchange = model.PreferredExchange;
blob.Spread = (decimal)model.Spread / 100.0m;
blob.DefaultCurrencyPairs = currencyPairs;
FillFromStore(model, blob);
rules = blob.GetRateRules(_defaultRules);
if (command == "Test")
{
if (string.IsNullOrWhiteSpace(model.ScriptTest))
@@ -142,6 +123,12 @@ public partial class UIStoresController
return View(model);
}
if (model.PreferredExchange is not null && !model.AvailableExchanges.Any(a => a.Id == model.PreferredExchange))
{
ModelState.AddModelError(nameof(model.PreferredExchange), $"Unsupported exchange");
return View(model);
}
// command == Save
if (CurrentStore.SetStoreBlob(blob))
{
@@ -175,16 +162,29 @@ public partial class UIStoresController
{
var blob = CurrentStore.GetStoreBlob();
blob.RateScripting = scripting;
blob.RateScript = blob.GetDefaultRateRules(_defaultRates).ToString();
blob.RateScript = blob.GetDefaultRateRules(_defaultRules).ToString();
CurrentStore.SetStoreBlob(blob);
await _storeRepo.UpdateStore(CurrentStore);
TempData[WellKnownTempData.SuccessMessage] = "Rate rules scripting " + (scripting ? "activated" : "deactivated");
return RedirectToAction(nameof(Rates), new { storeId = CurrentStore.Id });
}
private IEnumerable<RateSourceInfo> GetSupportedExchanges()
private void FillFromStore(RatesViewModel vm, StoreBlob storeBlob)
{
return _rateFactory.RateProviderFactory.AvailableRateProviders
var sources = _rateFactory.RateProviderFactory.AvailableRateProviders
.OrderBy(s => s.DisplayName, StringComparer.OrdinalIgnoreCase);
vm.AvailableExchanges = sources;
var exchange = storeBlob.GetPreferredExchange(_defaultRules);
var chosenSource = sources.First(r => r.Id == exchange);
vm.Exchanges = UIUserStoresController.GetExchangesSelectList(_rateFactory, _defaultRules, storeBlob);
vm.PreferredExchange = vm.Exchanges.SelectedValue as string;
vm.PreferredResolvedExchange = chosenSource.Id;
vm.RateSource = chosenSource.Url;
vm.Spread = (double)(storeBlob.Spread * 100m);
vm.StoreId = CurrentStore.Id;
vm.Script = storeBlob.GetRateRules(_defaultRules).ToString();
vm.DefaultScript = storeBlob.GetDefaultRateRules(_defaultRules).ToString();
vm.DefaultCurrencyPairs = storeBlob.GetDefaultCurrencyPairString();
vm.ShowScripting = storeBlob.RateScripting;
}
}