mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 01:43:50 +01:00
Add Label and accountKeyPath to the on chain payment methods (#2166)
This commit is contained in:
parent
f64f86fbb6
commit
623347bc48
@ -1,3 +1,6 @@
|
||||
using NBitcoin;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Client.Models
|
||||
{
|
||||
public class OnChainPaymentMethodData
|
||||
@ -22,6 +25,11 @@ namespace BTCPayServer.Client.Models
|
||||
/// </summary>
|
||||
public string DerivationScheme { get; set; }
|
||||
|
||||
public string Label { get; set; }
|
||||
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.KeyPathJsonConverter))]
|
||||
public RootedKeyPath AccountKeyPath { get; set; }
|
||||
|
||||
public OnChainPaymentMethodData()
|
||||
{
|
||||
}
|
||||
|
@ -1244,9 +1244,14 @@ namespace BTCPayServer.Tests
|
||||
new OnChainPaymentMethodData() {Default = true, Enabled = true, DerivationScheme = xpub});
|
||||
|
||||
Assert.Equal(xpub,method.DerivationScheme);
|
||||
|
||||
|
||||
method = await client.UpdateStoreOnChainPaymentMethod(store.Id, "BTC",
|
||||
new OnChainPaymentMethodData() { Default = true, Enabled = true, DerivationScheme = xpub, Label = "lol", AccountKeyPath = RootedKeyPath.Parse("01020304/1/2/3") });
|
||||
|
||||
method = await client.GetStoreOnChainPaymentMethod(store.Id, "BTC");
|
||||
|
||||
|
||||
Assert.Equal("lol", method.Label);
|
||||
Assert.Equal(RootedKeyPath.Parse("01020304/1/2/3"), method.AccountKeyPath);
|
||||
Assert.Equal(xpub,method.DerivationScheme);
|
||||
|
||||
|
||||
|
@ -10,6 +10,7 @@ using BTCPayServer.Services.Stores;
|
||||
using BTCPayServer.Services.Wallets;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NBitcoin;
|
||||
using NBXplorer.DerivationStrategy;
|
||||
using StoreData = BTCPayServer.Data.StoreData;
|
||||
|
||||
@ -203,6 +204,18 @@ namespace BTCPayServer.Controllers.GreenField
|
||||
var strategy = DerivationSchemeSettings.Parse(paymentMethodData.DerivationScheme, network);
|
||||
if (strategy != null)
|
||||
await wallet.TrackAsync(strategy.AccountDerivation);
|
||||
strategy.Label = paymentMethodData.Label;
|
||||
var signing = strategy.GetSigningAccountKeySettings();
|
||||
if (paymentMethodData.AccountKeyPath is RootedKeyPath r)
|
||||
{
|
||||
signing.AccountKeyPath = r.KeyPath;
|
||||
signing.RootFingerprint = r.MasterFingerprint;
|
||||
}
|
||||
else
|
||||
{
|
||||
signing.AccountKeyPath = null;
|
||||
signing.RootFingerprint = null;
|
||||
}
|
||||
store.SetSupportedPaymentMethod(id, strategy);
|
||||
storeBlob.SetExcluded(id, !paymentMethodData.Enabled);
|
||||
store.SetStoreBlob(storeBlob);
|
||||
@ -240,7 +253,11 @@ namespace BTCPayServer.Controllers.GreenField
|
||||
? null
|
||||
: new OnChainPaymentMethodData(paymentMethod.PaymentId.CryptoCode,
|
||||
paymentMethod.AccountDerivation.ToString(), !excluded,
|
||||
defaultPaymentMethod == paymentMethod.PaymentId);
|
||||
defaultPaymentMethod == paymentMethod.PaymentId)
|
||||
{
|
||||
Label = paymentMethod.Label,
|
||||
AccountKeyPath = paymentMethod.GetSigningAccountKeySettings().GetRootedKeyPath()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
@ -339,8 +340,16 @@ namespace BTCPayServer.Hosting
|
||||
logBuilder.AddProvider(new Serilog.Extensions.Logging.SerilogLoggerProvider(Log.Logger));
|
||||
}
|
||||
});
|
||||
|
||||
services.AddSingleton<IObjectModelValidator, SkippableObjectValidatorProvider>();
|
||||
services.SkipModelValidation<RootedKeyPath>();
|
||||
return services;
|
||||
}
|
||||
|
||||
public static void SkipModelValidation<T>(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<SkippableObjectValidatorProvider.ISkipValidation, SkippableObjectValidatorProvider.SkipValidationType<T>>();
|
||||
}
|
||||
private const long MAX_DEBUG_LOG_FILE_SIZE = 2000000; // If debug log is in use roll it every N MB.
|
||||
private static void AddBtcPayServerAuthenticationSchemes(this IServiceCollection services)
|
||||
{
|
||||
|
78
BTCPayServer/Hosting/SkippableObjectValidatorProvider.cs
Normal file
78
BTCPayServer/Hosting/SkippableObjectValidatorProvider.cs
Normal file
@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Hosting
|
||||
{
|
||||
public class SkippableObjectValidatorProvider : ObjectModelValidator
|
||||
{
|
||||
public interface ISkipValidation
|
||||
{
|
||||
bool SkipValidation(object obj);
|
||||
}
|
||||
public class SkipValidationType<T> : ISkipValidation
|
||||
{
|
||||
public bool SkipValidation(object obj)
|
||||
{
|
||||
return obj is T;
|
||||
}
|
||||
}
|
||||
public SkippableObjectValidatorProvider(
|
||||
IModelMetadataProvider modelMetadataProvider,
|
||||
IEnumerable<ISkipValidation> skipValidations,
|
||||
IOptions<MvcOptions> mvcOptions)
|
||||
: base(modelMetadataProvider, mvcOptions.Value.ModelValidatorProviders)
|
||||
{
|
||||
_mvcOptions = mvcOptions.Value;
|
||||
SkipValidations = skipValidations.ToList();
|
||||
}
|
||||
|
||||
class OverrideValidationVisitor : ValidationVisitor
|
||||
{
|
||||
public OverrideValidationVisitor(IEnumerable<ISkipValidation> skipValidations, ActionContext actionContext, IModelValidatorProvider validatorProvider, ValidatorCache validatorCache, IModelMetadataProvider metadataProvider, ValidationStateDictionary validationState) : base(actionContext, validatorProvider, validatorCache, metadataProvider, validationState)
|
||||
{
|
||||
SkipValidations = skipValidations;
|
||||
}
|
||||
|
||||
public IEnumerable<ISkipValidation> SkipValidations { get; }
|
||||
|
||||
protected override bool VisitComplexType(IValidationStrategy defaultStrategy)
|
||||
{
|
||||
if (SkipValidations.Any(v => v.SkipValidation(Model)))
|
||||
return true;
|
||||
return base.VisitComplexType(defaultStrategy);
|
||||
}
|
||||
}
|
||||
|
||||
public MvcOptions _mvcOptions { get; }
|
||||
IEnumerable<ISkipValidation> SkipValidations { get; }
|
||||
|
||||
public override ValidationVisitor GetValidationVisitor(
|
||||
ActionContext actionContext,
|
||||
IModelValidatorProvider validatorProvider,
|
||||
ValidatorCache validatorCache,
|
||||
IModelMetadataProvider metadataProvider,
|
||||
ValidationStateDictionary validationState)
|
||||
{
|
||||
var visitor = new OverrideValidationVisitor(
|
||||
SkipValidations,
|
||||
actionContext,
|
||||
validatorProvider,
|
||||
validatorCache,
|
||||
metadataProvider,
|
||||
validationState)
|
||||
{
|
||||
MaxValidationDepth = _mvcOptions.MaxValidationDepth,
|
||||
ValidateComplexTypesIfChildValidationFails = _mvcOptions.ValidateComplexTypesIfChildValidationFails,
|
||||
};
|
||||
|
||||
return visitor;
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using NBitcoin;
|
||||
|
||||
namespace BTCPayServer.Hosting
|
||||
{
|
||||
@ -75,7 +76,6 @@ namespace BTCPayServer.Hosting
|
||||
.ConfigureApiBehaviorOptions(options =>
|
||||
{
|
||||
var builtInFactory = options.InvalidModelStateResponseFactory;
|
||||
|
||||
options.InvalidModelStateResponseFactory = context =>
|
||||
{
|
||||
context.HttpContext.Response.StatusCode = (int)HttpStatusCode.UnprocessableEntity;
|
||||
|
@ -403,7 +403,17 @@
|
||||
},
|
||||
"derivationScheme": {
|
||||
"type": "string",
|
||||
"description": "The derivation scheme"
|
||||
"description": "The derivation scheme",
|
||||
"example": "xpub..."
|
||||
},
|
||||
"label": {
|
||||
"type": "string",
|
||||
"description": "A label that will be shown in the UI"
|
||||
},
|
||||
"accountKeyPath": {
|
||||
"type": "string",
|
||||
"description": "The wallet fingerprint followed by the keypath to derive the account key used for signing operation or creating PSBTs",
|
||||
"example": "abcd82a1/84'/0'/0'"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user