btcpayserver/BTCPayServer/Data/StoreDataExtensions.cs

165 lines
7.2 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using BTCPayServer.Payments;
using BTCPayServer.Security;
using BTCPayServer.Services.Rates;
using NBitcoin;
using NBXplorer;
2019-12-24 08:20:44 +01:00
using NBXplorer.DerivationStrategy;
using Newtonsoft.Json.Linq;
namespace BTCPayServer.Data
{
public static class StoreDataExtensions
{
#pragma warning disable CS0618
public static PaymentMethodId GetDefaultPaymentId(this StoreData storeData, BTCPayNetworkProvider networks)
{
PaymentMethodId[] paymentMethodIds = storeData.GetEnabledPaymentIds(networks);
var defaultPaymentId = string.IsNullOrEmpty(storeData.DefaultCrypto) ? null : PaymentMethodId.Parse(storeData.DefaultCrypto);
var chosen = paymentMethodIds.FirstOrDefault(f => f == defaultPaymentId) ??
paymentMethodIds.FirstOrDefault(f => f.CryptoCode == defaultPaymentId?.CryptoCode) ??
paymentMethodIds.FirstOrDefault();
return chosen;
}
public static PaymentMethodId[] GetEnabledPaymentIds(this StoreData storeData, BTCPayNetworkProvider networks)
{
var excludeFilter = storeData.GetStoreBlob().GetExcludedPaymentMethods();
var paymentMethodIds = storeData.GetSupportedPaymentMethods(networks).Select(p => p.PaymentId)
.Where(a => !excludeFilter.Match(a))
.OrderByDescending(a => a.CryptoCode == "BTC")
.ThenBy(a => a.CryptoCode)
.ThenBy(a => a.PaymentType == PaymentTypes.LightningLike ? 1 : 0)
.ToArray();
return paymentMethodIds;
}
public static void SetDefaultPaymentId(this StoreData storeData, PaymentMethodId defaultPaymentId)
{
storeData.DefaultCrypto = defaultPaymentId.ToString();
}
#pragma warning restore CS0618
2019-11-15 10:53:20 +01:00
public static StoreBlob GetStoreBlob(this StoreData storeData)
{
2019-11-15 10:53:20 +01:00
var result = storeData.StoreBlob == null ? new StoreBlob() : new Serializer(null).ToObject<StoreBlob>(Encoding.UTF8.GetString(storeData.StoreBlob));
if (result.PreferredExchange == null)
result.PreferredExchange = CoinGeckoRateProvider.CoinGeckoName;
return result;
}
public static bool SetStoreBlob(this StoreData storeData, StoreBlob storeBlob)
{
2019-11-15 10:53:20 +01:00
var original = new Serializer(null).ToString(storeData.GetStoreBlob());
var newBlob = new Serializer(null).ToString(storeBlob);
if (original == newBlob)
return false;
storeData.StoreBlob = Encoding.UTF8.GetBytes(newBlob);
return true;
}
public static IEnumerable<ISupportedPaymentMethod> GetSupportedPaymentMethods(this StoreData storeData, BTCPayNetworkProvider networks)
{
if (storeData == null)
throw new ArgumentNullException(nameof(storeData));
networks = networks.UnfilteredNetworks;
#pragma warning disable CS0618
bool btcReturned = false;
// Legacy stuff which should go away
if (!string.IsNullOrEmpty(storeData.DerivationStrategy))
{
btcReturned = true;
yield return DerivationSchemeSettings.Parse(storeData.DerivationStrategy, networks.BTC);
}
if (!string.IsNullOrEmpty(storeData.DerivationStrategies))
{
JObject strategies = JObject.Parse(storeData.DerivationStrategies);
foreach (var strat in strategies.Properties())
{
var paymentMethodId = PaymentMethodId.Parse(strat.Name);
var network = networks.GetNetwork<BTCPayNetworkBase>(paymentMethodId.CryptoCode);
if (network != null)
{
if (network == networks.BTC && paymentMethodId.PaymentType == PaymentTypes.BTCLike && btcReturned)
continue;
if (strat.Value.Type == JTokenType.Null)
continue;
yield return
paymentMethodId.PaymentType.DeserializeSupportedPaymentMethod(network, strat.Value);
}
}
}
#pragma warning restore CS0618
}
public static void SetSupportedPaymentMethod(this StoreData storeData, ISupportedPaymentMethod supportedPaymentMethod)
{
storeData.SetSupportedPaymentMethod(null, supportedPaymentMethod);
}
/// <summary>
/// Set or remove a new supported payment method for the store
/// </summary>
/// <param name="paymentMethodId">The paymentMethodId</param>
/// <param name="supportedPaymentMethod">The payment method, or null to remove</param>
public static void SetSupportedPaymentMethod(this StoreData storeData, PaymentMethodId paymentMethodId, ISupportedPaymentMethod supportedPaymentMethod)
{
if (supportedPaymentMethod != null && paymentMethodId != null && paymentMethodId != supportedPaymentMethod.PaymentId)
{
throw new InvalidOperationException("Incoherent arguments, this should never happen");
}
if (supportedPaymentMethod == null && paymentMethodId == null)
throw new ArgumentException($"{nameof(supportedPaymentMethod)} or {nameof(paymentMethodId)} should be specified");
if (supportedPaymentMethod != null && paymentMethodId == null)
{
paymentMethodId = supportedPaymentMethod.PaymentId;
}
#pragma warning disable CS0618
JObject strategies = string.IsNullOrEmpty(storeData.DerivationStrategies) ? new JObject() : JObject.Parse(storeData.DerivationStrategies);
bool existing = false;
foreach (var strat in strategies.Properties().ToList())
{
var stratId = PaymentMethodId.Parse(strat.Name);
if (stratId.IsBTCOnChain)
{
// Legacy stuff which should go away
storeData.DerivationStrategy = null;
}
if (stratId == paymentMethodId)
{
if (supportedPaymentMethod == null)
{
strat.Remove();
}
else
{
strat.Value = PaymentMethodExtensions.Serialize(supportedPaymentMethod);
}
existing = true;
break;
}
}
if (!existing && supportedPaymentMethod == null && paymentMethodId.IsBTCOnChain)
{
storeData.DerivationStrategy = null;
}
else if (!existing && supportedPaymentMethod != null)
strategies.Add(new JProperty(supportedPaymentMethod.PaymentId.ToString(), PaymentMethodExtensions.Serialize(supportedPaymentMethod)));
storeData.DerivationStrategies = strategies.ToString();
#pragma warning restore CS0618
}
}
}