Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
b04d70f141 | |||
101d6131c7 | |||
faabd68f6f | |||
1a54f2d01a | |||
4276994265 | |||
2c6133b4f7 | |||
64181d1a93 | |||
25e9a27a78 | |||
f3edaf5160 | |||
8cafa8a483 | |||
724af44e41 | |||
bac9ef4f93 | |||
ada6f3b844 | |||
c8a26ce952 | |||
6cf80b7533 | |||
79df523bb2 | |||
e921f9757a | |||
bed9737d64 | |||
2583eb15ec | |||
1879ea55e8 |
@ -35,6 +35,7 @@ using BTCPayServer.Services.Apps;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Rating;
|
||||
using BTCPayServer.Validation;
|
||||
using ExchangeSharp;
|
||||
@ -731,6 +732,40 @@ namespace BTCPayServer.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanGetRates()
|
||||
{
|
||||
using (var tester = ServerTester.Create())
|
||||
{
|
||||
tester.Start();
|
||||
var acc = tester.NewAccount();
|
||||
acc.GrantAccess();
|
||||
acc.RegisterDerivationScheme("BTC");
|
||||
acc.RegisterDerivationScheme("LTC");
|
||||
|
||||
var rateController = acc.GetController<RateController>();
|
||||
var GetBaseCurrencyRatesResult = JObject.Parse(((JsonResult)rateController.GetBaseCurrencyRates("BTC", acc.StoreId)
|
||||
.GetAwaiter().GetResult()).ToJson()).ToObject<DataWrapper<Rate[]>>();
|
||||
Assert.NotNull(GetBaseCurrencyRatesResult);
|
||||
Assert.NotNull(GetBaseCurrencyRatesResult.Data);
|
||||
Assert.Single(GetBaseCurrencyRatesResult.Data);
|
||||
Assert.Equal("LTC", GetBaseCurrencyRatesResult.Data.First().Code);
|
||||
|
||||
var GetRatesResult = JObject.Parse(((JsonResult)rateController.GetRates(null, acc.StoreId)
|
||||
.GetAwaiter().GetResult()).ToJson()).ToObject<DataWrapper<Rate[]>>();
|
||||
Assert.NotNull(GetRatesResult);
|
||||
Assert.NotNull(GetRatesResult.Data);
|
||||
Assert.Equal(2, GetRatesResult.Data.Length);
|
||||
|
||||
var GetCurrencyPairRateResult = JObject.Parse(((JsonResult)rateController.GetCurrencyPairRate("BTC", "LTC", acc.StoreId)
|
||||
.GetAwaiter().GetResult()).ToJson()).ToObject<DataWrapper<Rate>>();
|
||||
|
||||
Assert.NotNull(GetCurrencyPairRateResult);
|
||||
Assert.NotNull(GetCurrencyPairRateResult.Data);
|
||||
Assert.Equal("LTC", GetCurrencyPairRateResult.Data.Code);
|
||||
}
|
||||
}
|
||||
|
||||
private void AssertSearchInvoice(TestAccount acc, bool expected, string invoiceId, string filter)
|
||||
{
|
||||
var result = (Models.InvoicingModels.InvoicesModel)((ViewResult)acc.GetController<InvoiceController>().ListInvoices(filter).Result).Model;
|
||||
|
@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<Version>1.0.2.80</Version>
|
||||
<Version>1.0.2.81</Version>
|
||||
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
|
@ -213,7 +213,7 @@ namespace BTCPayServer.Controllers
|
||||
bool isDefaultCrypto = false;
|
||||
if (paymentMethodIdStr == null)
|
||||
{
|
||||
paymentMethodIdStr = store.GetDefaultCrypto();
|
||||
paymentMethodIdStr = store.GetDefaultCrypto(_NetworkProvider);
|
||||
isDefaultCrypto = true;
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,57 @@ namespace BTCPayServer.Controllers
|
||||
_CurrencyNameTable = currencyNameTable ?? throw new ArgumentNullException(nameof(currencyNameTable));
|
||||
}
|
||||
|
||||
[Route("rates/{baseCurrency}")]
|
||||
[HttpGet]
|
||||
[BitpayAPIConstraint]
|
||||
public async Task<IActionResult> GetBaseCurrencyRates(string baseCurrency, string storeId)
|
||||
{
|
||||
storeId = storeId ?? this.HttpContext.GetStoreData()?.Id;
|
||||
var store = this.HttpContext.GetStoreData();
|
||||
if (store == null || store.Id != storeId)
|
||||
store = await _StoreRepo.FindStore(storeId);
|
||||
if (store == null)
|
||||
{
|
||||
var err = Json(new BitpayErrorsModel() { Error = "Store not found" });
|
||||
err.StatusCode = 404;
|
||||
return err;
|
||||
}
|
||||
var currencypairs = "";
|
||||
var supportedMethods = store.GetSupportedPaymentMethods(_NetworkProvider);
|
||||
|
||||
var currencyCodes = supportedMethods.Where(method => !string.IsNullOrEmpty(method.PaymentId.CryptoCode))
|
||||
.Select(method => method.PaymentId.CryptoCode).Distinct();
|
||||
|
||||
|
||||
foreach (var currencyCode in currencyCodes)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(currencypairs))
|
||||
{
|
||||
currencypairs += ",";
|
||||
}
|
||||
currencypairs += baseCurrency + "_ " + currencyCode;
|
||||
}
|
||||
var result = await GetRates2(currencypairs, store.Id);
|
||||
var rates = (result as JsonResult)?.Value as Rate[];
|
||||
if (rates == null)
|
||||
return result;
|
||||
return Json(new DataWrapper<Rate[]>(rates));
|
||||
}
|
||||
|
||||
|
||||
[Route("rates/{baseCurrency}/{currency}")]
|
||||
[HttpGet]
|
||||
[BitpayAPIConstraint]
|
||||
public async Task<IActionResult> GetCurrencyPairRate(string baseCurrency, string currency, string storeId)
|
||||
{
|
||||
storeId = storeId ?? this.HttpContext.GetStoreData()?.Id;
|
||||
var result = await GetRates2($"{baseCurrency}_{currency}", storeId);
|
||||
var rates = (result as JsonResult)?.Value as Rate[];
|
||||
if (rates == null)
|
||||
return result;
|
||||
return Json(new DataWrapper<Rate>(rates.First()));
|
||||
}
|
||||
|
||||
[Route("rates")]
|
||||
[HttpGet]
|
||||
[BitpayAPIConstraint]
|
||||
@ -44,19 +95,19 @@ namespace BTCPayServer.Controllers
|
||||
return Json(new DataWrapper<Rate[]>(rates));
|
||||
}
|
||||
|
||||
|
||||
[Route("api/rates")]
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> GetRates2(string currencyPairs, string storeId)
|
||||
{
|
||||
if(storeId == null || currencyPairs == null)
|
||||
if (storeId == null)
|
||||
{
|
||||
var result = Json(new BitpayErrorsModel() { Error = "You need to specify storeId (in your store settings) and currencyPairs (eg. BTC_USD,LTC_CAD)" });
|
||||
var result = Json(new BitpayErrorsModel() { Error = "You need to specify storeId (in your store settings)" });
|
||||
result.StatusCode = 400;
|
||||
return result;
|
||||
}
|
||||
|
||||
var store = this.HttpContext.GetStoreData();
|
||||
if(store == null || store.Id != storeId)
|
||||
if (store == null || store.Id != storeId)
|
||||
store = await _StoreRepo.FindStore(storeId);
|
||||
if (store == null)
|
||||
{
|
||||
@ -64,12 +115,40 @@ namespace BTCPayServer.Controllers
|
||||
result.StatusCode = 404;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (currencyPairs == null)
|
||||
{
|
||||
currencyPairs = "";
|
||||
var supportedMethods = store.GetSupportedPaymentMethods(_NetworkProvider);
|
||||
var currencyCodes = supportedMethods.Where(method => !string.IsNullOrEmpty(method.PaymentId.CryptoCode))
|
||||
.Select(method => method.PaymentId.CryptoCode).Distinct();
|
||||
var defaultCrypto = store.GetDefaultCrypto(_NetworkProvider);
|
||||
|
||||
foreach (var currencyCode in currencyCodes)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(currencyPairs))
|
||||
{
|
||||
currencyPairs += ",";
|
||||
}
|
||||
currencyPairs += $"{defaultCrypto}_{currencyCode}";
|
||||
}
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(currencyPairs))
|
||||
{
|
||||
var result = Json(new BitpayErrorsModel() { Error = "You need to specify currencyPairs (eg. BTC_USD,LTC_CAD)" });
|
||||
result.StatusCode = 400;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var rules = store.GetStoreBlob().GetRateRules(_NetworkProvider);
|
||||
|
||||
HashSet<CurrencyPair> pairs = new HashSet<CurrencyPair>();
|
||||
foreach(var currency in currencyPairs.Split(','))
|
||||
foreach (var currency in currencyPairs.Split(','))
|
||||
{
|
||||
if(!CurrencyPair.TryParse(currency, out var pair))
|
||||
if (!CurrencyPair.TryParse(currency, out var pair))
|
||||
{
|
||||
var result = Json(new BitpayErrorsModel() { Error = $"Currency pair {currency} uncorrectly formatted" });
|
||||
result.StatusCode = 400;
|
||||
@ -81,6 +160,7 @@ namespace BTCPayServer.Controllers
|
||||
var fetching = _RateProviderFactory.FetchRates(pairs, rules);
|
||||
await Task.WhenAll(fetching.Select(f => f.Value).ToArray());
|
||||
return Json(pairs
|
||||
.AsParallel()
|
||||
.Select(r => (Pair: r, Value: fetching[r].GetAwaiter().GetResult().BidAsk?.Bid))
|
||||
.Where(r => r.Value.HasValue)
|
||||
.Select(r =>
|
||||
|
@ -317,7 +317,7 @@ namespace BTCPayServer.Controllers
|
||||
{
|
||||
var storeBlob = StoreData.GetStoreBlob();
|
||||
var vm = new CheckoutExperienceViewModel();
|
||||
vm.SetCryptoCurrencies(_ExplorerProvider, StoreData.GetDefaultCrypto());
|
||||
vm.SetCryptoCurrencies(_ExplorerProvider, StoreData.GetDefaultCrypto(_NetworkProvider));
|
||||
vm.SetLanguages(_LangService, storeBlob.DefaultLang);
|
||||
vm.LightningMaxValue = storeBlob.LightningMaxValue?.ToString() ?? "";
|
||||
vm.OnChainMinValue = storeBlob.OnChainMinValue?.ToString() ?? "";
|
||||
@ -352,7 +352,7 @@ namespace BTCPayServer.Controllers
|
||||
}
|
||||
bool needUpdate = false;
|
||||
var blob = StoreData.GetStoreBlob();
|
||||
if (StoreData.GetDefaultCrypto() != model.DefaultCryptoCurrency)
|
||||
if (StoreData.GetDefaultCrypto(_NetworkProvider) != model.DefaultCryptoCurrency)
|
||||
{
|
||||
needUpdate = true;
|
||||
StoreData.SetDefaultCrypto(model.DefaultCryptoCurrency);
|
||||
|
@ -197,9 +197,9 @@ namespace BTCPayServer.Data
|
||||
public IEnumerable<APIKeyData> APIKeys { get; set; }
|
||||
|
||||
#pragma warning disable CS0618
|
||||
public string GetDefaultCrypto()
|
||||
public string GetDefaultCrypto(BTCPayNetworkProvider networkProvider = null)
|
||||
{
|
||||
return DefaultCrypto ?? "BTC";
|
||||
return DefaultCrypto ?? (networkProvider == null? "BTC" : GetSupportedPaymentMethods(networkProvider).First().PaymentId.CryptoCode);
|
||||
}
|
||||
public void SetDefaultCrypto(string defaultCryptoCurrency)
|
||||
{
|
||||
|
@ -32,7 +32,7 @@ namespace BTCPayServer
|
||||
|
||||
public BTCPayNetwork Network { get { return this._Network; } }
|
||||
|
||||
public DerivationStrategyBase DerivationStrategyBase { get { return this._DerivationStrategy; } }
|
||||
public DerivationStrategyBase DerivationStrategyBase => this._DerivationStrategy;
|
||||
|
||||
public PaymentMethodId PaymentId => new PaymentMethodId(Network.CryptoCode, PaymentTypes.BTCLike);
|
||||
|
||||
|
@ -202,7 +202,8 @@ namespace BTCPayServer.HostedServices
|
||||
PaymentSubtotals = dto.PaymentSubtotals,
|
||||
PaymentTotals = dto.PaymentTotals,
|
||||
AmountPaid = dto.AmountPaid,
|
||||
ExchangeRates = dto.ExchangeRates
|
||||
ExchangeRates = dto.ExchangeRates,
|
||||
|
||||
};
|
||||
|
||||
// We keep backward compatibility with bitpay by passing BTC info to the notification
|
||||
|
@ -100,7 +100,7 @@ namespace BTCPayServer.Hosting
|
||||
(isJson || httpContext.Request.Query.ContainsKey("token")))
|
||||
return true;
|
||||
|
||||
if (path.Equals("/rates", StringComparison.OrdinalIgnoreCase) &&
|
||||
if (path.StartsWith("/rates", StringComparison.OrdinalIgnoreCase) &&
|
||||
httpContext.Request.Method == "GET")
|
||||
return true;
|
||||
|
||||
|
Reference in New Issue
Block a user