@bwalletx/connect 0.5.3 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/README.md +4 -0
- package/dist/bwalletx-connect.global.js +8 -8
- package/dist/bwalletx-connect.global.js.map +1 -1
- package/dist/{chunk-IUDD7YTQ.js → chunk-EXRQJTXF.js} +91 -20
- package/dist/chunk-EXRQJTXF.js.map +1 -0
- package/dist/{chunk-PI42H3XY.js → chunk-RIOHG5JH.js} +4 -4
- package/dist/chunk-RIOHG5JH.js.map +1 -0
- package/dist/element.cjs +86 -18
- package/dist/element.cjs.map +1 -1
- package/dist/element.js +1 -1
- package/dist/index.cjs +97 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -7
- package/dist/index.d.ts +31 -7
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +90 -22
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +2 -2
- package/dist/shell-react.cjs.map +1 -1
- package/dist/shell-react.js.map +1 -1
- package/dist/{wallets-VOKIKBbO.d.cts → wallets-CbzMtxrf.d.cts} +1 -1
- package/dist/{wallets-VOKIKBbO.d.ts → wallets-CbzMtxrf.d.ts} +1 -1
- package/package.json +9 -10
- package/dist/chunk-IUDD7YTQ.js.map +0 -1
- package/dist/chunk-PI42H3XY.js.map +0 -1
package/dist/element.cjs
CHANGED
|
@@ -36,13 +36,16 @@ var import_sdk = require("@bsv/sdk");
|
|
|
36
36
|
var RDNS_EXTENSION = "com.bwalletx.extension";
|
|
37
37
|
var RDNS_MOBILE = "space.bwallet.mobile";
|
|
38
38
|
var BWALLETX_RDNS = [RDNS_EXTENSION, RDNS_MOBILE];
|
|
39
|
-
|
|
39
|
+
var DEFAULT_DISCOVER_MS = 300;
|
|
40
|
+
function discoverBwalletX(ms = DEFAULT_DISCOVER_MS) {
|
|
40
41
|
if (typeof window === "undefined") return Promise.resolve(null);
|
|
41
42
|
return new Promise((resolve) => {
|
|
42
43
|
let done = false;
|
|
44
|
+
let timer;
|
|
43
45
|
const finish = (r) => {
|
|
44
46
|
if (done) return;
|
|
45
47
|
done = true;
|
|
48
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
46
49
|
window.removeEventListener("brc100:announceWallet", onAnnounce);
|
|
47
50
|
resolve(r);
|
|
48
51
|
};
|
|
@@ -53,13 +56,21 @@ function discoverBwalletX(ms = 1200) {
|
|
|
53
56
|
finish({ wallet: d.wallet, method: rdns === RDNS_EXTENSION ? "extension" : "in-app", rdns });
|
|
54
57
|
}
|
|
55
58
|
};
|
|
59
|
+
const cwiNow = () => {
|
|
60
|
+
const cwi = window.CWI;
|
|
61
|
+
if (cwi) finish({ wallet: cwi, method: "in-app", rdns: null });
|
|
62
|
+
return !!cwi;
|
|
63
|
+
};
|
|
56
64
|
window.addEventListener("brc100:announceWallet", onAnnounce);
|
|
57
65
|
window.dispatchEvent(new Event("brc100:requestWallet"));
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
if (done || cwiNow()) return;
|
|
67
|
+
if (isFramed()) {
|
|
68
|
+
void probeXdm(Math.max(ms, 1200)).then((w) => finish(w ? { wallet: w, method: "in-app", rdns: null } : null));
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
timer = setTimeout(() => {
|
|
72
|
+
timer = void 0;
|
|
73
|
+
if (!cwiNow()) finish(null);
|
|
63
74
|
}, ms);
|
|
64
75
|
});
|
|
65
76
|
}
|
|
@@ -115,6 +126,21 @@ async function probeXdm(ms = 1200, allowed = BWALLETX_PARENT_ORIGINS) {
|
|
|
115
126
|
return null;
|
|
116
127
|
}
|
|
117
128
|
}
|
|
129
|
+
var warmedAt = 0;
|
|
130
|
+
function prewarmBwalletX() {
|
|
131
|
+
if (typeof window === "undefined" || Date.now() - warmedAt < 2e4) return;
|
|
132
|
+
warmedAt = Date.now();
|
|
133
|
+
void discoverBwalletX(0).then((f) => {
|
|
134
|
+
if (f && f.method === "extension") void f.wallet.isAuthenticated({}).catch(() => {
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
function bindPrewarm(el) {
|
|
139
|
+
const on = () => prewarmBwalletX();
|
|
140
|
+
const evs = ["pointerenter", "focus", "touchstart"];
|
|
141
|
+
for (const e of evs) el.addEventListener(e, on, { passive: true });
|
|
142
|
+
return () => evs.forEach((e) => el.removeEventListener(e, on));
|
|
143
|
+
}
|
|
118
144
|
|
|
119
145
|
// src/pair.ts
|
|
120
146
|
var import_sdk3 = require("@bsv/sdk");
|
|
@@ -155,10 +181,22 @@ function pairUrl(link) {
|
|
|
155
181
|
const q = new URLSearchParams({ v: link.v, r: link.r, c: link.c, k: link.k, o: link.o, e: String(link.e) });
|
|
156
182
|
return `https://${PAIR_HOST}/pair?${q}`;
|
|
157
183
|
}
|
|
158
|
-
var
|
|
184
|
+
var newClaim = () => b64url(crypto.getRandomValues(new Uint8Array(16)));
|
|
185
|
+
var WALLET_CLAIM_INFO = "bwallet-pair-wallet-claim-v1";
|
|
186
|
+
var hex = (b) => Array.from(b, (x) => x.toString(16).padStart(2, "0")).join("");
|
|
187
|
+
async function walletClaimFor(channel, sitePub) {
|
|
188
|
+
const d = await crypto.subtle.digest("SHA-256", enc.encode(`${WALLET_CLAIM_INFO}|${channel}|${sitePub}`));
|
|
189
|
+
return b64url(new Uint8Array(d));
|
|
190
|
+
}
|
|
191
|
+
async function claimDigest(claim) {
|
|
192
|
+
return hex(new Uint8Array(await crypto.subtle.digest("SHA-256", enc.encode(claim))));
|
|
193
|
+
}
|
|
194
|
+
var relaySocketUrl = (relay, channel, role, expiry, claim, walletClaimHash) => {
|
|
159
195
|
const local = /^(localhost|127\.0\.0\.1)(:\d+)?$/.test(relay);
|
|
160
196
|
const q = new URLSearchParams({ role });
|
|
161
197
|
if (expiry) q.set("e", String(expiry));
|
|
198
|
+
if (claim) q.set("claim", claim);
|
|
199
|
+
if (walletClaimHash && role === "site") q.set("wc", walletClaimHash);
|
|
162
200
|
return `${local ? "ws" : "wss"}://${relay}/v1/c/${channel}?${q}`;
|
|
163
201
|
};
|
|
164
202
|
async function deriveSession(mine, theirs, channel) {
|
|
@@ -256,6 +294,7 @@ function parseStored(raw) {
|
|
|
256
294
|
if (typeof p.s !== "string" || !/^[0-9a-f]{64}$/i.test(p.s)) return null;
|
|
257
295
|
if (typeof p.k !== "string" || !/^0[23][0-9a-f]{64}$/i.test(p.k)) return null;
|
|
258
296
|
if (!n(p.sent) || !n(p.lastSeen) || !n(p.pairedAt)) return null;
|
|
297
|
+
if (p.sc !== void 0 && (typeof p.sc !== "string" || !/^[A-Za-z0-9_-]{22,64}$/.test(p.sc))) return null;
|
|
259
298
|
return p;
|
|
260
299
|
} catch {
|
|
261
300
|
return null;
|
|
@@ -313,7 +352,12 @@ var Link = class {
|
|
|
313
352
|
await this.opening;
|
|
314
353
|
}
|
|
315
354
|
reopen() {
|
|
316
|
-
|
|
355
|
+
if (!this.p.sc) {
|
|
356
|
+
this.p = { ...this.p, sc: newClaim() };
|
|
357
|
+
this.persist();
|
|
358
|
+
}
|
|
359
|
+
const e = Math.floor(Date.now() / 1e3) + QR_LIFETIME_S - 10;
|
|
360
|
+
const ws = this.socket(relaySocketUrl(this.p.r, this.p.c, "site", e, this.p.sc));
|
|
317
361
|
return new Promise((resolve, reject) => {
|
|
318
362
|
ws.onopen = () => {
|
|
319
363
|
this.ws = ws;
|
|
@@ -407,11 +451,13 @@ function pairBwalletX(opts) {
|
|
|
407
451
|
const siteKey = import_sdk3.PrivateKey.fromRandom();
|
|
408
452
|
const channel = newChannel();
|
|
409
453
|
const expiry = Math.floor(Date.now() / 1e3) + QR_LIFETIME_S;
|
|
410
|
-
|
|
454
|
+
const siteClaim = newClaim();
|
|
455
|
+
const sitePub = siteKey.toPublicKey().toString();
|
|
456
|
+
return walletClaimFor(channel, sitePub).then(claimDigest).then((wc) => new Promise((resolve, reject) => {
|
|
411
457
|
if (opts.signal?.aborted) return reject(new Error("cancelled"));
|
|
412
458
|
let ws;
|
|
413
459
|
try {
|
|
414
|
-
ws = socket(relaySocketUrl(relay, channel, "site", expiry));
|
|
460
|
+
ws = socket(relaySocketUrl(relay, channel, "site", expiry, siteClaim, wc));
|
|
415
461
|
} catch (e) {
|
|
416
462
|
return reject(e);
|
|
417
463
|
}
|
|
@@ -450,7 +496,7 @@ function pairBwalletX(opts) {
|
|
|
450
496
|
if (msg.t === "ready") {
|
|
451
497
|
settled = true;
|
|
452
498
|
clearTimeout(timer);
|
|
453
|
-
const p = { v: 1, c: channel, r: relay, s: siteKey.toHex(), k: walletKey, ...sealer.counters, pairedAt: Date.now() };
|
|
499
|
+
const p = { v: 1, c: channel, r: relay, s: siteKey.toHex(), k: walletKey, ...sealer.counters, pairedAt: Date.now(), sc: siteClaim };
|
|
454
500
|
await Promise.resolve(storage.setItem(key, JSON.stringify(p))).catch(() => {
|
|
455
501
|
});
|
|
456
502
|
const link = new Link(p, sealer, storage, key, socket, opts.callTimeoutMs ?? 12e4);
|
|
@@ -460,8 +506,8 @@ function pairBwalletX(opts) {
|
|
|
460
506
|
fail(new Error("Pairing was declined in bWalletX"));
|
|
461
507
|
}
|
|
462
508
|
});
|
|
463
|
-
opts.onLink(pairUrl({ v: PAIR_VERSION, r: relay, c: channel, k:
|
|
464
|
-
});
|
|
509
|
+
opts.onLink(pairUrl({ v: PAIR_VERSION, r: relay, c: channel, k: sitePub, o: origin, e: expiry }));
|
|
510
|
+
}));
|
|
465
511
|
}
|
|
466
512
|
async function restorePairing(opts = {}) {
|
|
467
513
|
const storage = opts.storage === void 0 ? defaultStorage() : opts.storage ?? memoryStorage();
|
|
@@ -477,16 +523,33 @@ async function restorePairing(opts = {}) {
|
|
|
477
523
|
// src/signin.ts
|
|
478
524
|
var LOGIN_PROTOCOL = [2, "bwallet sign in"];
|
|
479
525
|
async function connectBwalletX(opts = {}) {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
526
|
+
const status = (s) => {
|
|
527
|
+
try {
|
|
528
|
+
opts.onStatus?.(s);
|
|
529
|
+
} catch {
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
if (opts.wallet) {
|
|
533
|
+
status("opening");
|
|
534
|
+
return { wallet: opts.wallet, method: "wallet" };
|
|
535
|
+
}
|
|
536
|
+
status("finding");
|
|
537
|
+
const found = await discoverBwalletX(opts.discoverMs ?? DEFAULT_DISCOVER_MS);
|
|
538
|
+
if (found) {
|
|
539
|
+
status("opening");
|
|
540
|
+
return { wallet: found.wallet, method: found.method };
|
|
541
|
+
}
|
|
483
542
|
if (opts.reusePairing !== false) {
|
|
484
543
|
const restored = await restorePairing(opts.pairing ?? {});
|
|
485
|
-
if (restored)
|
|
544
|
+
if (restored) {
|
|
545
|
+
status("opening");
|
|
546
|
+
return { wallet: restored, method: "pairing" };
|
|
547
|
+
}
|
|
486
548
|
}
|
|
487
549
|
if (!opts.pairing) {
|
|
488
550
|
throw Object.assign(new Error("bWalletX was not found in this browser"), { code: "NOT_FOUND" });
|
|
489
551
|
}
|
|
552
|
+
status("pairing");
|
|
490
553
|
return { wallet: await pairBwalletX(opts.pairing), method: "pairing" };
|
|
491
554
|
}
|
|
492
555
|
async function signInWithBwalletX(opts) {
|
|
@@ -494,6 +557,10 @@ async function signInWithBwalletX(opts) {
|
|
|
494
557
|
if (method !== "pairing") await wallet.waitForAuthentication({}).catch(() => {
|
|
495
558
|
});
|
|
496
559
|
const { publicKey: identityKey } = await atStage("identity", () => wallet.getPublicKey({ identityKey: true }));
|
|
560
|
+
try {
|
|
561
|
+
opts.onStatus?.("signing");
|
|
562
|
+
} catch {
|
|
563
|
+
}
|
|
497
564
|
const c = await atStage("challenge", () => opts.challenge(identityKey));
|
|
498
565
|
const { signature } = await atStage(
|
|
499
566
|
"signature",
|
|
@@ -851,6 +918,7 @@ function createClass() {
|
|
|
851
918
|
const nf = this.#notFound ? `<p class="nf" part="not-found" role="status">bWalletX wasn't found in this browser. <a href="${esc(getUrl)}" target="_blank" rel="noopener">Get ${brand}</a> or <a href="${esc(webUrl)}" target="_blank" rel="noopener">use the web wallet</a>.</p>` : "";
|
|
852
919
|
this.#root.innerHTML = `<style>${SIGNIN_CSS}</style><button type="button" part="button" aria-label="${esc(aria)}" title="${esc(subtitle ? `${text} (${subtitle})` : text)}"${disabled ? " disabled" : ""}${loading ? ' aria-busy="true"' : ""}><span class="mark" part="mark">${mark}</span>${label}</button>${loading ? '<span class="sr" role="status">Connecting to bWalletX\u2026</span>' : ""}${nf}`;
|
|
853
920
|
this.button.addEventListener("click", () => void this.#click());
|
|
921
|
+
bindPrewarm(this.button);
|
|
854
922
|
}
|
|
855
923
|
#emit(type, detail, cancelable = false) {
|
|
856
924
|
return this.dispatchEvent(new CustomEvent(type, { detail, bubbles: true, composed: true, cancelable }));
|
|
@@ -877,7 +945,7 @@ function createClass() {
|
|
|
877
945
|
this.#notFound = false;
|
|
878
946
|
this.#setBusy(true);
|
|
879
947
|
try {
|
|
880
|
-
const ms = Number(this.#attr("discover-ms")) ||
|
|
948
|
+
const ms = Number(this.#attr("discover-ms")) || DEFAULT_DISCOVER_MS;
|
|
881
949
|
const found = await discoverBwalletX(ms);
|
|
882
950
|
if (!found) {
|
|
883
951
|
this.#notFound = true;
|