mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-26 15:41:29 +01:00
* Refactor Wallet import code The code for wallet import was incredibly messy as it evolved over time from various requests. This PR: * splits up each supported format into its own file * Supports taproot descriptors (through a hack until NBitcoin supports it internally) fixes #5518 * Reduces different paths for handling electrum/non-electrum xpubs * Allows plugins to add their own import support formats for onchain wallets. * Update NBitcoin to parse tr descriptors * Fix warnings * Use dedicated type OnChainWalletParsers --------- Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
76 lines
2.7 KiB
C#
76 lines
2.7 KiB
C#
#nullable enable
|
|
using System;
|
|
using System.Linq;
|
|
using BTCPayServer;
|
|
using NBitcoin;
|
|
using NBXplorer.DerivationStrategy;
|
|
using AccountKeySettings = BTCPayServer.AccountKeySettings;
|
|
using BTCPayNetwork = BTCPayServer.BTCPayNetwork;
|
|
|
|
namespace BTCPayServer.Services.WalletFileParsing;
|
|
public class BSMSWalletFileParser : IWalletFileParser
|
|
{
|
|
public (BTCPayServer.DerivationSchemeSettings? DerivationSchemeSettings, string? Error) TryParse(
|
|
BTCPayNetwork network,
|
|
string data)
|
|
{
|
|
try
|
|
{
|
|
string[] lines = data.Split(
|
|
new[] {"\r\n", "\r", "\n"},
|
|
StringSplitOptions.None
|
|
);
|
|
|
|
if (!lines[0].Trim().Equals("BSMS 1.0"))
|
|
{
|
|
return (null, null);
|
|
}
|
|
|
|
var descriptor = lines[1];
|
|
var derivationPath = lines[2].Split(',', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault() ??
|
|
"/0/*";
|
|
if (derivationPath == "No path restrictions")
|
|
{
|
|
derivationPath = "/0/*";
|
|
}
|
|
|
|
if (derivationPath != "/0/*")
|
|
{
|
|
return (null, "BTCPay Server can only derive address to the deposit and change paths");
|
|
}
|
|
|
|
|
|
descriptor = descriptor.Replace("/**", derivationPath);
|
|
var testAddress = BitcoinAddress.Create(lines[3], network.NBitcoinNetwork);
|
|
|
|
var result = network.GetDerivationSchemeParser().ParseOutputDescriptor(descriptor);
|
|
|
|
var deposit = new NBXplorer.KeyPathTemplates(null).GetKeyPathTemplate(DerivationFeature.Deposit);
|
|
var line = result.Item1.GetLineFor(deposit).Derive(0);
|
|
|
|
if (testAddress.ScriptPubKey != line.ScriptPubKey)
|
|
{
|
|
return (null, "BSMS test address did not match our generated address");
|
|
}
|
|
|
|
var derivationSchemeSettings = new BTCPayServer.DerivationSchemeSettings()
|
|
{
|
|
Network = network,
|
|
Source = "BSMS",
|
|
AccountDerivation = result.Item1,
|
|
AccountOriginal = descriptor.Trim(),
|
|
AccountKeySettings = result.Item2.Select((path, i) => new AccountKeySettings()
|
|
{
|
|
RootFingerprint = path?.MasterFingerprint,
|
|
AccountKeyPath = path?.KeyPath,
|
|
AccountKey = result.Item1.GetExtPubKeys().ElementAt(i).GetWif(network.NBitcoinNetwork)
|
|
}).ToArray()
|
|
};
|
|
return (derivationSchemeSettings, null);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
return (null, $"BSMS parse error: {e.Message}");
|
|
}
|
|
}
|
|
}
|