Refactor wallet file parsing (Fix: #5690) (#5692)

This commit is contained in:
Nicolas Dorier
2024-01-23 21:33:45 +09:00
committed by GitHub
parent 27e70a169e
commit b03f8db06b
10 changed files with 219 additions and 314 deletions

View File

@@ -1,5 +1,6 @@
#nullable enable
#nullable enable
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using BTCPayServer;
using NBitcoin;
@@ -10,67 +11,51 @@ using BTCPayNetwork = BTCPayServer.BTCPayNetwork;
namespace BTCPayServer.Services.WalletFileParsing;
public class BSMSWalletFileParser : IWalletFileParser
{
public (BTCPayServer.DerivationSchemeSettings? DerivationSchemeSettings, string? Error) TryParse(
BTCPayNetwork network,
string data)
public bool TryParse(BTCPayNetwork network, string data, [MaybeNullWhen(false)] out DerivationSchemeSettings derivationSchemeSettings)
{
try
derivationSchemeSettings = null;
string[] lines = data.Split(
new[] { "\r\n", "\r", "\n" },
StringSplitOptions.None
);
if (lines.Length < 4 || !lines[0].Trim().Equals("BSMS 1.0"))
return false;
var descriptor = lines[1];
var derivationPath = lines[2].Split(',', StringSplitOptions.RemoveEmptyEntries).FirstOrDefault() ??
"/0/*";
if (derivationPath == "No path restrictions")
derivationPath = "/0/*";
if (derivationPath != "/0/*")
return false;
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 false;
derivationSchemeSettings = new BTCPayServer.DerivationSchemeSettings()
{
string[] lines = data.Split(
new[] {"\r\n", "\r", "\n"},
StringSplitOptions.None
);
if (!lines[0].Trim().Equals("BSMS 1.0"))
Network = network,
Source = "BSMS",
AccountDerivation = result.Item1,
AccountOriginal = descriptor.Trim(),
AccountKeySettings = result.Item2.Select((path, i) => new AccountKeySettings()
{
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}");
}
RootFingerprint = path?.MasterFingerprint,
AccountKeyPath = path?.KeyPath,
AccountKey = result.Item1.GetExtPubKeys().ElementAt(i).GetWif(network.NBitcoinNetwork)
}).ToArray()
};
return true;
}
}