Allow account selection of the ledger

This commit is contained in:
nicolas.dorier
2018-03-18 14:15:23 +09:00
parent 8342ad9175
commit 806474c8c6
5 changed files with 134 additions and 105 deletions

View File

@@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework> <TargetFramework>netcoreapp2.0</TargetFramework>
<Version>1.0.1.50</Version> <Version>1.0.1.51</Version>
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn> <NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@@ -129,6 +129,8 @@ namespace BTCPayServer.Controllers
string command, string command,
// getinfo // getinfo
string cryptoCode = null, string cryptoCode = null,
// getxpub
int account = 0,
// sendtoaddress // sendtoaddress
string destination = null, string amount = null, string feeRate = null, string substractFees = null string destination = null, string amount = null, string feeRate = null, string substractFees = null
) )
@@ -204,7 +206,9 @@ namespace BTCPayServer.Controllers
} }
if (command == "getxpub") if (command == "getxpub")
{ {
result = await hw.GetExtPubKey(network); var getxpubResult = await hw.GetExtPubKey(network, account); ;
getxpubResult.CoinType = (int)(getxpubResult.KeyPath.Indexes[1] - 0x80000000);
result = getxpubResult;
} }
if (command == "getinfo") if (command == "getinfo")
{ {

View File

@@ -8,6 +8,7 @@ using BTCPayServer.Services.Wallets;
using LedgerWallet; using LedgerWallet;
using NBitcoin; using NBitcoin;
using NBXplorer.DerivationStrategy; using NBXplorer.DerivationStrategy;
using Newtonsoft.Json;
namespace BTCPayServer.Services namespace BTCPayServer.Services
{ {
@@ -76,18 +77,19 @@ namespace BTCPayServer.Services
return new LedgerTestResult() { Success = true }; return new LedgerTestResult() { Success = true };
} }
public async Task<GetXPubResult> GetExtPubKey(BTCPayNetwork network) public async Task<GetXPubResult> GetExtPubKey(BTCPayNetwork network, int account)
{ {
if (network == null) if (network == null)
throw new ArgumentNullException(nameof(network)); throw new ArgumentNullException(nameof(network));
var pubkey = await GetExtPubKey(_Ledger, network, new KeyPath("49'").Derive(network.CoinType).Derive(0, true), false); var path = new KeyPath("49'").Derive(network.CoinType).Derive(account, true);
var pubkey = await GetExtPubKey(_Ledger, network, path, false);
var derivation = new DerivationStrategyFactory(network.NBitcoinNetwork).CreateDirectDerivationStrategy(pubkey, new DerivationStrategyOptions() var derivation = new DerivationStrategyFactory(network.NBitcoinNetwork).CreateDirectDerivationStrategy(pubkey, new DerivationStrategyOptions()
{ {
P2SH = true, P2SH = true,
Legacy = false Legacy = false
}); });
return new GetXPubResult() { ExtPubKey = derivation.ToString() }; return new GetXPubResult() { ExtPubKey = derivation.ToString(), KeyPath = path };
} }
private static async Task<BitcoinExtPubKey> GetExtPubKey(LedgerClient ledger, BTCPayNetwork network, KeyPath account, bool onlyChaincode) private static async Task<BitcoinExtPubKey> GetExtPubKey(LedgerClient ledger, BTCPayNetwork network, KeyPath account, bool onlyChaincode)
@@ -231,5 +233,8 @@ namespace BTCPayServer.Services
public class GetXPubResult public class GetXPubResult
{ {
public string ExtPubKey { get; set; } public string ExtPubKey { get; set; }
[JsonConverter(typeof(NBitcoin.JsonConverters.KeyPathJsonConverter))]
public KeyPath KeyPath { get; set; }
public int CoinType { get; internal set; }
} }
} }

View File

@@ -33,9 +33,15 @@
<p id="no-ledger-info" class="form-text text-muted" style="display: none;"> <p id="no-ledger-info" class="form-text text-muted" style="display: none;">
No ledger wallet detected. If you own one, use chrome, open the app, and refresh this page. No ledger wallet detected. If you own one, use chrome, open the app, and refresh this page.
</p> </p>
<p id="ledger-info" class="form-text text-muted" style="display: none;"> <div id="ledger-info" class="form-text text-muted" style="display: none;">
<span>A ledger wallet is detected, please use our <a id="ledger-info-recommended" href="#">recommended choice</a></span> <span>A ledger wallet is detected, which account do you want to use?</span>
</p> <ul>
@for(int i = 0; i < 4; i++)
{
<li><a class="ledger-info-recommended" data-ledgeraccount="@i" href="#">Account @i (49'/<span class="ledger-info-cointype">0</span>'/@i')</a></li>
}
</ul>
</div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="DerivationSchemeFormat"></label> <label asp-for="DerivationSchemeFormat"></label>

View File

@@ -1,8 +1,12 @@
$(function () { $(function () {
var ledgerDetected = false; var ledgerDetected = false;
var recommendedPubKey = "";
var bridge = new ledgerwebsocket.LedgerWebSocketBridge(srvModel + "ws/ledger"); var bridge = new ledgerwebsocket.LedgerWebSocketBridge(srvModel + "ws/ledger");
var cryptoSelector = $("#CryptoCurrency");
function GetSelectedCryptoCode() {
return cryptoSelector.val();
}
function WriteAlert(type, message) { function WriteAlert(type, message) {
} }
@@ -14,10 +18,18 @@
} }
} }
$("#ledger-info-recommended").on("click", function (elem) { $(".ledger-info-recommended").on("click", function (elem) {
elem.preventDefault(); elem.preventDefault();
$("#DerivationScheme").val(recommendedPubKey); var account = elem.currentTarget.getAttribute("data-ledgeraccount");
var cryptoCode = GetSelectedCryptoCode();
bridge.sendCommand("getxpub", "cryptoCode=" + cryptoCode + "&account=" + account)
.then(function (result) {
if (cryptoCode !== GetSelectedCryptoCode())
return;
$("#DerivationScheme").val(result.extPubKey);
$("#DerivationSchemeFormat").val("BTCPay"); $("#DerivationSchemeFormat").val("BTCPay");
})
.catch(function (reason) { Write('check', 'error', reason); });
return false; return false;
}); });
@@ -30,21 +42,23 @@
var updateInfo = function () { var updateInfo = function () {
if (!ledgerDetected) if (!ledgerDetected)
return false; return false;
var cryptoCode = $("#CryptoCurrency").val(); var cryptoCode = GetSelectedCryptoCode();
bridge.sendCommand("getxpub", "cryptoCode=" + cryptoCode) bridge.sendCommand("getxpub", "cryptoCode=" + cryptoCode)
.catch(function (reason) { Write('check', 'error', reason); }) .catch(function (reason) { Write('check', 'error', reason); })
.then(function (result) { .then(function (result) {
if (!result) if (!result)
return; return;
if (cryptoCode !== GetSelectedCryptoCode())
return;
if (result.error) { if (result.error) {
Write('check', 'error', result.error); Write('check', 'error', result.error);
return; return;
} }
else { else {
Write('check', 'success', 'This store is configured to use your ledger'); Write('check', 'success', 'This store is configured to use your ledger');
recommendedPubKey = result.extPubKey;
$("#no-ledger-info").css("display", "none"); $("#no-ledger-info").css("display", "none");
$("#ledger-info").css("display", "block"); $("#ledger-info").css("display", "block");
$(".ledger-info-cointype").text(result.coinType);
} }
}); });
}; };