2021-10-18 09:56:47 +02:00
|
|
|
#nullable enable
|
2020-06-29 04:44:35 +02:00
|
|
|
using System;
|
2019-08-29 17:24:42 +02:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Text;
|
|
|
|
using BTCPayServer.Payments;
|
|
|
|
using BTCPayServer.Services.Rates;
|
2021-11-10 10:50:39 +01:00
|
|
|
using NBitcoin;
|
2019-08-29 17:24:42 +02:00
|
|
|
using NBXplorer;
|
|
|
|
using Newtonsoft.Json.Linq;
|
2021-11-10 10:50:39 +01:00
|
|
|
using BTCPayServer.Payments.Lightning;
|
2019-08-29 17:24:42 +02:00
|
|
|
|
|
|
|
namespace BTCPayServer.Data
|
|
|
|
{
|
|
|
|
public static class StoreDataExtensions
|
|
|
|
{
|
|
|
|
#pragma warning disable CS0618
|
2021-10-18 09:56:47 +02:00
|
|
|
public static PaymentMethodId? GetDefaultPaymentId(this StoreData storeData)
|
2019-08-29 17:24:42 +02:00
|
|
|
{
|
2020-08-09 14:43:13 +02:00
|
|
|
PaymentMethodId.TryParse(storeData.DefaultCrypto, out var defaultPaymentId);
|
2021-10-18 09:56:47 +02:00
|
|
|
return defaultPaymentId;
|
2019-08-29 17:24:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public static PaymentMethodId[] GetEnabledPaymentIds(this StoreData storeData, BTCPayNetworkProvider networks)
|
2021-11-04 08:21:01 +01:00
|
|
|
{
|
|
|
|
return GetEnabledPaymentMethods(storeData, networks).Select(method => method.PaymentId).ToArray();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static ISupportedPaymentMethod[] GetEnabledPaymentMethods(this StoreData storeData, BTCPayNetworkProvider networks)
|
2019-08-29 17:24:42 +02:00
|
|
|
{
|
|
|
|
var excludeFilter = storeData.GetStoreBlob().GetExcludedPaymentMethods();
|
2021-09-24 07:16:25 +02:00
|
|
|
var paymentMethodIds = storeData.GetSupportedPaymentMethods(networks)
|
2021-11-04 08:21:01 +01:00
|
|
|
.Where(a => !excludeFilter.Match(a.PaymentId))
|
|
|
|
.OrderByDescending(a => a.PaymentId.CryptoCode == "BTC")
|
|
|
|
.ThenBy(a => a.PaymentId.CryptoCode)
|
|
|
|
.ThenBy(a => a.PaymentId.PaymentType == PaymentTypes.LightningLike ? 1 : 0)
|
|
|
|
.ToArray();
|
2019-08-29 17:24:42 +02:00
|
|
|
return paymentMethodIds;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void SetDefaultPaymentId(this StoreData storeData, PaymentMethodId defaultPaymentId)
|
|
|
|
{
|
2020-12-29 10:33:44 +01:00
|
|
|
storeData.DefaultCrypto = defaultPaymentId?.ToString();
|
2019-08-29 17:24:42 +02:00
|
|
|
}
|
|
|
|
#pragma warning restore CS0618
|
|
|
|
|
2020-06-28 10:55:27 +02:00
|
|
|
|
2019-08-29 17:24:42 +02: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));
|
2019-08-29 17:24:42 +02:00
|
|
|
if (result.PreferredExchange == null)
|
2020-01-10 14:50:39 +01:00
|
|
|
result.PreferredExchange = CoinGeckoRateProvider.CoinGeckoName;
|
2020-10-16 06:30:46 +02:00
|
|
|
|
|
|
|
if (result.Hints == null)
|
|
|
|
result.Hints = new StoreBlob.StoreHints();
|
2019-08-29 17:24:42 +02:00
|
|
|
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);
|
2019-08-29 17:24:42 +02:00
|
|
|
if (original == newBlob)
|
|
|
|
return false;
|
|
|
|
storeData.StoreBlob = Encoding.UTF8.GetBytes(newBlob);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static IEnumerable<ISupportedPaymentMethod> GetSupportedPaymentMethods(this StoreData storeData, BTCPayNetworkProvider networks)
|
|
|
|
{
|
2020-03-23 07:46:54 +01:00
|
|
|
if (storeData == null)
|
|
|
|
throw new ArgumentNullException(nameof(storeData));
|
2019-08-29 17:24:42 +02:00
|
|
|
#pragma warning disable CS0618
|
|
|
|
bool btcReturned = false;
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(storeData.DerivationStrategies))
|
|
|
|
{
|
|
|
|
JObject strategies = JObject.Parse(storeData.DerivationStrategies);
|
|
|
|
foreach (var strat in strategies.Properties())
|
|
|
|
{
|
2020-08-09 14:43:13 +02:00
|
|
|
if (!PaymentMethodId.TryParse(strat.Name, out var paymentMethodId))
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2019-09-21 16:39:44 +02:00
|
|
|
var network = networks.GetNetwork<BTCPayNetworkBase>(paymentMethodId.CryptoCode);
|
2019-08-29 17:24:42 +02:00
|
|
|
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>
|
2021-10-18 09:56:47 +02:00
|
|
|
public static void SetSupportedPaymentMethod(this StoreData storeData, PaymentMethodId? paymentMethodId, ISupportedPaymentMethod? supportedPaymentMethod)
|
2019-08-29 17:24:42 +02:00
|
|
|
{
|
|
|
|
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())
|
|
|
|
{
|
2021-03-10 11:51:51 +01:00
|
|
|
if (!PaymentMethodId.TryParse(strat.Name, out var stratId))
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2019-08-29 17:24:42 +02:00
|
|
|
if (stratId == paymentMethodId)
|
|
|
|
{
|
|
|
|
if (supportedPaymentMethod == null)
|
|
|
|
{
|
|
|
|
strat.Remove();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
strat.Value = PaymentMethodExtensions.Serialize(supportedPaymentMethod);
|
|
|
|
}
|
|
|
|
existing = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2021-03-02 03:11:58 +01:00
|
|
|
if (!existing && supportedPaymentMethod != null)
|
2019-08-29 17:24:42 +02:00
|
|
|
strategies.Add(new JProperty(supportedPaymentMethod.PaymentId.ToString(), PaymentMethodExtensions.Serialize(supportedPaymentMethod)));
|
|
|
|
storeData.DerivationStrategies = strategies.ToString();
|
|
|
|
#pragma warning restore CS0618
|
|
|
|
}
|
2021-11-10 10:50:39 +01:00
|
|
|
|
|
|
|
public static bool IsLightningEnabled(this StoreData storeData, BTCPayNetworkProvider networks)
|
|
|
|
{
|
|
|
|
var paymentMethods = storeData.GetSupportedPaymentMethods(networks);
|
|
|
|
var lightningByCryptoCode = paymentMethods
|
|
|
|
.OfType<LightningSupportedPaymentMethod>()
|
|
|
|
.Where(method => method.PaymentId.PaymentType == LightningPaymentType.Instance)
|
|
|
|
.ToDictionary(c => c.CryptoCode.ToUpperInvariant());
|
|
|
|
var excludeFilters = storeData.GetStoreBlob().GetExcludedPaymentMethods();
|
|
|
|
var isLightningEnabled = false;
|
|
|
|
foreach (var paymentMethod in paymentMethods)
|
|
|
|
{
|
|
|
|
var paymentMethodId = paymentMethod.PaymentId;
|
|
|
|
switch (paymentMethodId.PaymentType)
|
|
|
|
{
|
|
|
|
// LNURLPayPaymentType is a subclass of LightningPaymentType, skip it
|
|
|
|
case LNURLPayPaymentType lnurlPayPaymentType:
|
|
|
|
break;
|
|
|
|
case LightningPaymentType _:
|
|
|
|
var lightning = lightningByCryptoCode.TryGet(paymentMethodId.CryptoCode);
|
|
|
|
isLightningEnabled = !excludeFilters.Match(paymentMethodId) && lightning != null;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return isLightningEnabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static bool IsLNUrlEnabled(this StoreData storeData, BTCPayNetworkProvider networks)
|
|
|
|
{
|
|
|
|
var paymentMethods = storeData.GetSupportedPaymentMethods(networks);
|
|
|
|
var excludeFilters = storeData.GetStoreBlob().GetExcludedPaymentMethods();
|
|
|
|
var isLNUrlEnabled = false;
|
|
|
|
foreach (var paymentMethod in paymentMethods)
|
|
|
|
{
|
|
|
|
var paymentMethodId = paymentMethod.PaymentId;
|
|
|
|
if (paymentMethodId.PaymentType is LNURLPayPaymentType)
|
|
|
|
{
|
|
|
|
isLNUrlEnabled = !excludeFilters.Match(paymentMethodId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return isLNUrlEnabled;
|
|
|
|
}
|
2019-08-29 17:24:42 +02:00
|
|
|
}
|
|
|
|
}
|