mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2026-01-28 18:34:27 +01:00
Support bbqr psbts (#5852)
* Support bbqr psbts https://bbqr.org/ @nvk * add js test for bbqr
This commit is contained in:
@@ -494,6 +494,10 @@ retry:
|
||||
version = Regex.Match(actual, "Original file: /npm/decimal\\.js@([0-9]+.[0-9]+.[0-9]+)/decimal\\.js").Groups[1].Value;
|
||||
expected = (await (await client.GetAsync($"https://cdn.jsdelivr.net/npm/decimal.js@{version}/decimal.min.js")).Content.ReadAsStringAsync()).Trim();
|
||||
EqualJsContent(expected, actual);
|
||||
|
||||
actual = GetFileContent("BTCPayServer", "wwwroot", "vendor", "bbqr", "bbqr.iife.js").Trim();
|
||||
expected = (await (await client.GetAsync($"https://cdn.jsdelivr.net/npm/bbqr@1.0.0/dist/bbqr.iife.js")).Content.ReadAsStringAsync()).Trim();
|
||||
EqualJsContent(expected, actual);
|
||||
}
|
||||
|
||||
private void EqualJsContent(string expected, string actual)
|
||||
|
||||
@@ -51,6 +51,12 @@
|
||||
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" :style="{width: `${decoder.getProgress() * 100}%`}" id="progressbar"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="bbqrDecoder">
|
||||
<div class="my-3">BBQR: {{bbqrDecoder.total}} parts, {{bbqrDecoder.progress * 100}}% completed</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" :style="{width: `${bbqrDecoder.progress * 100}%`}" id="progressbar"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3 text-center">
|
||||
<button type="button" class="btn btn-primary me-1" v-if="qrData" v-on:click="submitData">Submit</button>
|
||||
<button type="button" class="btn btn-secondary me-1" v-if="qrData" v-on:click="retry">Retry</button>
|
||||
@@ -85,6 +91,7 @@ function initCameraScanningApp(title, onDataSubmit, modalId, submitOnScan = fals
|
||||
noStreamApiSupport: false,
|
||||
qrData: null,
|
||||
decoder: null,
|
||||
bbqrDecoder: null,
|
||||
errorMessage: null,
|
||||
successMessage: null,
|
||||
camera: 0,
|
||||
@@ -135,6 +142,7 @@ function initCameraScanningApp(title, onDataSubmit, modalId, submitOnScan = fals
|
||||
this.successMessage = null;
|
||||
this.errorMessage = null;
|
||||
this.decoder = null;
|
||||
this.bbqrDecoder = null;
|
||||
},
|
||||
close() {
|
||||
if (this.modalId) {
|
||||
@@ -146,12 +154,51 @@ function initCameraScanningApp(title, onDataSubmit, modalId, submitOnScan = fals
|
||||
onDecode(content) {
|
||||
if (this.qrData) return;
|
||||
const isUR = content.toLowerCase().startsWith("ur:");
|
||||
console.debug(1, content);
|
||||
|
||||
const isBBQr = content.startsWith("B$");
|
||||
console.debug(content);
|
||||
try {
|
||||
if (!isUR) {
|
||||
if (isBBQr){
|
||||
this.decoder = null;
|
||||
const total = parseInt(content.substr(4, 2), 36);
|
||||
const current = parseInt(content.substr(6, 2), 36);
|
||||
const format = content.substr(2,1);
|
||||
const type = content.substr(3, 1);
|
||||
|
||||
if (!this.bbqrDecoder ||
|
||||
this.bbqrDecoder.total !== total ||
|
||||
this.bbqrDecoder.format !== format ||
|
||||
this.bbqrDecoder.type !== type) {
|
||||
this.bbqrDecoder = {
|
||||
total,
|
||||
format,
|
||||
type,
|
||||
data: new Array(total),
|
||||
progress: 1/total
|
||||
};
|
||||
}
|
||||
this.bbqrDecoder.data[current] = content;
|
||||
|
||||
const progress = this.bbqrDecoder.data.filter(value => value !== undefined).length / total;
|
||||
this.bbqrDecoder.progress = progress;
|
||||
if (progress >= 1) {
|
||||
try {
|
||||
const joinResult = BBQr.joinQRs(this.bbqrDecoder.data);
|
||||
function buf2hex(buffer) { // buffer is an ArrayBuffer
|
||||
return [...new Uint8Array(buffer)]
|
||||
.map(x => x.toString(16).padStart(2, '0'))
|
||||
.join('');
|
||||
}
|
||||
const result = buf2hex(joinResult.raw);
|
||||
this.setQrData(result);
|
||||
this.successMessage = `BBQr ${type} decoded`;
|
||||
}catch (error){
|
||||
this.errorMessage = error.message;
|
||||
}
|
||||
}
|
||||
} else if (!isUR) {
|
||||
this.setQrData(content);
|
||||
} else {
|
||||
this.bbqrDecoder = null;
|
||||
this.decoder = this.decoder || new window.URlib.URRegistryDecoder();
|
||||
if (this.decoder.receivePart(content)) {
|
||||
if (this.decoder.isComplete()) {
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
<script src="~/vendor/vuejs/vue.min.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/vue-qrcode/vue-qrcode.min.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/ur-registry/urlib.min.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/bbqr/bbqr.iife.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/vue-qrcode-reader/VueQrcodeReader.umd.min.js" asp-append-version="true"></script>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
<script src="~/vendor/vuejs/vue.min.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/vue-qrcode/vue-qrcode.min.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/ur-registry/urlib.min.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/bbqr/bbqr.iife.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/vue-qrcode-reader/VueQrcodeReader.umd.min.js" asp-append-version="true"></script>
|
||||
|
||||
<script>
|
||||
@@ -39,9 +40,12 @@
|
||||
const buffer = new window.URlib.Buffer.from(psbtHex, "hex");
|
||||
const cryptoPSBT = new window.URlib.CryptoPSBT(buffer);
|
||||
const encoder = cryptoPSBT.toUREncoder();
|
||||
const bbqrSplitResult = BBQr.splitQRs(buffer, 'P', { maxVersion: 10});
|
||||
|
||||
const modes = {
|
||||
ur: { title: "UR", fragments: encoder.encodeWhole() },
|
||||
static: { title: "Static", fragments: [psbtHex] }
|
||||
static: { title: "Static", fragments: [psbtHex] },
|
||||
bbqr: { title: "BBQr", fragments: bbqrSplitResult.parts}
|
||||
};
|
||||
initQRShow({ title: "Scan the PSBT", modes });
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<script src="~/vendor/vuejs/vue.min.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/vue-qrcode/vue-qrcode.min.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/ur-registry/urlib.min.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/bbqr/bbqr.iife.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/vue-qrcode-reader/VueQrcodeReader.umd.min.js" asp-append-version="true"></script>
|
||||
|
||||
<script>
|
||||
@@ -39,9 +40,11 @@
|
||||
const buffer = new window.URlib.Buffer.from(psbtHex, "hex");
|
||||
const cryptoPSBT = new window.URlib.CryptoPSBT(buffer);
|
||||
const encoder = cryptoPSBT.toUREncoder();
|
||||
const bbqrSplitResult = BBQr.splitQRs(buffer, 'P', { maxVersion: 10});
|
||||
const modes = {
|
||||
ur: { title: "UR", fragments: encoder.encodeWhole() },
|
||||
static: { title: "Static", fragments: [psbtHex] }
|
||||
static: { title: "Static", fragments: [psbtHex] },
|
||||
bbqr: { title: "BBQr", fragments: bbqrSplitResult.parts}
|
||||
};
|
||||
const continueCallback = () => {
|
||||
document.querySelector("#PSBTOptionsImportHeader button").click()
|
||||
|
||||
8
BTCPayServer/wwwroot/vendor/bbqr/bbqr.iife.js
vendored
Normal file
8
BTCPayServer/wwwroot/vendor/bbqr/bbqr.iife.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user