Fix "Do not propose on chain payment if the value of the invoice is below..." and take care of the GAP edge case

This commit is contained in:
HugoDoyon 2019-07-31 17:29:55 -04:00
parent f8427eb801
commit 428c7c5444

View File

@ -73,37 +73,62 @@ namespace BTCPayServer.Payments.Bitcoin
public override async Task<string> IsPaymentMethodAllowedBasedOnInvoiceAmount(StoreBlob storeBlob, public override async Task<string> IsPaymentMethodAllowedBasedOnInvoiceAmount(StoreBlob storeBlob,
Dictionary<CurrencyPair, Task<RateResult>> rate, Money amount, PaymentMethodId paymentMethodId) Dictionary<CurrencyPair, Task<RateResult>> rate, Money amount, PaymentMethodId paymentMethodId)
{ {
Func<Money, Money, bool> compare = null; Func<Money, Money, bool> compare = null;
CurrencyValue limitValue = null; CurrencyValue limitValue = null;
string errorMessage = null; string errorMessage = null;
if (paymentMethodId.PaymentType == PaymentTypes.LightningLike &&
storeBlob.LightningMaxValue != null) if (paymentMethodId.PaymentType == PaymentTypes.BTCLike)
{ {
compare = (a, b) => a > b; if (storeBlob.LightningMaxValue == null &&
limitValue = storeBlob.LightningMaxValue; storeBlob.OnChainMinValue != null)
errorMessage = "The amount of the invoice is too high to be paid with lightning"; {
} compare = (value, limit) => value < limit;
else if (paymentMethodId.PaymentType == PaymentTypes.BTCLike && limitValue = storeBlob.OnChainMinValue;
storeBlob.OnChainMinValue != null) errorMessage = "The amount of the invoice is too low to be paid on chain";
{ }
compare = (a, b) => a < b; else if (storeBlob.LightningMaxValue != null &&
limitValue = storeBlob.OnChainMinValue; storeBlob.OnChainMinValue != null)
errorMessage = "The amount of the invoice is too low to be paid on chain"; {
if (storeBlob.LightningMaxValue.Currency == storeBlob.OnChainMinValue.Currency &&
storeBlob.LightningMaxValue.Value <= storeBlob.OnChainMinValue.Value)
{
//Case where both fields are set but OnChainMinValue is greater
// --> then use LightningMaxValue as limit
compare = (value, limit) => value < limit;
limitValue = storeBlob.LightningMaxValue;
errorMessage = "The amount of the invoice is too low to be paid on chain";
}
else if (storeBlob.LightningMaxValue.Currency == storeBlob.OnChainMinValue.Currency &&
storeBlob.LightningMaxValue.Value > storeBlob.OnChainMinValue.Value)
{
//Case where both fields are set but LightningMaxValue is greater
// --> then use OnChainMinValue as limit
// (Otherwise a gap of price value with no payment method is possible)
compare = (value, limit) => value < limit;
limitValue = storeBlob.OnChainMinValue;
errorMessage = "The amount of the invoice is too low to be paid on chain";
}
}
} }
if (compare != null) if (compare != null)
{ {
var limitValueRate = await rate[new CurrencyPair(paymentMethodId.CryptoCode, storeBlob.OnChainMinValue.Currency)]; var currentRateToCrypto = await rate[new CurrencyPair(paymentMethodId.CryptoCode, limitValue.Currency)];
if (limitValueRate.BidAsk != null)
if (currentRateToCrypto.BidAsk != null)
{ {
var limitValueCrypto = Money.Coins(limitValue.Value / limitValueRate.BidAsk.Bid); var limitValueCrypto = Money.Coins(limitValue.Value / currentRateToCrypto.BidAsk.Bid);
if (compare(amount, limitValueCrypto)) if (compare(amount, limitValueCrypto))
{ {
return errorMessage; return errorMessage;
} }
} }
} }
return string.Empty; return string.Empty;
} }
public override IEnumerable<PaymentMethodId> GetSupportedPaymentMethods() public override IEnumerable<PaymentMethodId> GetSupportedPaymentMethods()