mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-02 02:42:28 +00:00
feat(wallet): Bitcoin Connect NWC "Connect wallet" flow [LOCAL — flag ON, do not push as-is]
Phase 0+1 of docs/bitcoin-connect-plan.md (#61). Adds Alby's Bitcoin Connect as a one-tap NWC connect front-end that feeds bitvid's EXISTING wallet pipeline; manual URI entry stays as the backup. - Vendored: pinned @getalby/[email protected].3 bundled by scripts/build-bitcoin-connect.mjs → vendor/bitcoin-connect.bundle.min.js (esbuild, browser ESM). crypto-shim aliases the L402-only `import('crypto')` bitvid never calls. `npm run build:bitcoin-connect` rebuilds it. - Flag: FEATURE_BITCOIN_CONNECT wired like FEATURE_AUDIO_INGEST (instance-config → config → constants). - UI: a "Connect wallet" button in the Wallet Connect pane (hidden unless the flag is on); the manual URI field stays below as the backup. - Controller: ProfileWalletController.handleBitcoinConnect() lazy-imports the bundle (only on click — the ~700KB never touches the main bundle), inits NWC-only with least-privilege requestMethods and persistConnection:false, then on onConnected extracts provider.client.nostrWalletConnectUrl → the SAME validate→save path as the manual field → disconnect() so bitvid solely holds the spending secret. The URI is never logged. NOTE: config/instance-config.js FEATURE_BITCOIN_CONNECT is TRUE for local testing only. Reset to false (shipping default) before pushing/deploying. Local commit; not pushed, not deployed. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
6dd40ce330
commit
69e87c6e15
12 files changed
+1663
-3
No files matched your search
@@ -0,0 +1,51 @@
|
||||
// Bundles Alby's Bitcoin Connect into a single self-contained ESM file that
|
||||
// bitvid lazy-imports behind FEATURE_BITCOIN_CONNECT (docs/bitcoin-connect-plan.md).
|
||||
// Mirrors the floating-ui vendor step in build-beacon.mjs. Pinned via the exact
|
||||
// devDependency version in package.json.
|
||||
import { build } from "esbuild";
|
||||
import { mkdir, copyFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const entryPoint = path.join(repoRoot, "scripts/vendor/bitcoin-connect-entry.mjs");
|
||||
const vendorDir = path.join(repoRoot, "vendor");
|
||||
const outFile = path.join(vendorDir, "bitcoin-connect.bundle.min.js");
|
||||
const licenseSrc = path.join(
|
||||
repoRoot,
|
||||
"node_modules/@getalby/bitcoin-connect/LICENSE",
|
||||
);
|
||||
const licenseOut = path.join(vendorDir, "bitcoin-connect.LICENSE");
|
||||
|
||||
await mkdir(vendorDir, { recursive: true });
|
||||
|
||||
await build({
|
||||
bundle: true,
|
||||
entryPoints: [entryPoint],
|
||||
outfile: outFile,
|
||||
format: "esm",
|
||||
splitting: false,
|
||||
platform: "browser",
|
||||
target: ["es2020"],
|
||||
minify: true,
|
||||
sourcemap: false,
|
||||
define: {
|
||||
"process.env.NODE_ENV": '"production"',
|
||||
global: "globalThis",
|
||||
},
|
||||
// @getalby/lightning-tools lazily `import('crypto')` for L402 macaroons — a
|
||||
// path bitvid never calls. Alias it to a browser shim so the bundle resolves.
|
||||
alias: {
|
||||
crypto: path.join(repoRoot, "scripts/vendor/crypto-shim.mjs"),
|
||||
"node:crypto": path.join(repoRoot, "scripts/vendor/crypto-shim.mjs"),
|
||||
},
|
||||
logLevel: "info",
|
||||
});
|
||||
|
||||
try {
|
||||
await copyFile(licenseSrc, licenseOut);
|
||||
} catch (error) {
|
||||
console.warn("[build-bitcoin-connect] could not copy LICENSE:", error.message);
|
||||
}
|
||||
|
||||
console.log("[build-bitcoin-connect] wrote", path.relative(repoRoot, outFile));
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// Vendor entry for Alby's Bitcoin Connect (getalby/bitcoin-connect), bundled by
|
||||
// scripts/build-bitcoin-connect.mjs into vendor/bitcoin-connect.bundle.min.js so
|
||||
// bitvid can lazy-import it behind FEATURE_BITCOIN_CONNECT without a runtime CDN.
|
||||
//
|
||||
// Importing the package self-registers its web components (bc-modal, etc.), so a
|
||||
// single import both loads the API and boots the UI. We re-export only the small
|
||||
// surface ProfileWalletController needs. See docs/bitcoin-connect-plan.md.
|
||||
export {
|
||||
init,
|
||||
launchModal,
|
||||
closeModal,
|
||||
onConnected,
|
||||
onDisconnected,
|
||||
disconnect,
|
||||
getConnectorConfig,
|
||||
isConnected,
|
||||
} from "@getalby/bitcoin-connect";
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
// Minimal browser shim for node's `crypto`, aliased in when bundling Bitcoin
|
||||
// Connect (scripts/build-bitcoin-connect.mjs). The only place its deps reach for
|
||||
// `crypto` is @getalby/lightning-tools' L402 macaroon helpers via a lazy
|
||||
// `await import('crypto')` — a path bitvid's NWC connect/pay flow never calls.
|
||||
// timingSafeEqual is implemented properly; the L402-only createHmac is stubbed so
|
||||
// it fails loudly rather than silently misbehaving if ever reached.
|
||||
export function timingSafeEqual(a, b) {
|
||||
const ua = a instanceof Uint8Array ? a : new Uint8Array(a);
|
||||
const ub = b instanceof Uint8Array ? b : new Uint8Array(b);
|
||||
if (ua.length !== ub.length) {
|
||||
return false;
|
||||
}
|
||||
let diff = 0;
|
||||
for (let i = 0; i < ua.length; i += 1) {
|
||||
diff |= ua[i] ^ ub[i];
|
||||
}
|
||||
return diff === 0;
|
||||
}
|
||||
|
||||
export function createHmac() {
|
||||
throw new Error(
|
||||
"createHmac (L402 macaroons) is not available in the bitvid browser bundle",
|
||||
);
|
||||
}
|
||||
|
||||
export default { timingSafeEqual, createHmac };
|
||||
Reference in new issue
Block a user