Use better default than coingecko when creating a new store (#4416)

* Use better default than coingecko when creating a new store

* Improve recommended exchange UX

* Add btcturk for TRY

* Fix recommendation

Co-authored-by: Dennis Reimann <mail@dennisreimann.de>
This commit is contained in:
Nicolas Dorier 2022-12-14 13:33:27 +09:00 committed by GitHub
parent dea019ebdc
commit 18ba0148ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 38 additions and 10 deletions

View file

@ -176,6 +176,7 @@ namespace BTCPayServer.Tests
var name = "Store" + RandomUtils.GetUInt64();
TestLogs.LogInformation($"Created store {name}");
Driver.WaitForElement(By.Id("Name")).SendKeys(name);
new SelectElement(Driver.FindElement(By.Id("PreferredExchange"))).SelectByText("CoinGecko");
Driver.WaitForElement(By.Id("Create")).Click();
Driver.FindElement(By.Id("StoreNav-StoreSettings")).Click();
Driver.FindElement(By.Id($"SectionNav-{StoreNavPages.General.ToString()}")).Click();

View file

@ -174,7 +174,7 @@ namespace BTCPayServer.Tests
await RegisterAsync();
}
var store = GetController<UIUserStoresController>();
await store.CreateStore(new CreateStoreViewModel { Name = "Test Store" });
await store.CreateStore(new CreateStoreViewModel { Name = "Test Store", PreferredExchange = "coingecko" });
StoreId = store.CreatedStoreId;
parent.Stores.Add(StoreId);
}

View file

@ -201,7 +201,7 @@ namespace BTCPayServer.Controllers
var exchanges = GetSupportedExchanges();
var storeBlob = CurrentStore.GetStoreBlob();
var vm = new RatesViewModel();
vm.SetExchangeRates(exchanges, storeBlob.PreferredExchange ?? CoinGeckoRateProvider.CoinGeckoName);
vm.SetExchangeRates(exchanges, storeBlob.PreferredExchange ?? storeBlob.GetRecommendedExchange());
vm.Spread = (double)(storeBlob.Spread * 100m);
vm.StoreId = CurrentStore.Id;
vm.Script = storeBlob.GetRateRules(_NetworkProvider).ToString();
@ -225,7 +225,7 @@ namespace BTCPayServer.Controllers
}
var exchanges = GetSupportedExchanges();
model.SetExchangeRates(exchanges, model.PreferredExchange);
model.SetExchangeRates(exchanges, model.PreferredExchange ?? this.HttpContext.GetStoreData().GetStoreBlob().GetRecommendedExchange());
model.StoreId = storeId ?? model.StoreId;
CurrencyPair[]? currencyPairs = null;
try

View file

@ -44,7 +44,7 @@ namespace BTCPayServer.Controllers
var vm = new CreateStoreViewModel
{
DefaultCurrency = StoreBlob.StandardDefaultCurrency,
Exchanges = GetExchangesSelectList(CoinGeckoRateProvider.CoinGeckoName)
Exchanges = GetExchangesSelectList(null)
};
return View(vm);
@ -99,7 +99,9 @@ namespace BTCPayServer.Controllers
var exchanges = _rateFactory.RateProviderFactory
.GetSupportedExchanges()
.Where(r => !string.IsNullOrWhiteSpace(r.Name))
.OrderBy(s => s.Id, StringComparer.OrdinalIgnoreCase);
.OrderBy(s => s.Id, StringComparer.OrdinalIgnoreCase)
.ToList();
exchanges.Insert(0, new AvailableRateProvider(null, "Recommended", ""));
var chosen = exchanges.FirstOrDefault(f => f.Id == selected) ?? exchanges.First();
return new SelectList(exchanges, nameof(chosen.Id), nameof(chosen.Name), chosen.Id);
}

View file

