mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2026-01-26 17:34:27 +01:00
Taproot support for wallets (#2830)
* Support taproot for HotWallet * Support taproot for hardware wallets * Fix NBX version * Undo formatting * Do not show Taproot when not supported * Create taproot wallet from xpub * Bug Fix
This commit is contained in:
@@ -55,6 +55,7 @@ namespace BTCPayServer.Controllers
|
||||
vm.RootKeyPath = network.GetRootKeyPath();
|
||||
vm.CanUseHotWallet = hotWallet;
|
||||
vm.CanUseRPCImport = rpcImport;
|
||||
vm.CanUseTaproot = TaprootSupported(vm.CryptoCode);
|
||||
|
||||
if (vm.Method == null)
|
||||
{
|
||||
@@ -109,6 +110,11 @@ namespace BTCPayServer.Controllers
|
||||
try
|
||||
{
|
||||
strategy = ParseDerivationStrategy(vm.DerivationScheme, network);
|
||||
if(strategy.AccountDerivation is TaprootDerivationStrategy && !TaprootSupported(vm.CryptoCode))
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.DerivationScheme), "Taproot is not supported");
|
||||
return View(vm.ViewName, vm);
|
||||
}
|
||||
strategy.Source = "ManualDerivationScheme";
|
||||
if (!string.IsNullOrEmpty(vm.AccountKey))
|
||||
{
|
||||
@@ -208,6 +214,7 @@ namespace BTCPayServer.Controllers
|
||||
|
||||
vm.CanUseHotWallet = hotWallet;
|
||||
vm.CanUseRPCImport = rpcImport;
|
||||
vm.CanUseTaproot = TaprootSupported(vm.CryptoCode);
|
||||
vm.RootKeyPath = network.GetRootKeyPath();
|
||||
vm.Network = network;
|
||||
|
||||
@@ -262,6 +269,12 @@ namespace BTCPayServer.Controllers
|
||||
CanUseRPCImport = rpcImport
|
||||
};
|
||||
|
||||
if (request.ScriptPubKeyType == ScriptPubKeyType.TaprootBIP86 && !TaprootSupported(cryptoCode) )
|
||||
{
|
||||
ModelState.AddModelError(nameof(request.ScriptPubKeyType), $"Taproot not supported");
|
||||
return View(vm.ViewName, vm);
|
||||
}
|
||||
|
||||
if (isImport && string.IsNullOrEmpty(request.ExistingMnemonic))
|
||||
{
|
||||
ModelState.AddModelError(nameof(request.ExistingMnemonic), "Please provide your existing seed");
|
||||
|
||||
@@ -68,7 +68,8 @@ namespace BTCPayServer.Controllers
|
||||
EventAggregator eventAggregator,
|
||||
AppService appService,
|
||||
WebhookNotificationManager webhookNotificationManager,
|
||||
IDataProtectionProvider dataProtector)
|
||||
IDataProtectionProvider dataProtector,
|
||||
NBXplorerDashboard Dashboard)
|
||||
{
|
||||
_RateFactory = rateFactory;
|
||||
_Repo = repo;
|
||||
@@ -89,6 +90,7 @@ namespace BTCPayServer.Controllers
|
||||
_ServiceProvider = serviceProvider;
|
||||
_BtcpayServerOptions = btcpayServerOptions;
|
||||
_BTCPayEnv = btcpayEnv;
|
||||
_Dashboard = Dashboard;
|
||||
}
|
||||
|
||||
readonly BTCPayServerOptions _BtcpayServerOptions;
|
||||
@@ -107,6 +109,7 @@ namespace BTCPayServer.Controllers
|
||||
private readonly IAuthorizationService _authorizationService;
|
||||
private readonly AppService _appService;
|
||||
private readonly EventAggregator _EventAggregator;
|
||||
private readonly NBXplorerDashboard _Dashboard;
|
||||
|
||||
[TempData]
|
||||
public bool StoreNotConfigured
|
||||
@@ -143,6 +146,13 @@ namespace BTCPayServer.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
public bool TaprootSupported(string crytoCode)
|
||||
{
|
||||
var networkSupport = ((BTCPayNetwork)_NetworkProvider.GetNetwork(crytoCode))?.NBitcoinNetwork?.Consensus?.SupportTaproot is true;
|
||||
var status = _Dashboard.Get(crytoCode).Status;
|
||||
return networkSupport && !(status.NetworkType == ChainName.Mainnet && status.ChainHeight < 709632);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
[Route("{storeId}/users")]
|
||||
@@ -444,7 +454,7 @@ namespace BTCPayServer.Controllers
|
||||
}
|
||||
SetCryptoCurrencies(model, CurrentStore);
|
||||
model.SetLanguages(_LangService, model.DefaultLang);
|
||||
model.PaymentMethodCriteria??= new List<PaymentMethodCriteriaViewModel>();
|
||||
model.PaymentMethodCriteria ??= new List<PaymentMethodCriteriaViewModel>();
|
||||
for (var index = 0; index < model.PaymentMethodCriteria.Count; index++)
|
||||
{
|
||||
var methodCriterion = model.PaymentMethodCriteria[index];
|
||||
@@ -457,7 +467,7 @@ namespace BTCPayServer.Controllers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View(model);
|
||||
@@ -550,7 +560,7 @@ namespace BTCPayServer.Controllers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("{storeId}")]
|
||||
public async Task<IActionResult> UpdateStore()
|
||||
{
|
||||
@@ -575,16 +585,16 @@ namespace BTCPayServer.Controllers
|
||||
vm.PayJoinEnabled = storeBlob.PayJoinEnabled;
|
||||
vm.HintWallet = storeBlob.Hints.Wallet;
|
||||
vm.HintLightning = storeBlob.Hints.Lightning;
|
||||
|
||||
|
||||
(bool canUseHotWallet, _) = await CanUseHotWallet();
|
||||
vm.CanUsePayJoin = canUseHotWallet && store
|
||||
.GetSupportedPaymentMethods(_NetworkProvider)
|
||||
.OfType<DerivationSchemeSettings>()
|
||||
.Any(settings => settings.Network.SupportPayJoin && settings.IsHotWallet);
|
||||
|
||||
|
||||
return View(vm);
|
||||
}
|
||||
|
||||
|
||||
[HttpPost("{storeId}")]
|
||||
public async Task<IActionResult> UpdateStore(StoreViewModel model, string command = null)
|
||||
{
|
||||
@@ -704,7 +714,7 @@ namespace BTCPayServer.Controllers
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
|
||||
return new DerivationSchemeSettings(parser.Parse(derivationScheme), network);
|
||||
}
|
||||
|
||||
|
||||
@@ -222,7 +222,21 @@ namespace BTCPayServer.Controllers
|
||||
continue;
|
||||
}
|
||||
|
||||
if (addressType == "segwit")
|
||||
if (!network.NBitcoinNetwork.Consensus.SupportTaproot && addressType == "taproot")
|
||||
{
|
||||
await websocketHelper.Send("{ \"error\": \"taproot-notsupported\"}", cancellationToken);
|
||||
continue;
|
||||
}
|
||||
if (addressType == "taproot")
|
||||
{
|
||||
keyPath = new KeyPath("86'").Derive(network.CoinType).Derive(accountNumber, true);
|
||||
xpub = await device.GetXPubAsync(keyPath);
|
||||
strategy = factory.CreateDirectDerivationStrategy(xpub, new DerivationStrategyOptions()
|
||||
{
|
||||
ScriptPubKeyType = ScriptPubKeyType.TaprootBIP86
|
||||
});
|
||||
}
|
||||
else if (addressType == "segwit")
|
||||
{
|
||||
keyPath = new KeyPath("84'").Derive(network.CoinType).Derive(accountNumber, true);
|
||||
xpub = await device.GetXPubAsync(keyPath);
|
||||
@@ -337,6 +351,8 @@ askdevice:
|
||||
private ScriptPubKeyType GetScriptPubKeyType(RootedKeyPath keyPath)
|
||||
{
|
||||
var path = keyPath.KeyPath.ToString();
|
||||
if (path.StartsWith("86'", StringComparison.OrdinalIgnoreCase))
|
||||
return ScriptPubKeyType.TaprootBIP86;
|
||||
if (path.StartsWith("84'", StringComparison.OrdinalIgnoreCase))
|
||||
return ScriptPubKeyType.Segwit;
|
||||
if (path.StartsWith("49'", StringComparison.OrdinalIgnoreCase))
|
||||
|
||||
Reference in New Issue
Block a user