mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 22:14:26 +01:00
Decouple taproot activation from support in generate wallet (#2837)
This commit is contained in:
@@ -55,7 +55,9 @@ namespace BTCPayServer.Controllers
|
|||||||
vm.RootKeyPath = network.GetRootKeyPath();
|
vm.RootKeyPath = network.GetRootKeyPath();
|
||||||
vm.CanUseHotWallet = hotWallet;
|
vm.CanUseHotWallet = hotWallet;
|
||||||
vm.CanUseRPCImport = rpcImport;
|
vm.CanUseRPCImport = rpcImport;
|
||||||
vm.CanUseTaproot = TaprootSupported(vm.CryptoCode);
|
vm.SupportTaproot = network.NBitcoinNetwork.Consensus.SupportTaproot;
|
||||||
|
vm.SupportSegwit = network.NBitcoinNetwork.Consensus.SupportSegwit;
|
||||||
|
vm.IsTaprootActivated = TaprootActivated(vm.CryptoCode);
|
||||||
|
|
||||||
if (vm.Method == null)
|
if (vm.Method == null)
|
||||||
{
|
{
|
||||||
@@ -110,11 +112,6 @@ namespace BTCPayServer.Controllers
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
strategy = ParseDerivationStrategy(vm.DerivationScheme, network);
|
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";
|
strategy.Source = "ManualDerivationScheme";
|
||||||
if (!string.IsNullOrEmpty(vm.AccountKey))
|
if (!string.IsNullOrEmpty(vm.AccountKey))
|
||||||
{
|
{
|
||||||
@@ -214,7 +211,9 @@ namespace BTCPayServer.Controllers
|
|||||||
|
|
||||||
vm.CanUseHotWallet = hotWallet;
|
vm.CanUseHotWallet = hotWallet;
|
||||||
vm.CanUseRPCImport = rpcImport;
|
vm.CanUseRPCImport = rpcImport;
|
||||||
vm.CanUseTaproot = TaprootSupported(vm.CryptoCode);
|
vm.SupportTaproot = network.NBitcoinNetwork.Consensus.SupportTaproot;
|
||||||
|
vm.SupportSegwit = network.NBitcoinNetwork.Consensus.SupportSegwit;
|
||||||
|
vm.IsTaprootActivated = TaprootActivated(vm.CryptoCode);
|
||||||
vm.RootKeyPath = network.GetRootKeyPath();
|
vm.RootKeyPath = network.GetRootKeyPath();
|
||||||
vm.Network = network;
|
vm.Network = network;
|
||||||
|
|
||||||
@@ -266,14 +265,11 @@ namespace BTCPayServer.Controllers
|
|||||||
IsHotWallet = isImport ? request.SavePrivateKeys : method == WalletSetupMethod.HotWallet,
|
IsHotWallet = isImport ? request.SavePrivateKeys : method == WalletSetupMethod.HotWallet,
|
||||||
DerivationSchemeFormat = "BTCPay",
|
DerivationSchemeFormat = "BTCPay",
|
||||||
CanUseHotWallet = hotWallet,
|
CanUseHotWallet = hotWallet,
|
||||||
CanUseRPCImport = rpcImport
|
CanUseRPCImport = rpcImport,
|
||||||
|
IsTaprootActivated = TaprootActivated(cryptoCode),
|
||||||
|
SupportTaproot = network.NBitcoinNetwork.Consensus.SupportTaproot,
|
||||||
|
SupportSegwit = network.NBitcoinNetwork.Consensus.SupportSegwit
|
||||||
};
|
};
|
||||||
|
|
||||||
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))
|
if (isImport && string.IsNullOrEmpty(request.ExistingMnemonic))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -146,11 +146,16 @@ namespace BTCPayServer.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TaprootSupported(string crytoCode)
|
public bool TaprootActivated(string crytoCode)
|
||||||
{
|
{
|
||||||
var networkSupport = ((BTCPayNetwork)_NetworkProvider.GetNetwork(crytoCode))?.NBitcoinNetwork?.Consensus?.SupportTaproot is true;
|
var network = (BTCPayNetwork)_NetworkProvider.GetNetwork(crytoCode);
|
||||||
|
#pragma warning disable CS0618
|
||||||
|
if (!(network.IsBTC && network.NBitcoinNetwork.ChainName == ChainName.Mainnet))
|
||||||
|
// Consider it activated for everything that is not mainnet bitcoin
|
||||||
|
return true;
|
||||||
|
#pragma warning restore CS0618
|
||||||
var status = _Dashboard.Get(crytoCode).Status;
|
var status = _Dashboard.Get(crytoCode).Status;
|
||||||
return networkSupport && !(status.NetworkType == ChainName.Mainnet && status.ChainHeight < 709632);
|
return status.ChainHeight >= 709632;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,10 @@ namespace BTCPayServer.Models.StoreViewModels
|
|||||||
public bool CanUseHotWallet { get; set; }
|
public bool CanUseHotWallet { get; set; }
|
||||||
[Display(Name = "Can use RPC import")]
|
[Display(Name = "Can use RPC import")]
|
||||||
public bool CanUseRPCImport { get; set; }
|
public bool CanUseRPCImport { get; set; }
|
||||||
[Display(Name = "Can use Taproot")]
|
public bool SupportSegwit { get; set; }
|
||||||
public bool CanUseTaproot { get; set; }
|
public bool SupportTaproot { get; set; }
|
||||||
|
[Display(Name = "Is taproot activated")]
|
||||||
|
public bool IsTaprootActivated { get; set; }
|
||||||
public RootedKeyPath GetAccountKeypath()
|
public RootedKeyPath GetAccountKeypath()
|
||||||
{
|
{
|
||||||
if (KeyPath != null && RootFingerprint != null &&
|
if (KeyPath != null && RootFingerprint != null &&
|
||||||
|
|||||||
@@ -7,7 +7,9 @@
|
|||||||
ViewData.SetActivePageAndTitle(StoreNavPages.Wallet, $"Create {Model.CryptoCode} {type} Wallet", Context.GetStoreData().StoreName);
|
ViewData.SetActivePageAndTitle(StoreNavPages.Wallet, $"Create {Model.CryptoCode} {type} Wallet", Context.GetStoreData().StoreName);
|
||||||
ViewData.Add(nameof(Model.CanUseHotWallet), Model.CanUseHotWallet);
|
ViewData.Add(nameof(Model.CanUseHotWallet), Model.CanUseHotWallet);
|
||||||
ViewData.Add(nameof(Model.CanUseRPCImport), Model.CanUseRPCImport);
|
ViewData.Add(nameof(Model.CanUseRPCImport), Model.CanUseRPCImport);
|
||||||
ViewData.Add(nameof(Model.CanUseTaproot), Model.CanUseTaproot);
|
ViewData.Add(nameof(Model.IsTaprootActivated), Model.IsTaprootActivated);
|
||||||
|
ViewData.Add(nameof(Model.SupportSegwit), Model.SupportSegwit);
|
||||||
|
ViewData.Add(nameof(Model.SupportTaproot), Model.SupportTaproot);
|
||||||
ViewData.Add(nameof(Model.Method), Model.Method);
|
ViewData.Add(nameof(Model.Method), Model.Method);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,9 @@
|
|||||||
{
|
{
|
||||||
ViewData.Add(nameof(Model.CanUseHotWallet), Model.CanUseHotWallet);
|
ViewData.Add(nameof(Model.CanUseHotWallet), Model.CanUseHotWallet);
|
||||||
ViewData.Add(nameof(Model.CanUseRPCImport), Model.CanUseRPCImport);
|
ViewData.Add(nameof(Model.CanUseRPCImport), Model.CanUseRPCImport);
|
||||||
ViewData.Add(nameof(Model.CanUseTaproot), Model.CanUseTaproot);
|
ViewData.Add(nameof(Model.IsTaprootActivated), Model.IsTaprootActivated);
|
||||||
|
ViewData.Add(nameof(Model.SupportSegwit), Model.SupportSegwit);
|
||||||
|
ViewData.Add(nameof(Model.SupportTaproot), Model.SupportTaproot);
|
||||||
ViewData.Add(nameof(Model.Method), Model.Method);
|
ViewData.Add(nameof(Model.Method), Model.Method);
|
||||||
|
|
||||||
<partial name="_GenerateWalletForm" model="Model.SetupRequest" />
|
<partial name="_GenerateWalletForm" model="Model.SetupRequest" />
|
||||||
|
|||||||
@@ -47,32 +47,35 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
@if (Model.SupportSegwit)
|
||||||
<td rowspan="4">P2WPKH</td>
|
{
|
||||||
<td class="font-monospace">xpub…</td>
|
<tr>
|
||||||
</tr>
|
<td rowspan="4">P2WPKH</td>
|
||||||
<tr>
|
<td class="font-monospace">xpub…</td>
|
||||||
<td class="font-monospace">zpub…</td>
|
</tr>
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<td class="font-monospace">zpub…</td>
|
||||||
<td class="font-monospace">wpkh(xpub…/0/*)</td>
|
</tr>
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<td class="font-monospace">wpkh(xpub…/0/*)</td>
|
||||||
<td class="font-monospace">wpkh([…/84'/0'/0']xpub…/0/*)</td>
|
</tr>
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<td class="font-monospace">wpkh([…/84'/0'/0']xpub…/0/*)</td>
|
||||||
<td rowspan="4">P2SH-P2WPKH</td>
|
</tr>
|
||||||
<td class="font-monospace">xpub…-[p2sh]</td>
|
<tr>
|
||||||
</tr>
|
<td rowspan="4">P2SH-P2WPKH</td>
|
||||||
<tr>
|
<td class="font-monospace">xpub…-[p2sh]</td>
|
||||||
<td class="font-monospace">ypub…</td>
|
</tr>
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<td class="font-monospace">ypub…</td>
|
||||||
<td class="font-monospace">sh(wpkh(xpub…/0/*)</td>
|
</tr>
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<td class="font-monospace">sh(wpkh(xpub…/0/*)</td>
|
||||||
<td class="font-monospace">sh(wpkh([…/49'/0'/0']xpub…/0/*)</td>
|
</tr>
|
||||||
</tr>
|
<tr>
|
||||||
|
<td class="font-monospace">sh(wpkh([…/49'/0'/0']xpub…/0/*)</td>
|
||||||
|
</tr>
|
||||||
|
}
|
||||||
<tr>
|
<tr>
|
||||||
<td rowspan="3">P2PKH</td>
|
<td rowspan="3">P2PKH</td>
|
||||||
<td class="font-monospace">xpub…-[legacy]</td>
|
<td class="font-monospace">xpub…-[legacy]</td>
|
||||||
@@ -83,7 +86,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="font-monospace">pkh(xpub…/0/*)</td>
|
<td class="font-monospace">pkh(xpub…/0/*)</td>
|
||||||
</tr>
|
</tr>
|
||||||
@if (Model.CanUseTaproot)
|
@if (Model.SupportTaproot && Model.IsTaprootActivated)
|
||||||
{
|
{
|
||||||
<tr>
|
<tr>
|
||||||
<td rowspan="1">P2TR</td>
|
<td rowspan="1">P2TR</td>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
var isHotWallet = method is WalletSetupMethod.HotWallet;
|
var isHotWallet = method is WalletSetupMethod.HotWallet;
|
||||||
var canUseHotWallet = ViewData["CanUseHotWallet"] is true;
|
var canUseHotWallet = ViewData["CanUseHotWallet"] is true;
|
||||||
var canUseRpcImport = ViewData["CanUseRPCImport"] is true;
|
var canUseRpcImport = ViewData["CanUseRPCImport"] is true;
|
||||||
var canUseTaproot = ViewData["CanUseTaproot"] is true;
|
var isTaprootActivated = ViewData["IsTaprootActivated"] is true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (!User.IsInRole(Roles.ServerAdmin))
|
@if (!User.IsInRole(Roles.ServerAdmin))
|
||||||
@@ -34,12 +34,27 @@
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label asp-for="ScriptPubKeyType" class="form-label">Address type</label>
|
<label asp-for="ScriptPubKeyType" class="form-label">Address type</label>
|
||||||
<select class="form-select w-auto" asp-for="ScriptPubKeyType">
|
<select class="form-select w-auto" asp-for="ScriptPubKeyType">
|
||||||
<option value="@ScriptPubKeyType.Segwit">Segwit (Recommended, cheapest transaction fee)</option>
|
@if (ViewData["SupportSegwit"] is true)
|
||||||
<option value="@ScriptPubKeyType.SegwitP2SH">Segwit wrapped (Compatible with old wallets)</option>
|
|
||||||
<option value="@ScriptPubKeyType.Legacy">Legacy (Not recommended)</option>
|
|
||||||
@if (canUseTaproot)
|
|
||||||
{
|
{
|
||||||
<option value="@ScriptPubKeyType.TaprootBIP86">Taproot (ONLY FOR DEVELOPMENT)</option>
|
<option value="@ScriptPubKeyType.Segwit">Segwit (Recommended)</option>
|
||||||
|
<option value="@ScriptPubKeyType.SegwitP2SH">Segwit wrapped (Compatible with old wallets)</option>
|
||||||
|
<option value="@ScriptPubKeyType.Legacy">Legacy (Not recommended)</option>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<option value="@ScriptPubKeyType.Legacy">Legacy</option>
|
||||||
|
}
|
||||||
|
|
||||||
|
@if (ViewData["SupportTaproot"] is true)
|
||||||
|
{
|
||||||
|
@if (isTaprootActivated)
|
||||||
|
{
|
||||||
|
<option value="@ScriptPubKeyType.TaprootBIP86">Taproot (For advanced users)</option>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<option value="@ScriptPubKeyType.TaprootBIP86" disabled>Taproot (Available from block 709632)</option>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
<span asp-validation-for="ScriptPubKeyType" class="text-danger"></span>
|
<span asp-validation-for="ScriptPubKeyType" class="text-danger"></span>
|
||||||
|
|||||||
Reference in New Issue
Block a user