btcpayserver/BTCPayServer/Views/Wallets/WalletReceive.cshtml
Andrew Camilleri 4176f3659b
Add QR code scan/show for PSBT + Import wallet via QR (#1931)
* Add PSBT QR code scan/show

This PR introduces support to show and read PSBTs in BC-UR format via animated QR codes.  This allows you to use BTCPay with HW devices such as Cobo Vault and Blue wallet to sign transactions without ever exposing the keys outside of that device.
Spec: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md
I've also bumped the QR code library we sue as it had a bug with large datasets.

* Reuse same code for all and allow wallet import via QR code scan

* remove unecessary js vendor files

* Allow export wallet from settings via QR

* formatting

* bundle

* fix wallet receive bundle
2020-10-21 14:03:11 +02:00

142 lines
5.5 KiB
Plaintext

@addTagHelper *, BundlerMinifier.TagHelpers
@model BTCPayServer.Controllers.WalletReceiveViewModel
@{
Layout = "../Shared/_NavLayout.cshtml";
ViewData["Title"] = "Manage wallet";
ViewData.SetActivePageAndTitle(WalletsNavPages.Receive);
}
@if (TempData.HasStatusMessage())
{
<div class="row">
<div class="col-md-12 text-center">
<partial name="_StatusMessage" />
</div>
</div>
}
<div class="row no-gutters">
<div class="col-lg-8 mx-auto my-auto">
<form method="post" asp-action="WalletReceive" class="card text-center">
<div class="card-body">
@if (string.IsNullOrEmpty(Model.Address))
{
<h3 class="card-title mb-3">Receive @Model.CryptoCode</h3>
<button id="generateButton" class="btn btn-lg btn-primary" type="submit" name="command" value="generate-new-address">Generate @Model.CryptoCode address</button>
}
else
{
<h3 class="card-title mb-4">Next available @Model.CryptoCode&nbsp;address</h3>
<noscript>
<div class="card-body m-sm-0 p-sm-0">
<div class="input-group">
<input type="text" class="form-control " readonly="readonly" asp-for="Address" id="address" />
<div class="input-group-append">
<span class="input-group-text fa fa-copy"> </span>
</div>
</div>
<div class="row mt-4">
<div class="col-12 col-sm-6">
<button type="submit" name="command" value="generate-new-address" class="btn btn-primary w-100">Generate another address</button>
</div>
<div class="col-12 col-sm-6 mt-4 mt-sm-0">
<button type="submit" name="command" value="unreserve-current-address" class="btn btn-secondary w-100">Unreserve this address</button>
</div>
</div>
</div>
</noscript>
<div class="only-for-js card-body m-sm-0 p-sm-0" id="app">
<div class="qr-container mb-4">
<img v-bind:src="srvModel.cryptoImage" class="qr-icon" />
<qrcode v-bind:value="srvModel.address" :options="{ width: 256, margin: 1, color: {dark:'#000', light:'#f5f5f7'} }" tag="svg">
</qrcode>
</div>
<div class="input-group copy" data-clipboard-target="#vue-address">
<input type="text" class=" form-control " readonly="readonly" :value="srvModel.address" id="vue-address" />
<div class="input-group-append">
<span class="input-group-text fa fa-copy"> </span>
</div>
</div>
<div class="row mt-4">
<div class="col-12 col-sm-6">
<button type="submit" name="command" value="generate-new-address" class="btn btn-primary w-100">Generate another address</button>
</div>
<div class="col-12 col-sm-6 mt-4 mt-sm-0">
<button type="submit" name="command" value="unreserve-current-address" class="btn btn-secondary w-100">Unreserve this address</button>
</div>
</div>
</div>
}
</div>
</form>
</div>
</div>
@section HeadScripts
{
<bundle name="wwwroot/bundles/lightning-node-info-bundle.min.js" asp-append-version="true" />
<script type="text/javascript">
var srvModel = @Safe.Json(Model);
window.onload = function() {
if($("#app").length <1){
return;
}
Vue.use(Toasted);
var app = new Vue({
el: '#app',
components: {
qrcode: VueQrcode
},
data: {
srvModel: srvModel
},
mounted: function() {
this.$nextTick(function() {
var copyInput = new Clipboard('.copy');
copyInput.on("success",
function(e) {
Vue.toasted.show('Copied',
{
iconPack: "fontawesome",
icon: "copy",
duration: 5000
});
});
});
}
});
}
</script>
<style>
.qr-icon {
height: 64px;
width: 64px;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
.qr-container {
position: relative;
text-align: center;
}
.qr-container svg {
width: 256px;
height: 256px;
}
.copy {
cursor: copy;
}
</style>
}