2020-06-29 04:44:35 +02:00
|
|
|
using System;
|
2019-05-08 16:39:11 +02:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
|
|
|
using BTCPayServer.Payments;
|
|
|
|
using NBitcoin;
|
2022-04-12 09:55:10 +02:00
|
|
|
using NBXplorer.Client;
|
2019-05-08 16:39:11 +02:00
|
|
|
using NBXplorer.DerivationStrategy;
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
|
|
namespace BTCPayServer
|
|
|
|
{
|
2024-04-04 09:31:04 +02:00
|
|
|
public class DerivationSchemeSettings
|
2019-05-08 16:39:11 +02:00
|
|
|
{
|
|
|
|
public static DerivationSchemeSettings Parse(string derivationStrategy, BTCPayNetwork network)
|
|
|
|
{
|
2021-12-28 09:39:54 +01:00
|
|
|
ArgumentNullException.ThrowIfNull(network);
|
|
|
|
ArgumentNullException.ThrowIfNull(derivationStrategy);
|
2024-04-04 09:31:04 +02:00
|
|
|
var result = new DerivationSchemeSettings();
|
2024-01-17 10:08:39 +01:00
|
|
|
var parser = network.GetDerivationSchemeParser();
|
2024-01-24 09:49:15 +01:00
|
|
|
if (parser.TryParseXpub(derivationStrategy, ref result) ||
|
|
|
|
parser.TryParseXpub(derivationStrategy, ref result, electrum: true))
|
2021-01-11 03:22:42 +01:00
|
|
|
{
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-01-24 09:49:15 +01:00
|
|
|
throw new FormatException($"Invalid Derivation Scheme");
|
2019-05-08 16:39:11 +02:00
|
|
|
}
|
2019-05-08 17:40:30 +02:00
|
|
|
|
2024-04-04 09:31:04 +02:00
|
|
|
public string GetNBXWalletId(Network network)
|
2019-05-09 09:11:09 +02:00
|
|
|
{
|
2024-04-04 09:31:04 +02:00
|
|
|
return AccountDerivation is null ? null : DBUtils.nbxv1_get_wallet_id(network.NetworkSet.CryptoCode, AccountDerivation.ToString());
|
2022-04-12 09:55:10 +02:00
|
|
|
}
|
2023-04-10 04:07:03 +02:00
|
|
|
|
2019-05-08 16:39:11 +02:00
|
|
|
public DerivationSchemeSettings()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
2019-05-12 17:30:28 +02:00
|
|
|
|
2019-05-08 16:39:11 +02:00
|
|
|
public DerivationSchemeSettings(DerivationStrategyBase derivationStrategy, BTCPayNetwork network)
|
|
|
|
{
|
2021-12-28 09:39:54 +01:00
|
|
|
ArgumentNullException.ThrowIfNull(network);
|
|
|
|
ArgumentNullException.ThrowIfNull(derivationStrategy);
|
2019-05-08 16:39:11 +02:00
|
|
|
AccountDerivation = derivationStrategy;
|
2019-05-12 17:13:55 +02:00
|
|
|
AccountKeySettings = derivationStrategy.GetExtPubKeys().Select(c => new AccountKeySettings()
|
|
|
|
{
|
|
|
|
AccountKey = c.GetWif(network.NBitcoinNetwork)
|
|
|
|
}).ToArray();
|
2019-05-08 16:39:11 +02:00
|
|
|
}
|
2019-05-12 17:30:28 +02:00
|
|
|
|
|
|
|
|
|
|
|
BitcoinExtPubKey _SigningKey;
|
|
|
|
public BitcoinExtPubKey SigningKey
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return _SigningKey ?? AccountKeySettings?.Select(k => k.AccountKey).FirstOrDefault();
|
|
|
|
}
|
|
|
|
set
|
|
|
|
{
|
|
|
|
_SigningKey = value;
|
|
|
|
}
|
|
|
|
}
|
2019-05-08 17:54:53 +02:00
|
|
|
public string Source { get; set; }
|
2021-06-17 08:36:22 +02:00
|
|
|
|
|
|
|
public bool IsHotWallet { get; set; }
|
2019-05-12 17:13:55 +02:00
|
|
|
|
2021-02-11 11:48:54 +01:00
|
|
|
[Obsolete("Use GetSigningAccountKeySettings().AccountKeyPath instead")]
|
2019-05-12 17:13:55 +02:00
|
|
|
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
2019-05-08 16:39:11 +02:00
|
|
|
public KeyPath AccountKeyPath { get; set; }
|
2019-05-10 12:30:10 +02:00
|
|
|
|
2019-05-08 16:39:11 +02:00
|
|
|
public DerivationStrategyBase AccountDerivation { get; set; }
|
|
|
|
public string AccountOriginal { get; set; }
|
|
|
|
|
2021-02-11 11:48:54 +01:00
|
|
|
[Obsolete("Use GetSigningAccountKeySettings().RootFingerprint instead")]
|
2019-05-12 17:13:55 +02:00
|
|
|
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
2019-05-08 16:39:11 +02:00
|
|
|
public HDFingerprint? RootFingerprint { get; set; }
|
|
|
|
|
2021-02-11 11:48:54 +01:00
|
|
|
[Obsolete("Use GetSigningAccountKeySettings().AccountKey instead")]
|
2019-05-12 17:13:55 +02:00
|
|
|
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
|
2019-05-10 12:30:10 +02:00
|
|
|
public BitcoinExtPubKey ExplicitAccountKey { get; set; }
|
|
|
|
|
2019-05-12 17:30:28 +02:00
|
|
|
public AccountKeySettings GetSigningAccountKeySettings()
|
|
|
|
{
|
|
|
|
return AccountKeySettings.Single(a => a.AccountKey == SigningKey);
|
|
|
|
}
|
|
|
|
|
2019-05-12 17:13:55 +02:00
|
|
|
public AccountKeySettings[] AccountKeySettings
|
|
|
|
{
|
2024-04-04 09:31:04 +02:00
|
|
|
get;
|
|
|
|
set;
|
2019-05-12 17:13:55 +02:00
|
|
|
}
|
|
|
|
|
2019-05-12 04:07:41 +02:00
|
|
|
public IEnumerable<NBXplorer.Models.PSBTRebaseKeyRules> GetPSBTRebaseKeyRules()
|
|
|
|
{
|
2019-05-12 17:30:28 +02:00
|
|
|
foreach (var accountKey in AccountKeySettings)
|
2019-05-12 04:07:41 +02:00
|
|
|
{
|
2019-11-16 09:22:51 +01:00
|
|
|
if (accountKey.GetRootedKeyPath() is RootedKeyPath rootedKeyPath)
|
2019-05-12 04:07:41 +02:00
|
|
|
{
|
2019-05-12 17:13:55 +02:00
|
|
|
yield return new NBXplorer.Models.PSBTRebaseKeyRules()
|
|
|
|
{
|
|
|
|
AccountKey = accountKey.AccountKey,
|
2019-11-16 09:22:51 +01:00
|
|
|
AccountKeyPath = rootedKeyPath
|
2019-05-12 17:13:55 +02:00
|
|
|
};
|
|
|
|
}
|
2019-05-12 04:07:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-08 16:39:11 +02:00
|
|
|
public string Label { get; set; }
|
|
|
|
|
|
|
|
public override string ToString()
|
|
|
|
{
|
|
|
|
return AccountDerivation.ToString();
|
|
|
|
}
|
|
|
|
public string ToPrettyString()
|
|
|
|
{
|
2019-05-08 18:07:05 +02:00
|
|
|
return !string.IsNullOrEmpty(Label) ? Label :
|
|
|
|
!String.IsNullOrEmpty(AccountOriginal) ? AccountOriginal :
|
2019-05-08 16:39:11 +02:00
|
|
|
ToString();
|
|
|
|
}
|
2019-05-09 09:11:09 +02:00
|
|
|
|
2019-05-12 04:07:41 +02:00
|
|
|
public void RebaseKeyPaths(PSBT psbt)
|
|
|
|
{
|
|
|
|
foreach (var rebase in GetPSBTRebaseKeyRules())
|
|
|
|
{
|
2019-11-16 09:22:51 +01:00
|
|
|
psbt.RebaseKeyPaths(rebase.AccountKey, rebase.AccountKeyPath);
|
2019-05-12 04:07:41 +02:00
|
|
|
}
|
|
|
|
}
|
2019-05-08 16:39:11 +02:00
|
|
|
}
|
2019-05-12 17:13:55 +02:00
|
|
|
public class AccountKeySettings
|
|
|
|
{
|
|
|
|
public HDFingerprint? RootFingerprint { get; set; }
|
|
|
|
public KeyPath AccountKeyPath { get; set; }
|
2019-05-14 09:06:43 +02:00
|
|
|
|
|
|
|
public RootedKeyPath GetRootedKeyPath()
|
|
|
|
{
|
|
|
|
if (RootFingerprint is HDFingerprint fp && AccountKeyPath != null)
|
|
|
|
return new RootedKeyPath(fp, AccountKeyPath);
|
|
|
|
return null;
|
|
|
|
}
|
2019-05-12 17:13:55 +02:00
|
|
|
public BitcoinExtPubKey AccountKey { get; set; }
|
|
|
|
public bool IsFullySetup()
|
|
|
|
{
|
|
|
|
return AccountKeyPath != null && RootFingerprint is HDFingerprint;
|
|
|
|
}
|
|
|
|
}
|
2019-05-08 16:39:11 +02:00
|
|
|
}
|