mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-22 14:22:40 +01:00
Allow import of coldcard wallet
This commit is contained in:
parent
0b6dfe0fd3
commit
538eb66672
5 changed files with 105 additions and 27 deletions
|
@ -1,12 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Models;
|
||||
using BTCPayServer.Models.StoreViewModels;
|
||||
using BTCPayServer.Payments;
|
||||
using BTCPayServer.Services;
|
||||
|
@ -111,10 +113,13 @@ namespace BTCPayServer.Controllers
|
|||
.FirstOrDefault(d => d.PaymentId == id);
|
||||
return existing;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpPost]
|
||||
[Route("{storeId}/derivations/{cryptoCode}")]
|
||||
public async Task<IActionResult> AddDerivationScheme(string storeId, DerivationSchemeViewModel vm, string cryptoCode)
|
||||
public async Task<IActionResult> AddDerivationScheme(string storeId, DerivationSchemeViewModel vm,
|
||||
string cryptoCode)
|
||||
{
|
||||
vm.CryptoCode = cryptoCode;
|
||||
var store = HttpContext.GetStoreData();
|
||||
|
@ -126,45 +131,70 @@ namespace BTCPayServer.Controllers
|
|||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
vm.RootKeyPath = network.GetRootKeyPath();
|
||||
DerivationSchemeSettings strategy = null;
|
||||
|
||||
PaymentMethodId paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike);
|
||||
var exisingStrategy = store.GetSupportedPaymentMethods(_NetworkProvider)
|
||||
.Where(c => c.PaymentId == paymentMethodId)
|
||||
.OfType<DerivationSchemeSettings>()
|
||||
.Select(c => c.AccountDerivation.ToString())
|
||||
.FirstOrDefault();
|
||||
|
||||
var wallet = _WalletProvider.GetWallet(network);
|
||||
if (wallet == null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
PaymentMethodId paymentMethodId = new PaymentMethodId(network.CryptoCode, PaymentTypes.BTCLike);
|
||||
var exisingStrategy = store.GetSupportedPaymentMethods(_NetworkProvider)
|
||||
.Where(c => c.PaymentId == paymentMethodId)
|
||||
.OfType<DerivationSchemeSettings>()
|
||||
.Select(c => c.AccountDerivation.ToString())
|
||||
.FirstOrDefault();
|
||||
DerivationSchemeSettings strategy = null;
|
||||
try
|
||||
if (vm.ColdcardPublicFile != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(vm.DerivationScheme))
|
||||
using (var stream = new StreamReader(vm.ColdcardPublicFile.OpenReadStream()))
|
||||
{
|
||||
strategy = ParseDerivationStrategy(vm.DerivationScheme, null, network);
|
||||
vm.DerivationScheme = strategy.ToString();
|
||||
var fileContent = await stream.ReadToEndAsync();
|
||||
if (
|
||||
!DerivationSchemeSettings.TryParseFromColdcard(fileContent, network, out strategy))
|
||||
{
|
||||
vm.StatusMessage = new StatusMessageModel()
|
||||
{
|
||||
Severity = StatusMessageModel.StatusSeverity.Error,
|
||||
Message = "Coldcard public file was not in the correct format"
|
||||
}.ToString();
|
||||
vm.Confirmation = false;
|
||||
return View(vm);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
else
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.DerivationScheme), "Invalid Derivation Scheme");
|
||||
vm.Confirmation = false;
|
||||
return View(vm);
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(vm.DerivationScheme))
|
||||
{
|
||||
strategy = ParseDerivationStrategy(vm.DerivationScheme, null, network);
|
||||
vm.DerivationScheme = strategy.ToString();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
ModelState.AddModelError(nameof(vm.DerivationScheme), "Invalid Derivation Scheme");
|
||||
vm.Confirmation = false;
|
||||
return View(vm);
|
||||
}
|
||||
}
|
||||
|
||||
var storeBlob = store.GetStoreBlob();
|
||||
var wasExcluded = storeBlob.GetExcludedPaymentMethods().Match(paymentMethodId);
|
||||
var willBeExcluded = !vm.Enabled;
|
||||
|
||||
var showAddress = // Show addresses if:
|
||||
// - If the user is testing the hint address in confirmation screen
|
||||
(vm.Confirmation && !string.IsNullOrWhiteSpace(vm.HintAddress)) ||
|
||||
// - The user is setting a new derivation scheme
|
||||
(!vm.Confirmation && strategy != null && exisingStrategy != strategy.AccountDerivation.ToString()) ||
|
||||
// - The user is clicking on continue without changing anything
|
||||
(!vm.Confirmation && willBeExcluded == wasExcluded);
|
||||
// - If the user is testing the hint address in confirmation screen
|
||||
(vm.Confirmation && !string.IsNullOrWhiteSpace(vm.HintAddress)) ||
|
||||
// - The user is setting a new derivation scheme
|
||||
(!vm.Confirmation && strategy != null && exisingStrategy != strategy.AccountDerivation.ToString()) ||
|
||||
// - The user is clicking on continue without changing anything
|
||||
(!vm.Confirmation && willBeExcluded == wasExcluded);
|
||||
|
||||
showAddress = showAddress && strategy != null;
|
||||
if (!showAddress)
|
||||
|
@ -186,7 +216,7 @@ namespace BTCPayServer.Controllers
|
|||
|
||||
await _Repo.UpdateStore(store);
|
||||
StatusMessage = $"Derivation scheme for {network.CryptoCode} has been modified.";
|
||||
return RedirectToAction(nameof(UpdateStore), new { storeId = storeId });
|
||||
return RedirectToAction(nameof(UpdateStore), new {storeId = storeId});
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(vm.HintAddress))
|
||||
{
|
||||
|
@ -210,13 +240,17 @@ namespace BTCPayServer.Controllers
|
|||
ModelState.AddModelError(nameof(vm.HintAddress), "Impossible to find a match with this address");
|
||||
return ShowAddresses(vm, strategy);
|
||||
}
|
||||
|
||||
vm.HintAddress = "";
|
||||
vm.StatusMessage = "Address successfully found, please verify that the rest is correct and click on \"Confirm\"";
|
||||
vm.StatusMessage =
|
||||
"Address successfully found, please verify that the rest is correct and click on \"Confirm\"";
|
||||
ModelState.Remove(nameof(vm.HintAddress));
|
||||
ModelState.Remove(nameof(vm.DerivationScheme));
|
||||
}
|
||||
|
||||
return ShowAddresses(vm, strategy);
|
||||
}
|
||||
|
||||
|
||||
private IActionResult ShowAddresses(DerivationSchemeViewModel vm, DerivationSchemeSettings strategy)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using NBitcoin;
|
||||
|
||||
|
@ -32,5 +33,8 @@ namespace BTCPayServer.Models.StoreViewModels
|
|||
|
||||
public string StatusMessage { get; internal set; }
|
||||
public KeyPath RootKeyPath { get; set; }
|
||||
|
||||
[Display(Name = "Coldcard Wallet File")]
|
||||
public IFormFile ColdcardPublicFile{ get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,33 @@
|
|||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
|
||||
<div class="modal fade" id="coldcardimport" tabindex="-1" role="dialog" aria-labelledby="coldcardimport" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<form class="modal-content" form method="post" enctype="multipart/form-data">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="exampleModalLabel">Import Coldcard Wallet</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>You may import your Coldcard wallet by exporting the public details from <kbd>Advanced->MicroSD Card->Electrum Wallet</kbd> and uploading it here.</p>
|
||||
<div class="form-group">
|
||||
<label asp-for="ColdcardPublicFile"></label>
|
||||
|
||||
<input type="file" class="form-control-file" asp-for="ColdcardPublicFile" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="post">
|
||||
@if (!Model.Confirmation)
|
||||
{
|
||||
|
@ -36,9 +63,12 @@
|
|||
<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.
|
||||
</p>
|
||||
<div id="ledger-info" class="form-text text-muted" style="display: none;">
|
||||
<div id="ledger-info" class="form-text text-muted display-when-ledger-connected" >
|
||||
<span>A ledger wallet is detected, which account do you want to use? No need to paste manually xpub if your ledger device was detected. Just select derivation scheme from the list bellow and xpub will automatically populate.</span>
|
||||
<div class="dropdown">
|
||||
|
||||
</div>
|
||||
<div class="d-flex">
|
||||
<div class="dropdown display-when-ledger-connected mr-2">
|
||||
<button class="btn btn-primary dropdown-toggle" type="button" id="ledgerAccountsDropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Select ledger wallet account
|
||||
</button>
|
||||
|
@ -49,7 +79,13 @@
|
|||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#coldcardimport">
|
||||
Import Coldcard wallet
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<span>BTCPay format memo</span>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
$("#ledger-loading").css("display", id === "ledger-loading" ? "block" : "none");
|
||||
$("#no-ledger-info").css("display", id === "no-ledger-info" ? "block" : "none");
|
||||
$("#ledger-validate").css("display", id === "ledger-validate" ? "block" : "none");
|
||||
$("#ledger-info").css("display", id === "ledger-info" ? "block" : "none");
|
||||
$(".display-when-ledger-connected").css("display", id === "ledger-info" ? "block" : "none");
|
||||
}
|
||||
function Write(prefix, type, message) {
|
||||
if (type === "error") {
|
||||
|
|
|
@ -19,3 +19,7 @@
|
|||
.only-for-js, .input-group-clear{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.display-when-ledger-connected{
|
||||
display: none;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue