mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 18:11:36 +01:00
122 lines
4.4 KiB
C#
122 lines
4.4 KiB
C#
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using BTCPayServer.Models;
|
|
using BTCPayServer.Payments.Changelly;
|
|
using BTCPayServer.Rating;
|
|
using BTCPayServer.Services.Rates;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using BTCPayServer.Data;
|
|
|
|
namespace BTCPayServer.Controllers
|
|
{
|
|
[Route("[controller]/{storeId}")]
|
|
public class ChangellyController : Controller
|
|
{
|
|
private readonly ChangellyClientProvider _changellyClientProvider;
|
|
private readonly BTCPayNetworkProvider _btcPayNetworkProvider;
|
|
private readonly RateFetcher _RateProviderFactory;
|
|
|
|
public ChangellyController(ChangellyClientProvider changellyClientProvider,
|
|
BTCPayNetworkProvider btcPayNetworkProvider,
|
|
RateFetcher rateProviderFactory)
|
|
{
|
|
_RateProviderFactory = rateProviderFactory ?? throw new ArgumentNullException(nameof(rateProviderFactory));
|
|
|
|
_changellyClientProvider = changellyClientProvider;
|
|
_btcPayNetworkProvider = btcPayNetworkProvider;
|
|
}
|
|
|
|
[HttpGet]
|
|
[Route("currencies")]
|
|
public async Task<IActionResult> GetCurrencyList(string storeId)
|
|
{
|
|
try
|
|
{
|
|
|
|
var client = await TryGetChangellyClient(storeId);
|
|
|
|
return Ok(await client.GetCurrenciesFull());
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
return BadRequest(new BitpayErrorModel()
|
|
{
|
|
Error = e.Message
|
|
});
|
|
}
|
|
}
|
|
|
|
[HttpGet]
|
|
[Route("calculate")]
|
|
public async Task<IActionResult> CalculateAmount(string storeId, string fromCurrency, string toCurrency,
|
|
decimal toCurrencyAmount, CancellationToken cancellationToken)
|
|
{
|
|
try
|
|
{
|
|
var client = await TryGetChangellyClient(storeId);
|
|
|
|
if (fromCurrency.Equals("usd", StringComparison.InvariantCultureIgnoreCase)
|
|
|| fromCurrency.Equals("eur", StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
return await HandleCalculateFiatAmount(fromCurrency, toCurrency, toCurrencyAmount, cancellationToken);
|
|
}
|
|
|
|
var callCounter = 0;
|
|
var baseRate = await client.GetExchangeAmount(fromCurrency, toCurrency, 1);
|
|
var currentAmount = ChangellyCalculationHelper.ComputeBaseAmount(baseRate, toCurrencyAmount);
|
|
while (true)
|
|
{
|
|
if (callCounter > 10)
|
|
{
|
|
BadRequest();
|
|
}
|
|
|
|
var computedAmount = await client.GetExchangeAmount(fromCurrency, toCurrency, currentAmount);
|
|
callCounter++;
|
|
if (computedAmount < toCurrencyAmount)
|
|
{
|
|
currentAmount =
|
|
ChangellyCalculationHelper.ComputeCorrectAmount(currentAmount, computedAmount,
|
|
toCurrencyAmount);
|
|
}
|
|
else
|
|
{
|
|
return Ok(currentAmount);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
return BadRequest(new BitpayErrorModel()
|
|
{
|
|
Error = e.Message
|
|
});
|
|
}
|
|
}
|
|
|
|
private async Task<Changelly> TryGetChangellyClient(string storeId)
|
|
{
|
|
var store = IsTest? null: HttpContext.GetStoreData();
|
|
storeId = storeId ?? store?.Id;
|
|
|
|
return await _changellyClientProvider.TryGetChangellyClient(storeId, store);
|
|
}
|
|
|
|
private async Task<IActionResult> HandleCalculateFiatAmount(string fromCurrency, string toCurrency,
|
|
decimal toCurrencyAmount, CancellationToken cancellationToken)
|
|
{
|
|
var store = HttpContext.GetStoreData();
|
|
var rules = store.GetStoreBlob().GetRateRules(_btcPayNetworkProvider);
|
|
var rate = await _RateProviderFactory.FetchRate(new CurrencyPair(toCurrency, fromCurrency), rules, cancellationToken);
|
|
if (rate.BidAsk == null) return BadRequest();
|
|
var flatRate = rate.BidAsk.Center;
|
|
return Ok(flatRate * toCurrencyAmount);
|
|
}
|
|
|
|
public bool IsTest { get; set; } = false;
|
|
}
|
|
|
|
|
|
}
|