From d5e55c9c577feb6f8000bad3c37045a2cd7c9b4c Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Tue, 23 Jun 2026 23:05:52 -0700 Subject: Add QR scanner to the send page (lazy-loaded decoder) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scan a Bitcoin address, a BIP21 URI (fills address + amount), or a signed-transaction QR (opens a broadcast confirmation, then relays it) from a viewfinder button on the Send form. Decoder strategy keeps the main bundle small: - Prefer the native BarcodeDetector (Chrome desktop/Android) — no lib. - Otherwise lazy-load jsQR from a separate dist/jsqr.js, only when the scanner is opened. jsQR stays out of index.html (~424 KB vs ~551 KB) and off the initial load. - The service worker precaches jsqr.js so offline scanning works for installed PWAs on browsers without BarcodeDetector. The scanner needs a camera + secure context, so it never shows on a standalone file:// page; offline air-gapped signing is unaffected. Co-Authored-By: Claude Opus 4.8 (1M context) --- dev.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'dev.js') diff --git a/dev.js b/dev.js index 099069c..dde8813 100644 --- a/dev.js +++ b/dev.js @@ -1,14 +1,19 @@ // Dev server: rebuilds the inlined bundle on every request so you just refresh // the browser to see changes. Same output as `bun run build`, unminified. -import { buildHtml } from './build.js'; +import { buildHtml, buildJsQr } from './build.js'; const port = Number(process.env.PORT || 5173); Bun.serve({ port, - async fetch() { + async fetch(req) { try { + if (new URL(req.url).pathname === '/jsqr.js') { + return new Response(await buildJsQr({ minify: false }), { + headers: { 'content-type': 'text/javascript; charset=utf-8' }, + }); + } const html = await buildHtml({ minify: false }); return new Response(html, { headers: { 'content-type': 'text/html; charset=utf-8' }, -- cgit v1.2.3