Sign with NBX Seed (#1218)

This commit is contained in:
Andrew Camilleri
2020-01-21 09:33:12 +01:00
committed by Nicolas Dorier
parent 6848482999
commit 8e6f43cd3a
7 changed files with 85 additions and 4 deletions

View File

@@ -29,6 +29,7 @@ using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using NBitcoin;
using NBitcoin.DataEncoders;
using NBXplorer;
using NBXplorer.DerivationStrategy;
using NBXplorer.Models;
using Newtonsoft.Json;
@@ -54,6 +55,7 @@ namespace BTCPayServer.Controllers
private readonly BTCPayWalletProvider _walletProvider;
private readonly WalletReceiveStateService _WalletReceiveStateService;
private readonly EventAggregator _EventAggregator;
private readonly SettingsRepository _settingsRepository;
public RateFetcher RateFetcher { get; }
CurrencyNameTable _currencyTable;
@@ -70,7 +72,8 @@ namespace BTCPayServer.Controllers
IFeeProviderFactory feeRateProvider,
BTCPayWalletProvider walletProvider,
WalletReceiveStateService walletReceiveStateService,
EventAggregator eventAggregator)
EventAggregator eventAggregator,
SettingsRepository settingsRepository)
{
_currencyTable = currencyTable;
Repository = repo;
@@ -86,6 +89,7 @@ namespace BTCPayServer.Controllers
_walletProvider = walletProvider;
_WalletReceiveStateService = walletReceiveStateService;
_EventAggregator = eventAggregator;
_settingsRepository = settingsRepository;
}
// Borrowed from https://github.com/ManageIQ/guides/blob/master/labels.md
@@ -368,6 +372,15 @@ namespace BTCPayServer.Controllers
return RedirectToAction(nameof(WalletReceive), new {walletId});
}
private async Task<bool> CanUseHotWallet()
{
var isAdmin = (await _authorizationService.AuthorizeAsync(User, Policies.CanModifyServerSettings.Key)).Succeeded;
if (isAdmin)
return true;
var policies = await _settingsRepository.GetSettingAsync<PoliciesSettings>();
return policies?.AllowHotWalletForAll is true;
}
[HttpGet]
[Route("{walletId}/send")]
public async Task<IActionResult> WalletSend(
@@ -405,6 +418,9 @@ namespace BTCPayServer.Controllers
var feeProvider = _feeRateProvider.CreateFeeProvider(network);
var recommendedFees = feeProvider.GetFeeRateAsync();
var balance = _walletProvider.GetWallet(network).GetBalance(paymentMethod.AccountDerivation);
model.NBXSeedAvailable = await CanUseHotWallet() && !string.IsNullOrEmpty(await ExplorerClientProvider.GetExplorerClient(network)
.GetMetadataAsync<string>(GetDerivationSchemeSettings(walletId).AccountDerivation,
WellknownMetadataKeys.Mnemonic));
model.CurrentBalance = await balance;
model.RecommendedSatoshiPerByte = (int)(await recommendedFees).GetFee(1).Satoshi;
model.FeeSatoshiPerByte = model.RecommendedSatoshiPerByte;
@@ -554,6 +570,15 @@ namespace BTCPayServer.Controllers
{
case "vault":
return ViewVault(walletId, psbt.PSBT);
case "nbx-seed":
var extKey = await ExplorerClientProvider.GetExplorerClient(network)
.GetMetadataAsync<string>(derivationScheme.AccountDerivation, WellknownMetadataKeys.MasterHDKey, cancellation);
return await SignWithSeed(walletId, new SignWithSeedViewModel()
{
SeedOrKey = extKey,
PSBT = psbt.PSBT.ToBase64()
});
case "ledger":
return ViewWalletSendLedger(psbt.PSBT, psbt.ChangeAddress);
case "seed":
@@ -643,7 +668,7 @@ namespace BTCPayServer.Controllers
{
if (!ModelState.IsValid)
{
return View(viewModel);
return View("SignWithSeed", viewModel);
}
var network = NetworkProvider.GetNetwork<BTCPayNetwork>(walletId.CryptoCode);
if (network == null)
@@ -666,7 +691,7 @@ namespace BTCPayServer.Controllers
if (!ModelState.IsValid)
{
return View(viewModel);
return View("SignWithSeed", viewModel);
}
ExtKey signingKey = null;
@@ -679,7 +704,7 @@ namespace BTCPayServer.Controllers
if (rootedKeyPath == null)
{
ModelState.AddModelError(nameof(viewModel.SeedOrKey), "The master fingerprint and/or account key path of your seed are not set in the wallet settings.");
return View(viewModel);
return View("SignWithSeed", viewModel);
}
// The user gave the root key, let's try to rebase the PSBT, and derive the account private key
if (rootedKeyPath.MasterFingerprint == extKey.GetPublicKey().GetHDFingerPrint())