btcpayserver/BTCPayServer/Controllers/RateController.cs

210 lines
7.6 KiB
C#
Raw Normal View History

2017-09-13 08:47:34 +02:00
using BTCPayServer.Models;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using BTCPayServer.Filters;
using BTCPayServer.Services.Rates;
using BTCPayServer.Services.Stores;
2018-05-02 20:32:42 +02:00
using BTCPayServer.Rating;
using Newtonsoft.Json;
2017-09-13 08:47:34 +02:00
namespace BTCPayServer.Controllers
{
public class RateController : Controller
{
2018-05-02 20:32:42 +02:00
BTCPayRateProviderFactory _RateProviderFactory;
BTCPayNetworkProvider _NetworkProvider;
CurrencyNameTable _CurrencyNameTable;
StoreRepository _StoreRepo;
public RateController(
2018-05-02 20:32:42 +02:00
BTCPayRateProviderFactory rateProviderFactory,
BTCPayNetworkProvider networkProvider,
StoreRepository storeRepo,
CurrencyNameTable currencyNameTable)
{
_RateProviderFactory = rateProviderFactory ?? throw new ArgumentNullException(nameof(rateProviderFactory));
_NetworkProvider = networkProvider;
_StoreRepo = storeRepo;
_CurrencyNameTable = currencyNameTable ?? throw new ArgumentNullException(nameof(currencyNameTable));
}
2017-09-13 08:47:34 +02:00
2018-05-21 16:49:37 +02:00
[Route("rates/{baseCurrency}")]
[HttpGet]
[BitpayAPIConstraint]
2018-05-28 14:29:23 +02:00
public async Task<IActionResult> GetBaseCurrencyRates(string baseCurrency)
2018-05-21 16:49:37 +02:00
{
2018-05-28 14:55:49 +02:00
var store = this.HttpContext.GetStoreData();
2018-05-21 16:49:37 +02:00
var currencypairs = "";
var supportedMethods = store.GetSupportedPaymentMethods(_NetworkProvider);
2018-05-28 14:55:49 +02:00
var currencyCodes = supportedMethods.Where(method => !string.IsNullOrEmpty(method.CryptoCode))
.Select(method => method.CryptoCode).Distinct();
foreach (var currencyCode in currencyCodes)
2018-05-21 16:49:37 +02:00
{
if (!string.IsNullOrEmpty(currencypairs))
{
currencypairs += ",";
}
2018-05-28 14:55:49 +02:00
currencypairs += baseCurrency + "_ " + currencyCode;
2018-05-21 16:49:37 +02:00
}
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.First()));
}
2018-05-28 10:20:18 +02:00
[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]
2018-05-28 14:55:49 +02:00
public async Task<IActionResult> GetRates(string currencyPairs, string storeId)
2018-01-20 04:11:24 +01:00
{
2018-05-06 15:41:38 +02:00
storeId = storeId ?? this.HttpContext.GetStoreData()?.Id;
2018-05-02 20:32:42 +02:00
var result = await GetRates2(currencyPairs, storeId);
2018-05-06 15:41:38 +02:00
var rates = (result as JsonResult)?.Value as Rate[];
2018-05-02 20:32:42 +02:00
if (rates == null)
2018-01-20 04:11:24 +01:00
return result;
2018-05-06 15:41:38 +02:00
return Json(new DataWrapper<Rate[]>(rates));
2018-01-20 04:11:24 +01:00
}
2018-05-21 16:49:37 +02:00
2018-01-20 04:11:24 +01:00
[Route("api/rates")]
[HttpGet]
2018-05-02 20:32:42 +02:00
public async Task<IActionResult> GetRates2(string currencyPairs, string storeId)
{
2018-05-28 14:55:49 +02:00
if (storeId == null)
2018-05-02 20:32:42 +02:00
{
var result = Json(new BitpayErrorsModel() { Error = "You need to specify storeId (in your store settings) and currencyPairs (eg. BTC_USD,LTC_CAD)" });
result.StatusCode = 400;
return result;
}
2018-05-06 15:41:38 +02:00
var store = this.HttpContext.GetStoreData();
2018-05-28 14:55:49 +02:00
if (store == null || store.Id != storeId)
2018-05-06 15:41:38 +02:00
store = await _StoreRepo.FindStore(storeId);
2018-05-02 20:32:42 +02:00
if (store == null)
{
2018-05-02 20:32:42 +02:00
var result = Json(new BitpayErrorsModel() { Error = "Store not found" });
result.StatusCode = 404;
return result;
}
2018-05-28 14:55:49 +02:00
if (currencyPairs == null)
{
currencyPairs = "";
var supportedMethods = store.GetSupportedPaymentMethods(_NetworkProvider);
var currencyCodes = supportedMethods.Where(method => !string.IsNullOrEmpty(method.CryptoCode))
.Select(method => method.CryptoCode).Distinct();
foreach (var currencyCode in currencyCodes)
{
foreach (var currencyCode2 in currencyCodes)
{
if (currencyCode == currencyCode2)
{
continue;
}
if (!string.IsNullOrEmpty(currencyPairs))
{
currencyPairs += ",";
}
currencyPairs += $"{currencyCode}_{currencyCode2}";
}
}
if (string.IsNullOrEmpty(currencyPairs))
{
var result = Json(new BitpayErrorsModel() { Error = "You need to specify storeId (in your store settings) and currencyPairs (eg. BTC_USD,LTC_CAD)" });
result.StatusCode = 400;
return result;
}
}
2018-05-02 20:32:42 +02:00
var rules = store.GetStoreBlob().GetRateRules(_NetworkProvider);
2018-05-02 20:32:42 +02:00
HashSet<CurrencyPair> pairs = new HashSet<CurrencyPair>();
2018-05-28 14:55:49 +02:00
foreach (var currency in currencyPairs.Split(','))
2018-05-02 20:32:42 +02:00
{
2018-05-28 14:55:49 +02:00
if (!CurrencyPair.TryParse(currency, out var pair))
2018-05-02 20:32:42 +02:00
{
var result = Json(new BitpayErrorsModel() { Error = $"Currency pair {currency} uncorrectly formatted" });
result.StatusCode = 400;
return result;
}
pairs.Add(pair);
}
2018-04-15 14:18:51 +02:00
2018-05-02 20:32:42 +02:00
var fetching = _RateProviderFactory.FetchRates(pairs, rules);
await Task.WhenAll(fetching.Select(f => f.Value).ToArray());
return Json(pairs
.Select(r => (Pair: r, Value: fetching[r].GetAwaiter().GetResult().Value))
.Where(r => r.Value.HasValue)
.Select(r =>
new Rate()
{
2018-05-02 20:32:42 +02:00
CryptoCode = r.Pair.Left,
Code = r.Pair.Right,
2018-05-06 15:41:38 +02:00
CurrencyPair = r.Pair.ToString(),
2018-05-20 16:37:18 +02:00
Name = _CurrencyNameTable.GetCurrencyData(r.Pair.Right, true).Name,
2018-05-02 20:32:42 +02:00
Value = r.Value.Value
2018-01-20 04:11:24 +01:00
}).Where(n => n.Name != null).ToArray());
}
2018-05-02 20:32:42 +02:00
public class Rate
{
[JsonProperty(PropertyName = "name")]
public string Name
{
get;
set;
}
[JsonProperty(PropertyName = "cryptoCode")]
public string CryptoCode
{
get;
set;
}
2018-05-06 15:41:38 +02:00
[JsonProperty(PropertyName = "currencyPair")]
public string CurrencyPair
{
get;
set;
}
2018-05-02 20:32:42 +02:00
[JsonProperty(PropertyName = "code")]
public string Code
{
get;
set;
}
[JsonProperty(PropertyName = "rate")]
public decimal Value
{
get;
set;
}
}
}
2017-09-13 08:47:34 +02:00
}