Simplify logic in LedgerHardwareWalletSerivce by using NBitcoin helper methods.

This commit is contained in:
nicolas.dorier 2019-05-13 08:18:12 +09:00
parent 702c7f2c30
commit f9fb0bb477
No known key found for this signature in database
GPG Key ID: 6618763EF09186FE
2 changed files with 11 additions and 33 deletions

View File

@ -47,7 +47,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="NBitcoin" Version="4.1.2.21" />
<PackageReference Include="NBitcoin" Version="4.1.2.22" />
<PackageReference Include="NBitpayClient" Version="1.0.0.34" />
<PackageReference Include="DBriize" Version="1.0.0.4" />
<PackageReference Include="NBXplorer.Client" Version="2.0.0.12" />

View File

@ -114,11 +114,7 @@ namespace BTCPayServer.Services
account.Indexes.Length == 0 ? 0 : account.Indexes.Last()).GetWif(network.NBitcoinNetwork);
return extpubkey;
}
class HDKey
{
public PubKey PubKey { get; set; }
public KeyPath KeyPath { get; set; }
}
public override async Task<PSBT> SignTransactionAsync(PSBT psbt, HDFingerprint? rootFingerprint, BitcoinExtPubKey accountKey, Script changeHint, CancellationToken cancellationToken)
{
HashSet<HDFingerprint> knownFingerprints = new HashSet<HDFingerprint>();
@ -126,22 +122,20 @@ namespace BTCPayServer.Services
if (rootFingerprint is HDFingerprint fp)
knownFingerprints.Add(fp);
var unsigned = psbt.GetGlobalTransaction();
var changeKeyPath = psbt.Outputs
.Where(o => changeHint == null ? true : changeHint == o.ScriptPubKey)
.Select(o => (Output: o, HDKey: GetHDKey(knownFingerprints, accountKey, o)))
.Where(o => o.HDKey != null)
.Select(o => o.HDKey.KeyPath)
var changeKeyPath = psbt.Outputs.HDKeysFor(rootFingerprint, accountKey)
.Where(o => changeHint == null ? true : changeHint == o.Coin.ScriptPubKey)
.Select(o => o.KeyPath)
.FirstOrDefault();
var signatureRequests = psbt
.Inputs
.Select(i => (Input: i, HDKey: GetHDKey(knownFingerprints, accountKey, i)))
.Where(i => i.HDKey != null)
.HDKeysFor(rootFingerprint, accountKey)
.GroupBy(hd => hd.Coin)
.Select(i => new SignatureRequest()
{
InputCoin = i.Input.GetSignableCoin(),
InputTransaction = i.Input.NonWitnessUtxo,
KeyPath = i.HDKey.KeyPath,
PubKey = i.HDKey.PubKey
InputCoin = i.Key.GetSignableCoin(),
InputTransaction = i.Key.NonWitnessUtxo,
KeyPath = i.First().KeyPath,
PubKey = i.First().PubKey
}).ToArray();
var signedTransaction = await Ledger.SignTransactionAsync(signatureRequests, unsigned, changeKeyPath, cancellationToken);
if (signedTransaction == null)
@ -160,22 +154,6 @@ namespace BTCPayServer.Services
return psbt;
}
private HDKey GetHDKey(HashSet<HDFingerprint> knownFingerprints, BitcoinExtPubKey accountKey, PSBTCoin coin)
{
// Check if the accountKey match this coin by checking if the non hardened last part of the path
// can derive the same pubkey
foreach (var key in coin.HDKeyPaths)
{
if (!knownFingerprints.Contains(key.Value.Item1))
continue;
var accountKeyPath = key.Value.Item2.GetAccountKeyPath();
// We might have a fingerprint collision, let's check
if (accountKey.ExtPubKey.Derive(accountKeyPath).GetPublicKey() == key.Key)
return new HDKey() { KeyPath = key.Value.Item2, PubKey = key.Key };
}
return null;
}
public override void Dispose()
{
if (_Transport != null)