@ -170,7 +170,7 @@ namespace BTCPayServer.Data
}
}
var preferredExchange = string.IsNullOrEmpty(PreferredExchange) ? CoinGeckoRateProvider.CoinGeckoName : PreferredExchange;
var preferredExchange = string.IsNullOrEmpty(PreferredExchange) ? GetRecommendedExchange() : PreferredExchange;
builder.AppendLine(CultureInfo.InvariantCulture, $"X_X = {preferredExchange}(X_X);");
BTCPayServer.Rating.RateRules.TryParse(builder.ToString(), out var rules);
@ -178,6 +178,21 @@ namespace BTCPayServer.Data
return rules;
}
public static JObject RecommendedExchanges = new ()
{
{ "EUR", "kraken" },
{ "USD", "kraken" },
{ "GBP", "kraken" },
{ "CHF", "kraken" },
{ "GTQ", "bitpay" },
{ "COP", "yadio" },
{ "JPY", "bitbank" },
{ "TRY", "btcturk" }
};
public string GetRecommendedExchange() =>
RecommendedExchanges.Property(DefaultCurrency)?.Value.ToString() ?? "coingecko";
[Obsolete("Use GetExcludedPaymentMethods instead")]
public string[] ExcludedPaymentMethods { get; set; }

View file

@ -49,7 +49,7 @@ namespace BTCPayServer.Data
{
var result = storeData.StoreBlob == null ? new StoreBlob() : new Serializer(null).ToObject<StoreBlob>(storeData.StoreBlob);
if (result.PreferredExchange == null)
result.PreferredExchange = CoinGeckoRateProvider.CoinGeckoName;
result.PreferredExchange = result.GetRecommendedExchange();
if (result.PaymentMethodCriteria is null)
result.PaymentMethodCriteria = new List<PaymentMethodCriteria>();
result.PaymentMethodCriteria.RemoveAll(criteria => criteria?.PaymentMethod is null);

View file

@ -15,7 +15,6 @@ namespace BTCPayServer.Models.StoreViewModels
[Display(Name = "Default currency")]
public string DefaultCurrency { get; set; }
[Required]
[Display(Name = "Preferred Price Source")]
public string PreferredExchange { get; set; }

View file

@ -19,9 +19,8 @@ namespace BTCPayServer.Models.StoreViewModels
public void SetExchangeRates(IEnumerable<AvailableRateProvider> supportedList, string preferredExchange)
{
var defaultStore = preferredExchange ?? CoinGeckoRateProvider.CoinGeckoName;
supportedList = supportedList.Select(a => new AvailableRateProvider(a.Id, a.SourceId, a.DisplayName, a.Url, a.Source)).ToArray();
var chosen = supportedList.FirstOrDefault(f => f.Id == defaultStore) ?? supportedList.FirstOrDefault();
var chosen = supportedList.FirstOrDefault(f => f.Id == preferredExchange) ?? supportedList.FirstOrDefault();
Exchanges = new SelectList(supportedList, nameof(chosen.Id), nameof(chosen.Name), chosen);
PreferredExchange = chosen?.Id;
RateSource = chosen?.Url;

View file

@ -5,6 +5,17 @@
@section PageFootContent {
<partial name="_ValidationScriptsPartial"/>
<script>
const exchanges = @Safe.Json(StoreBlob.RecommendedExchanges);
const recommended = document.querySelector("#PreferredExchange option[value='']")
const updateRecommended = currency => {
const source = exchanges[currency] || 'coingecko'
const name = source.charAt(0).toUpperCase() + source.slice(1)
recommended.innerText = `Recommended (${name})`
}
updateRecommended(@Safe.Json(Model.DefaultCurrency))
delegate('change', '#DefaultCurrency', e => updateRecommended(e.target.value))
</script>
}
<partial name="_StatusMessage" />
@ -27,6 +38,7 @@
<div class="form-group">
<label asp-for="PreferredExchange" class="form-label" data-required></label>
<select asp-for="PreferredExchange" asp-items="Model.Exchanges" class="form-select w-300px"></select>
<div class="form-text mt-2 only-for-js">The recommended price source gets chosen based on the default currency.</div>
<span asp-validation-for="PreferredExchange" class="text-danger"></span>
</div>
<div class="form-group mt-4">