@bwalletx/connect 0.4.1 → 0.5.3
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 +20 -0
- package/README.md +6 -2
- package/assets/protocol/401.jpg +0 -0
- package/assets/protocol/401.mp4 +0 -0
- package/assets/protocol/402.jpg +0 -0
- package/assets/protocol/402.mp4 +0 -0
- package/assets/protocol/403.jpg +0 -0
- package/assets/protocol/403.mp4 +0 -0
- package/dist/access-Dp0eKIOc.d.cts +118 -0
- package/dist/access-Dp0eKIOc.d.ts +118 -0
- package/dist/bwalletx-connect.global.js +20 -17
- package/dist/bwalletx-connect.global.js.map +1 -1
- package/dist/{chunk-NNMUSWPG.js → chunk-IUDD7YTQ.js} +200 -10
- package/dist/chunk-IUDD7YTQ.js.map +1 -0
- package/dist/chunk-MWD4BCO5.js +182 -0
- package/dist/chunk-MWD4BCO5.js.map +1 -0
- package/dist/{chunk-FUQ46RJV.js → chunk-PI42H3XY.js} +65 -10
- package/dist/chunk-PI42H3XY.js.map +1 -0
- package/dist/{chunk-7NAKOJGZ.js → chunk-QRXFL66W.js} +220 -10
- package/dist/chunk-QRXFL66W.js.map +1 -0
- package/dist/element.cjs +290 -14
- package/dist/element.cjs.map +1 -1
- package/dist/element.js +2 -1
- package/dist/element.js.map +1 -1
- package/dist/index.cjs +437 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +71 -1
- package/dist/index.d.ts +71 -1
- package/dist/index.js +36 -4
- package/dist/index.js.map +1 -1
- package/dist/next.cjs +377 -9
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +52 -2
- package/dist/next.d.ts +52 -2
- package/dist/next.js +92 -1
- package/dist/next.js.map +1 -1
- package/dist/react.cjs +561 -226
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +5 -0
- package/dist/react.d.ts +5 -0
- package/dist/react.js +12 -3
- package/dist/react.js.map +1 -1
- package/dist/server.cjs +406 -9
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +111 -1
- package/dist/server.d.ts +111 -1
- package/dist/server.js +47 -1
- package/package.json +12 -11
- package/dist/chunk-7NAKOJGZ.js.map +0 -1
- package/dist/chunk-FUQ46RJV.js.map +0 -1
- package/dist/chunk-NNMUSWPG.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -30,23 +30,32 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
|
+
ACCESS_ERROR_STATUS: () => ACCESS_ERROR_STATUS,
|
|
34
|
+
ACCESS_PROTOCOL: () => ACCESS_PROTOCOL,
|
|
35
|
+
ACCESS_VERSION: () => ACCESS_VERSION,
|
|
36
|
+
AccessError: () => AccessError,
|
|
33
37
|
BRC29_PROTOCOL: () => BRC29_PROTOCOL,
|
|
34
38
|
BWALLETX_RDNS: () => BWALLETX_RDNS,
|
|
35
39
|
GET_URL: () => GET_URL,
|
|
36
40
|
LOGIN_PROTOCOL: () => LOGIN_PROTOCOL,
|
|
37
41
|
LOGO_URL: () => LOGO_URL,
|
|
42
|
+
PROTOCOL_MEDIA: () => PROTOCOL_MEDIA,
|
|
38
43
|
PaymentError: () => PaymentError,
|
|
39
44
|
RDNS_EXTENSION: () => RDNS_EXTENSION,
|
|
40
45
|
RDNS_MOBILE: () => RDNS_MOBILE,
|
|
41
46
|
SIGNIN_CSS: () => SIGNIN_CSS,
|
|
42
47
|
SIGNIN_TAG: () => SIGNIN_TAG,
|
|
48
|
+
WALLET_THEME_META: () => WALLET_THEME_META,
|
|
43
49
|
WEB_WALLET_URL: () => WEB_WALLET_URL,
|
|
50
|
+
accessErrorMessage: () => accessErrorMessage,
|
|
44
51
|
amountInSats: () => amountInSats,
|
|
45
52
|
brc100Option: () => brc100Option,
|
|
46
53
|
buildAuthorizeUrl: () => buildAuthorizeUrl,
|
|
47
54
|
buyToken: () => buyToken,
|
|
55
|
+
canonicalJson: () => canonicalJson,
|
|
48
56
|
clearPairing: () => clearPairing,
|
|
49
57
|
connectBwalletX: () => connectBwalletX,
|
|
58
|
+
declareWalletTheme: () => declareWalletTheme,
|
|
50
59
|
defineBwalletxSignin: () => defineBwalletxSignin,
|
|
51
60
|
discoverBwalletX: () => discoverBwalletX,
|
|
52
61
|
discoverWallets: () => discoverWallets,
|
|
@@ -55,23 +64,30 @@ __export(src_exports, {
|
|
|
55
64
|
inOrder: () => inOrder,
|
|
56
65
|
isIdentityKeyHex: () => isIdentityKeyHex,
|
|
57
66
|
isPaymail: () => isPaymail,
|
|
67
|
+
isTouchDevice: () => isTouchDevice,
|
|
58
68
|
markSvg: () => markSvg,
|
|
59
69
|
pairBwalletX: () => pairBwalletX,
|
|
60
70
|
pairingModal: () => pairingModal,
|
|
61
71
|
pairingOption: () => pairingOption,
|
|
62
72
|
pay: () => pay,
|
|
63
73
|
pickWallet: () => pickWallet,
|
|
74
|
+
protocolMediaUrl: () => protocolMediaUrl,
|
|
75
|
+
proveHoldings: () => proveHoldings,
|
|
64
76
|
qrSvg: () => qrSvg,
|
|
65
77
|
renderButton: () => renderButton,
|
|
78
|
+
requestAccess: () => requestAccess,
|
|
66
79
|
resolvePaymailP2P: () => resolvePaymailP2P,
|
|
67
80
|
restorePairing: () => restorePairing,
|
|
68
81
|
signInWithBwalletX: () => signInWithBwalletX,
|
|
69
82
|
signinText: () => signinText,
|
|
70
|
-
|
|
83
|
+
throwIfAccessError: () => throwIfAccessError,
|
|
84
|
+
tip: () => tip,
|
|
85
|
+
toAccessError: () => toAccessError
|
|
71
86
|
});
|
|
72
87
|
module.exports = __toCommonJS(src_exports);
|
|
73
88
|
|
|
74
89
|
// src/discover.ts
|
|
90
|
+
var import_sdk = require("@bsv/sdk");
|
|
75
91
|
var RDNS_EXTENSION = "com.bwalletx.extension";
|
|
76
92
|
var RDNS_MOBILE = "space.bwallet.mobile";
|
|
77
93
|
var BWALLETX_RDNS = [RDNS_EXTENSION, RDNS_MOBILE];
|
|
@@ -96,16 +112,70 @@ function discoverBwalletX(ms = 1200) {
|
|
|
96
112
|
window.dispatchEvent(new Event("brc100:requestWallet"));
|
|
97
113
|
setTimeout(() => {
|
|
98
114
|
const cwi = window.CWI;
|
|
99
|
-
|
|
115
|
+
if (cwi) return finish({ wallet: cwi, method: "in-app", rdns: null });
|
|
116
|
+
if (!isFramed()) return finish(null);
|
|
117
|
+
void probeXdm(ms).then((w) => finish(w ? { wallet: w, method: "in-app", rdns: null } : null));
|
|
100
118
|
}, ms);
|
|
101
119
|
});
|
|
102
120
|
}
|
|
103
121
|
async function findBwalletX(ms = 1200) {
|
|
104
122
|
return (await discoverBwalletX(ms))?.wallet ?? null;
|
|
105
123
|
}
|
|
124
|
+
var isFramed = () => {
|
|
125
|
+
try {
|
|
126
|
+
return window.parent !== window;
|
|
127
|
+
} catch {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
var BWALLETX_PARENT_ORIGINS = [
|
|
132
|
+
"https://web.bwalletx.com",
|
|
133
|
+
"https://desktop.bwalletx.com",
|
|
134
|
+
"https://bwalletx.com",
|
|
135
|
+
"https://www.bwallet.space",
|
|
136
|
+
"https://bwallet.space",
|
|
137
|
+
"capacitor://localhost",
|
|
138
|
+
// iOS app shell
|
|
139
|
+
"https://localhost",
|
|
140
|
+
// Android app shell
|
|
141
|
+
"tauri://localhost",
|
|
142
|
+
// bWalletX Desktop (macOS)
|
|
143
|
+
"https://tauri.localhost",
|
|
144
|
+
// bWalletX Desktop (Windows)
|
|
145
|
+
"chrome-extension://bombmmcjghjdlbmcclnhjodgcelnehgl"
|
|
146
|
+
// bWalletX for Chrome (fixed id)
|
|
147
|
+
];
|
|
148
|
+
var parentOrigin = () => {
|
|
149
|
+
try {
|
|
150
|
+
const anc = window.location.ancestorOrigins;
|
|
151
|
+
if (anc && anc.length > 0) return anc[0] ?? null;
|
|
152
|
+
if (!document.referrer) return null;
|
|
153
|
+
const u = new URL(document.referrer);
|
|
154
|
+
return `${u.protocol}//${u.host}`;
|
|
155
|
+
} catch {
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
async function probeXdm(ms = 1200, allowed = BWALLETX_PARENT_ORIGINS) {
|
|
160
|
+
const origin = parentOrigin();
|
|
161
|
+
if (!origin || !allowed.includes(origin)) return null;
|
|
162
|
+
try {
|
|
163
|
+
const w = new import_sdk.WalletClient(new import_sdk.XDM(origin));
|
|
164
|
+
const ok = await Promise.race([
|
|
165
|
+
w.isAuthenticated({}).then(
|
|
166
|
+
() => true,
|
|
167
|
+
() => false
|
|
168
|
+
),
|
|
169
|
+
new Promise((r) => setTimeout(() => r(false), ms))
|
|
170
|
+
]);
|
|
171
|
+
return ok ? w : null;
|
|
172
|
+
} catch {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
106
176
|
|
|
107
177
|
// src/pair.ts
|
|
108
|
-
var
|
|
178
|
+
var import_sdk3 = require("@bsv/sdk");
|
|
109
179
|
|
|
110
180
|
// src/in-order.ts
|
|
111
181
|
function inOrder(handle, onError) {
|
|
@@ -117,7 +187,7 @@ function inOrder(handle, onError) {
|
|
|
117
187
|
}
|
|
118
188
|
|
|
119
189
|
// src/protocol.ts
|
|
120
|
-
var
|
|
190
|
+
var import_sdk2 = require("@bsv/sdk");
|
|
121
191
|
var PAIR_VERSION = "1";
|
|
122
192
|
var PAIR_INFO = "bwallet-pair-v1";
|
|
123
193
|
var PAIR_HOST = "www.bwallet.space";
|
|
@@ -150,7 +220,7 @@ var relaySocketUrl = (relay, channel, role, expiry) => {
|
|
|
150
220
|
return `${local ? "ws" : "wss"}://${relay}/v1/c/${channel}?${q}`;
|
|
151
221
|
};
|
|
152
222
|
async function deriveSession(mine, theirs, channel) {
|
|
153
|
-
const point = mine.deriveSharedSecret(
|
|
223
|
+
const point = mine.deriveSharedSecret(import_sdk2.PublicKey.fromString(theirs));
|
|
154
224
|
const ikm = new Uint8Array(point.encode(true));
|
|
155
225
|
const base = await crypto.subtle.importKey("raw", ikm, "HKDF", false, ["deriveBits"]);
|
|
156
226
|
const bits = new Uint8Array(
|
|
@@ -392,7 +462,7 @@ function pairBwalletX(opts) {
|
|
|
392
462
|
const relay = opts.relay ?? DEFAULT_RELAY;
|
|
393
463
|
const origin = opts.origin ?? (typeof location !== "undefined" ? location.origin : "");
|
|
394
464
|
if (!origin) return Promise.reject(new Error("pairBwalletX needs options.origin outside a browser"));
|
|
395
|
-
const siteKey =
|
|
465
|
+
const siteKey = import_sdk3.PrivateKey.fromRandom();
|
|
396
466
|
const channel = newChannel();
|
|
397
467
|
const expiry = Math.floor(Date.now() / 1e3) + QR_LIFETIME_S;
|
|
398
468
|
return new Promise((resolve, reject) => {
|
|
@@ -456,7 +526,7 @@ async function restorePairing(opts = {}) {
|
|
|
456
526
|
const key = opts.storageKey ?? DEFAULT_KEY;
|
|
457
527
|
const p = parseStored(await Promise.resolve(storage.getItem(key)).catch(() => null));
|
|
458
528
|
if (!p) return null;
|
|
459
|
-
const { key: aes } = await deriveSession(
|
|
529
|
+
const { key: aes } = await deriveSession(import_sdk3.PrivateKey.fromHex(p.s), p.k, p.c);
|
|
460
530
|
const sealer = new Sealer(aes, "site");
|
|
461
531
|
sealer.restore({ sent: p.sent, lastSeen: p.lastSeen });
|
|
462
532
|
return new Link(p, sealer, storage, key, opts.socket ?? defaultSocket(), opts.callTimeoutMs ?? 12e4).wallet();
|
|
@@ -486,16 +556,28 @@ async function signInWithBwalletX(opts) {
|
|
|
486
556
|
const { wallet, method } = await connectBwalletX(opts);
|
|
487
557
|
if (method !== "pairing") await wallet.waitForAuthentication({}).catch(() => {
|
|
488
558
|
});
|
|
489
|
-
const { publicKey: identityKey } = await wallet.getPublicKey({ identityKey: true });
|
|
490
|
-
const c = await opts.challenge(identityKey);
|
|
491
|
-
const { signature } = await
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
559
|
+
const { publicKey: identityKey } = await atStage("identity", () => wallet.getPublicKey({ identityKey: true }));
|
|
560
|
+
const c = await atStage("challenge", () => opts.challenge(identityKey));
|
|
561
|
+
const { signature } = await atStage(
|
|
562
|
+
"signature",
|
|
563
|
+
() => wallet.createSignature({
|
|
564
|
+
protocolID: c.protocolID ?? LOGIN_PROTOCOL,
|
|
565
|
+
keyID: c.keyID,
|
|
566
|
+
counterparty: "anyone",
|
|
567
|
+
data: Array.from(new TextEncoder().encode(c.message))
|
|
568
|
+
})
|
|
569
|
+
);
|
|
497
570
|
return { identityKey, signature: Array.from(signature), nonce: c.nonce, method, wallet };
|
|
498
571
|
}
|
|
572
|
+
async function atStage(stage, run) {
|
|
573
|
+
try {
|
|
574
|
+
return await run();
|
|
575
|
+
} catch (e) {
|
|
576
|
+
const err = e instanceof Error ? e : new Error(String(e));
|
|
577
|
+
if (!err.stage) Object.assign(err, { stage });
|
|
578
|
+
throw err;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
499
581
|
|
|
500
582
|
// src/button.ts
|
|
501
583
|
var CSS = `
|
|
@@ -541,6 +623,239 @@ function renderButton(el2, opts = {}) {
|
|
|
541
623
|
return b;
|
|
542
624
|
}
|
|
543
625
|
|
|
626
|
+
// src/access-client.ts
|
|
627
|
+
var import_sdk4 = require("@bsv/sdk");
|
|
628
|
+
|
|
629
|
+
// src/access.ts
|
|
630
|
+
var ACCESS_VERSION = 1;
|
|
631
|
+
var ACCESS_PROTOCOL = [2, "bwalletx access"];
|
|
632
|
+
var MAX_HOLDING_PROOFS = 50;
|
|
633
|
+
var ACCESS_ERROR_STATUS = {
|
|
634
|
+
not_installed: 424,
|
|
635
|
+
user_rejected: 403,
|
|
636
|
+
wrong_account: 409,
|
|
637
|
+
insufficient_tokens: 403,
|
|
638
|
+
identity_level_too_low: 403,
|
|
639
|
+
kyc_required: 403,
|
|
640
|
+
indexer_unavailable: 503,
|
|
641
|
+
expired: 401,
|
|
642
|
+
replay: 401,
|
|
643
|
+
invalid_signature: 401,
|
|
644
|
+
bad_request: 400
|
|
645
|
+
};
|
|
646
|
+
var AccessError = class extends Error {
|
|
647
|
+
code;
|
|
648
|
+
have;
|
|
649
|
+
need;
|
|
650
|
+
constructor(code, message, extra = {}) {
|
|
651
|
+
super(message ?? code);
|
|
652
|
+
this.name = "AccessError";
|
|
653
|
+
this.code = code;
|
|
654
|
+
this.have = extra.have;
|
|
655
|
+
this.need = extra.need;
|
|
656
|
+
}
|
|
657
|
+
toJSON() {
|
|
658
|
+
const b = { error: this.code, message: this.message };
|
|
659
|
+
if (this.have !== void 0) b.have = this.have;
|
|
660
|
+
if (this.need !== void 0) b.need = this.need;
|
|
661
|
+
return b;
|
|
662
|
+
}
|
|
663
|
+
};
|
|
664
|
+
var PROTOCOL_MEDIA = {
|
|
665
|
+
"401": { name: "Identity", color: "#22c55e", video: "assets/protocol/401.mp4", poster: "assets/protocol/401.jpg" },
|
|
666
|
+
"402": { name: "Payment", color: "#3b82f6", video: "assets/protocol/402.mp4", poster: "assets/protocol/402.jpg" },
|
|
667
|
+
"403": { name: "Access", color: "#ef4444", video: "assets/protocol/403.mp4", poster: "assets/protocol/403.jpg" }
|
|
668
|
+
};
|
|
669
|
+
function protocolMediaUrl(kind, which, version = "latest") {
|
|
670
|
+
return `https://unpkg.com/@bwalletx/connect@${version}/${PROTOCOL_MEDIA[kind][which]}`;
|
|
671
|
+
}
|
|
672
|
+
function canonicalJson(v) {
|
|
673
|
+
if (v === null) return "null";
|
|
674
|
+
if (typeof v === "string" || typeof v === "boolean") return JSON.stringify(v);
|
|
675
|
+
if (typeof v === "number") {
|
|
676
|
+
if (!Number.isFinite(v)) throw new Error("canonicalJson: non-finite number");
|
|
677
|
+
return JSON.stringify(v);
|
|
678
|
+
}
|
|
679
|
+
if (Array.isArray(v)) return `[${v.map((x) => canonicalJson(x)).join(",")}]`;
|
|
680
|
+
if (typeof v === "object") {
|
|
681
|
+
const o = v;
|
|
682
|
+
const keys = Object.keys(o).filter((k) => o[k] !== void 0).sort();
|
|
683
|
+
return `{${keys.map((k) => `${JSON.stringify(k)}:${canonicalJson(o[k])}`).join(",")}}`;
|
|
684
|
+
}
|
|
685
|
+
throw new Error(`canonicalJson: unsupported ${typeof v}`);
|
|
686
|
+
}
|
|
687
|
+
function challengeBytes(challenge) {
|
|
688
|
+
return Array.from(new TextEncoder().encode(challenge));
|
|
689
|
+
}
|
|
690
|
+
var TOKEN_ID = /^bsv21:[0-9a-f]{64}_\d{1,6}$/;
|
|
691
|
+
var RAW = /^[1-9]\d{0,38}$/;
|
|
692
|
+
function normaliseRequirement(r) {
|
|
693
|
+
if (!r || typeof r !== "object") throw new AccessError("bad_request", "require must be an object");
|
|
694
|
+
const req = r;
|
|
695
|
+
const out = {};
|
|
696
|
+
if (req.token !== void 0) {
|
|
697
|
+
const t = req.token;
|
|
698
|
+
if (!t || typeof t !== "object" || typeof t.id !== "string") throw new AccessError("bad_request", "require.token.id is required");
|
|
699
|
+
const id = t.id.trim().toLowerCase();
|
|
700
|
+
if (!TOKEN_ID.test(id)) throw new AccessError("bad_request", "require.token.id must be 'bsv21:<txid>_<vout>'");
|
|
701
|
+
const hasMin = t.min !== void 0;
|
|
702
|
+
const hasBps = t.minBps !== void 0;
|
|
703
|
+
if (hasMin === hasBps) throw new AccessError("bad_request", "require.token needs exactly one of min or minBps");
|
|
704
|
+
out.token = { id };
|
|
705
|
+
if (hasMin) {
|
|
706
|
+
if (typeof t.min !== "string" || !RAW.test(t.min)) throw new AccessError("bad_request", "require.token.min must be a positive integer string (raw units)");
|
|
707
|
+
out.token.min = t.min;
|
|
708
|
+
} else {
|
|
709
|
+
if (!Number.isInteger(t.minBps) || t.minBps < 1 || t.minBps > 1e4) {
|
|
710
|
+
throw new AccessError("bad_request", "require.token.minBps must be an integer 1..10000");
|
|
711
|
+
}
|
|
712
|
+
out.token.minBps = t.minBps;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
if (req.identityLevel !== void 0) {
|
|
716
|
+
if (!Number.isInteger(req.identityLevel) || req.identityLevel < 1 || req.identityLevel > 10) {
|
|
717
|
+
throw new AccessError("bad_request", "require.identityLevel must be an integer 1..10");
|
|
718
|
+
}
|
|
719
|
+
out.identityLevel = req.identityLevel;
|
|
720
|
+
}
|
|
721
|
+
if (req.kyc !== void 0) {
|
|
722
|
+
if (typeof req.kyc !== "boolean") throw new AccessError("bad_request", "require.kyc must be a boolean");
|
|
723
|
+
if (req.kyc) out.kyc = true;
|
|
724
|
+
}
|
|
725
|
+
if (!out.token && !out.identityLevel && !out.kyc) throw new AccessError("bad_request", "require is empty");
|
|
726
|
+
return out;
|
|
727
|
+
}
|
|
728
|
+
function parseAccessChallenge(s) {
|
|
729
|
+
if (typeof s !== "string" || s.length > 4096) throw new AccessError("bad_request", "challenge must be a string");
|
|
730
|
+
let c;
|
|
731
|
+
try {
|
|
732
|
+
c = JSON.parse(s);
|
|
733
|
+
} catch {
|
|
734
|
+
throw new AccessError("bad_request", "challenge is not JSON");
|
|
735
|
+
}
|
|
736
|
+
if (!c || typeof c !== "object" || c.v !== 1) throw new AccessError("bad_request", "unsupported challenge version");
|
|
737
|
+
if (c.kind !== "401" && c.kind !== "402" && c.kind !== "403") throw new AccessError("bad_request", "bad kind");
|
|
738
|
+
if (typeof c.origin !== "string" || typeof c.nonce !== "string" || !/^[A-Za-z0-9_-]{16,64}$/.test(c.nonce)) {
|
|
739
|
+
throw new AccessError("bad_request", "bad origin or nonce");
|
|
740
|
+
}
|
|
741
|
+
if (!Number.isInteger(c.iat) || !Number.isInteger(c.exp) || c.exp <= c.iat) throw new AccessError("bad_request", "bad iat/exp");
|
|
742
|
+
if (c.sub !== void 0 && (typeof c.sub !== "string" || !/^0[23][0-9a-f]{64}$/.test(c.sub))) throw new AccessError("bad_request", "bad sub");
|
|
743
|
+
c.require = normaliseRequirement(c.require);
|
|
744
|
+
if (canonicalJson(c) !== s) throw new AccessError("bad_request", "challenge is not canonical");
|
|
745
|
+
return c;
|
|
746
|
+
}
|
|
747
|
+
function accessErrorMessage(code, e = {}) {
|
|
748
|
+
switch (code) {
|
|
749
|
+
case "not_installed":
|
|
750
|
+
return "No bWalletX (or other BRC-100 wallet) was found.";
|
|
751
|
+
case "user_rejected":
|
|
752
|
+
return "The request was declined in the wallet.";
|
|
753
|
+
case "wrong_account":
|
|
754
|
+
return "The wallet is signed in to a different account than this site expects.";
|
|
755
|
+
case "insufficient_tokens":
|
|
756
|
+
return `Not enough tokens: holding ${e.have ?? 0}, need ${e.need ?? "?"}.`;
|
|
757
|
+
case "identity_level_too_low":
|
|
758
|
+
return `Identity level ${e.have ?? 0} is below the required level ${e.need ?? "?"}.`;
|
|
759
|
+
case "kyc_required":
|
|
760
|
+
return "A verified identity (KYC) is required.";
|
|
761
|
+
case "indexer_unavailable":
|
|
762
|
+
return "Holdings could not be checked right now. Try again shortly.";
|
|
763
|
+
case "expired":
|
|
764
|
+
return "The request expired. Try again.";
|
|
765
|
+
case "replay":
|
|
766
|
+
return "That request was already used. Try again.";
|
|
767
|
+
case "invalid_signature":
|
|
768
|
+
return "The wallet signature did not verify.";
|
|
769
|
+
case "bad_request":
|
|
770
|
+
return "The request was malformed.";
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// src/access-client.ts
|
|
775
|
+
var ONESAT = [0, "onesat"];
|
|
776
|
+
var LEGACY_ONESAT = [0, "p 1sat"];
|
|
777
|
+
function toAccessError(e) {
|
|
778
|
+
if (e instanceof AccessError) return e;
|
|
779
|
+
const err = e;
|
|
780
|
+
const msg = String(err?.message ?? e ?? "");
|
|
781
|
+
if (err?.code === "NOT_FOUND") return new AccessError("not_installed", msg);
|
|
782
|
+
if (/reject|denied|declin|cancel|user/i.test(msg) || err?.code === "ERR_USER_REJECTED" || err?.status === 4001) {
|
|
783
|
+
return new AccessError("user_rejected", msg);
|
|
784
|
+
}
|
|
785
|
+
return new AccessError("bad_request", msg || "access failed");
|
|
786
|
+
}
|
|
787
|
+
function throwIfAccessError(body) {
|
|
788
|
+
const b = body;
|
|
789
|
+
if (b && typeof b.error === "string") throw new AccessError(b.error, b.message, { have: b.have, need: b.need });
|
|
790
|
+
}
|
|
791
|
+
function hash160FromP2pkh(script) {
|
|
792
|
+
const m = /^76a914([0-9a-f]{40})88ac$/i.exec(script.slice(-50));
|
|
793
|
+
return m ? m[1].toLowerCase() : null;
|
|
794
|
+
}
|
|
795
|
+
async function proveHoldings(wallet, challenge, tokenId, basket = "bsv21") {
|
|
796
|
+
const bare = tokenId.replace(/^bsv21:/, "");
|
|
797
|
+
const list = await wallet.listOutputs({ basket, include: "locking scripts", includeCustomInstructions: true, limit: 1e4 });
|
|
798
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
799
|
+
const data = challengeBytes(challenge);
|
|
800
|
+
for (const out of list.outputs) {
|
|
801
|
+
if (byKey.size >= MAX_HOLDING_PROOFS) break;
|
|
802
|
+
let ci = {};
|
|
803
|
+
try {
|
|
804
|
+
ci = JSON.parse(out.customInstructions ?? "{}");
|
|
805
|
+
} catch {
|
|
806
|
+
continue;
|
|
807
|
+
}
|
|
808
|
+
if (ci.id !== bare || !ci.keyID) continue;
|
|
809
|
+
const want = out.lockingScript ? hash160FromP2pkh(out.lockingScript) : null;
|
|
810
|
+
const counterparty = ci.counterparty ?? "self";
|
|
811
|
+
for (const protocolID of ci.protocolID ? [ci.protocolID] : [ONESAT, LEGACY_ONESAT]) {
|
|
812
|
+
const { publicKey } = await wallet.getPublicKey({ protocolID, keyID: ci.keyID, counterparty });
|
|
813
|
+
const h = import_sdk4.Utils.toHex(import_sdk4.Hash.hash160(import_sdk4.PublicKey.fromString(publicKey).encode(true)));
|
|
814
|
+
if (want && h !== want) continue;
|
|
815
|
+
const existing = byKey.get(publicKey);
|
|
816
|
+
if (existing) {
|
|
817
|
+
existing.outpoints.push(out.outpoint.replace(".", "_"));
|
|
818
|
+
break;
|
|
819
|
+
}
|
|
820
|
+
const { signature } = await wallet.createSignature({ protocolID, keyID: ci.keyID, counterparty, data });
|
|
821
|
+
byKey.set(publicKey, { pubkey: publicKey, signature: Array.from(signature), outpoints: [out.outpoint.replace(".", "_")] });
|
|
822
|
+
break;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
return [...byKey.values()];
|
|
826
|
+
}
|
|
827
|
+
async function requestAccess(o) {
|
|
828
|
+
let wallet;
|
|
829
|
+
try {
|
|
830
|
+
({ wallet } = await connectBwalletX({ wallet: o.wallet, pairing: o.pairing, discoverMs: o.discoverMs }));
|
|
831
|
+
} catch (e) {
|
|
832
|
+
throw e?.code === "NOT_FOUND" ? new AccessError("not_installed") : toAccessError(e);
|
|
833
|
+
}
|
|
834
|
+
try {
|
|
835
|
+
const { publicKey: identityKey } = await wallet.getPublicKey({ identityKey: true });
|
|
836
|
+
const { challenge } = await o.challenge(identityKey);
|
|
837
|
+
const c = parseAccessChallenge(challenge);
|
|
838
|
+
if (c.sub && c.sub !== identityKey.toLowerCase()) throw new AccessError("wrong_account");
|
|
839
|
+
if (Date.now() / 1e3 >= c.exp) throw new AccessError("expired");
|
|
840
|
+
const { signature } = await wallet.createSignature({
|
|
841
|
+
protocolID: ACCESS_PROTOCOL,
|
|
842
|
+
keyID: c.nonce,
|
|
843
|
+
counterparty: "anyone",
|
|
844
|
+
data: challengeBytes(challenge)
|
|
845
|
+
});
|
|
846
|
+
const response = { v: 1, challenge, identityKey, signature: Array.from(signature) };
|
|
847
|
+
if (c.require.token) response.holdings = await proveHoldings(wallet, challenge, c.require.token.id, o.tokenBasket);
|
|
848
|
+
let verified;
|
|
849
|
+
if (o.verify) {
|
|
850
|
+
verified = await o.verify(response);
|
|
851
|
+
throwIfAccessError(verified);
|
|
852
|
+
}
|
|
853
|
+
return { response, verified, wallet };
|
|
854
|
+
} catch (e) {
|
|
855
|
+
throw toAccessError(e);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
|
|
544
859
|
// src/element.ts
|
|
545
860
|
var SIGNIN_TAG = "bwalletx-signin";
|
|
546
861
|
var GET_URL = "https://bwalletx.com/get";
|
|
@@ -636,6 +951,10 @@ async function postJson(url, body) {
|
|
|
636
951
|
if (!res.ok) throw new Error(data.error ?? `HTTP ${res.status}`);
|
|
637
952
|
return data;
|
|
638
953
|
}
|
|
954
|
+
async function postAccess(url, body) {
|
|
955
|
+
const res = await fetch(url, { method: "POST", credentials: "include", headers: { "content-type": "application/json" }, body: JSON.stringify(body) });
|
|
956
|
+
return res.json().catch(() => ({ error: "bad_request", message: `HTTP ${res.status}` }));
|
|
957
|
+
}
|
|
639
958
|
var OBSERVED = ["size", "theme", "label", "brand", "subtitle", "loading", "disabled", "full-width", "aria-label", "get-url", "web-url"];
|
|
640
959
|
function createClass() {
|
|
641
960
|
return class BwalletxSigninElement extends HTMLElement {
|
|
@@ -718,6 +1037,26 @@ function createClass() {
|
|
|
718
1037
|
if (!found) {
|
|
719
1038
|
this.#notFound = true;
|
|
720
1039
|
this.#emit("bwalletx-not-found");
|
|
1040
|
+
if (this.#attr("require-token")) this.#emit("bwalletx-access-denied", { code: "not_installed", message: "No wallet found" });
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1043
|
+
const requireToken = this.#attr("require-token");
|
|
1044
|
+
if (requireToken) {
|
|
1045
|
+
const verifyUrl2 = this.#attr("verify-url");
|
|
1046
|
+
const min = this.#attr("min");
|
|
1047
|
+
const minBps = this.#attr("min-bps");
|
|
1048
|
+
const hint = { token: { id: requireToken, ...minBps ? { minBps: Number(minBps) } : { min: min ?? "1" } } };
|
|
1049
|
+
try {
|
|
1050
|
+
const a = await requestAccess({
|
|
1051
|
+
wallet: found.wallet,
|
|
1052
|
+
challenge: (identityKey) => postJson(challengeUrl, { identityKey, require: hint }),
|
|
1053
|
+
verify: verifyUrl2 ? (response2) => postAccess(verifyUrl2, response2) : void 0
|
|
1054
|
+
});
|
|
1055
|
+
this.#emit("bwalletx-access-granted", { identityKey: a.response.identityKey, response: a.verified });
|
|
1056
|
+
} catch (e) {
|
|
1057
|
+
const err = e instanceof AccessError ? e : new AccessError("bad_request", String(e));
|
|
1058
|
+
this.#emit("bwalletx-access-denied", { code: err.code, message: err.message, have: err.have, need: err.need });
|
|
1059
|
+
}
|
|
721
1060
|
return;
|
|
722
1061
|
}
|
|
723
1062
|
const r = await signInWithBwalletX({ wallet: found.wallet, challenge: (identityKey) => postJson(challengeUrl, { identityKey }) });
|
|
@@ -742,7 +1081,7 @@ function defineBwalletxSignin(tag = SIGNIN_TAG) {
|
|
|
742
1081
|
}
|
|
743
1082
|
|
|
744
1083
|
// src/pay.ts
|
|
745
|
-
var
|
|
1084
|
+
var import_sdk5 = require("@bsv/sdk");
|
|
746
1085
|
var BRC29_PROTOCOL = [2, "3241645161d8"];
|
|
747
1086
|
var PaymentError = class extends Error {
|
|
748
1087
|
constructor(code, message, maybeSent = false, cause) {
|
|
@@ -762,13 +1101,13 @@ var isPaymail = (s) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s);
|
|
|
762
1101
|
function randomB64(n) {
|
|
763
1102
|
const b = new Uint8Array(n);
|
|
764
1103
|
globalThis.crypto.getRandomValues(b);
|
|
765
|
-
return
|
|
1104
|
+
return import_sdk5.Utils.toBase64(Array.from(b));
|
|
766
1105
|
}
|
|
767
1106
|
function opReturn(text) {
|
|
768
|
-
const d =
|
|
1107
|
+
const d = import_sdk5.Utils.toArray(text, "utf8");
|
|
769
1108
|
const len = d.length;
|
|
770
1109
|
const push = len < 76 ? [len] : len <= 255 ? [76, len] : [77, len & 255, len >> 8];
|
|
771
|
-
return
|
|
1110
|
+
return import_sdk5.Utils.toHex([0, 106, ...push, ...d]);
|
|
772
1111
|
}
|
|
773
1112
|
var clip = (s, n) => s.length > n ? s.slice(0, n - 1) + "\u2026" : s;
|
|
774
1113
|
var describe = (s) => clip(s.length < 5 ? `${s} payment`.trim() : s, 50);
|
|
@@ -864,7 +1203,7 @@ async function pay(source, req, o = {}) {
|
|
|
864
1203
|
} catch (e) {
|
|
865
1204
|
throw new PaymentError("WALLET_ERROR", `The wallet could not derive the payment key: ${e.message}`, false, e);
|
|
866
1205
|
}
|
|
867
|
-
outputs = [{ script: new
|
|
1206
|
+
outputs = [{ script: new import_sdk5.P2PKH().lock(import_sdk5.PublicKey.fromString(pk).toHash()).toHex(), satoshis: sats, description: "payment" }];
|
|
868
1207
|
remittance = { senderIdentityKey: me, derivationPrefix, derivationSuffix, outputIndex: 0 };
|
|
869
1208
|
} else if (isPaymail(to)) {
|
|
870
1209
|
const r2 = await (o.resolvePaymail ?? ((p, s) => resolvePaymailP2P(p, s, o.fetch ?? fetch)))(to, sats);
|
|
@@ -872,7 +1211,7 @@ async function pay(source, req, o = {}) {
|
|
|
872
1211
|
submit = r2.submit;
|
|
873
1212
|
} else {
|
|
874
1213
|
try {
|
|
875
|
-
outputs = [{ script: new
|
|
1214
|
+
outputs = [{ script: new import_sdk5.P2PKH().lock(to).toHex(), satoshis: sats, description: "payment" }];
|
|
876
1215
|
} catch {
|
|
877
1216
|
throw new PaymentError("BAD_REQUEST", `Not a paymail, address or identity key: ${to}`);
|
|
878
1217
|
}
|
|
@@ -882,7 +1221,7 @@ async function pay(source, req, o = {}) {
|
|
|
882
1221
|
if (!r.txid) throw new PaymentError("WALLET_ERROR", "The wallet did not return a txid", true);
|
|
883
1222
|
const tx = r.tx ? Array.from(r.tx) : void 0;
|
|
884
1223
|
if (submit && tx) {
|
|
885
|
-
await submit(
|
|
1224
|
+
await submit(import_sdk5.Transaction.fromAtomicBEEF(tx).toHex()).catch(() => {
|
|
886
1225
|
});
|
|
887
1226
|
}
|
|
888
1227
|
return { txid: r.txid, tx, sats, outputs, remittance };
|
|
@@ -903,7 +1242,7 @@ async function buyToken(source, req) {
|
|
|
903
1242
|
}
|
|
904
1243
|
|
|
905
1244
|
// src/wallets.ts
|
|
906
|
-
var
|
|
1245
|
+
var import_sdk6 = require("@bsv/sdk");
|
|
907
1246
|
async function brc100Connected(wallet, o) {
|
|
908
1247
|
await wallet.waitForAuthentication({}).catch(() => {
|
|
909
1248
|
});
|
|
@@ -962,7 +1301,7 @@ function handcashAdapter(o) {
|
|
|
962
1301
|
var NAMES = { [RDNS_EXTENSION]: "bWalletX", "space.bwallet.mobile": "bWalletX" };
|
|
963
1302
|
async function probe(substrate, ms) {
|
|
964
1303
|
try {
|
|
965
|
-
const w = new
|
|
1304
|
+
const w = new import_sdk6.WalletClient(substrate);
|
|
966
1305
|
const ok = await Promise.race([w.isAuthenticated({}).then(() => true), new Promise((r) => setTimeout(() => r(false), ms))]);
|
|
967
1306
|
return ok ? w : null;
|
|
968
1307
|
} catch {
|
|
@@ -1015,6 +1354,9 @@ var CSS2 = `
|
|
|
1015
1354
|
.bwx-row{display:flex;gap:8px;margin-top:14px}
|
|
1016
1355
|
.bwx-btn{flex:1;border:1px solid #3a3220;background:#15130e;color:#f4f1e8;border-radius:10px;padding:10px 12px;font:inherit;cursor:pointer}
|
|
1017
1356
|
.bwx-btn:hover{border-color:#e8c766}
|
|
1357
|
+
a.bwx-btn{display:block;text-align:center;text-decoration:none;box-sizing:border-box}
|
|
1358
|
+
.bwx-primary{background:linear-gradient(180deg,#fcd34d,#f59e0b);color:#000;border:0;font-weight:700;min-height:48px;padding:13px 12px}
|
|
1359
|
+
.bwx-stack{display:flex;flex-direction:column;gap:8px}
|
|
1018
1360
|
.bwx-list{display:flex;flex-direction:column;gap:8px}
|
|
1019
1361
|
.bwx-opt{display:flex;align-items:center;gap:10px;text-align:left}
|
|
1020
1362
|
.bwx-opt img{width:24px;height:24px;border-radius:6px}
|
|
@@ -1045,6 +1387,18 @@ function qrSvg(text) {
|
|
|
1045
1387
|
q.make();
|
|
1046
1388
|
return q.createSvgTag({ cellSize: 4, margin: 2, scalable: true });
|
|
1047
1389
|
}
|
|
1390
|
+
function isTouchDevice(env = globalThis) {
|
|
1391
|
+
const nav = env.navigator;
|
|
1392
|
+
if (!nav) return false;
|
|
1393
|
+
const ua = nav.userAgent ?? "";
|
|
1394
|
+
if (/Android|iPhone|iPad|iPod|Mobile|Silk|Kindle/i.test(ua)) return true;
|
|
1395
|
+
if (/Macintosh/.test(ua) && (nav.maxTouchPoints ?? 0) > 1) return true;
|
|
1396
|
+
try {
|
|
1397
|
+
return !!env.matchMedia?.("(pointer: coarse)").matches && !env.matchMedia?.("(hover: hover)").matches;
|
|
1398
|
+
} catch {
|
|
1399
|
+
return false;
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1048
1402
|
function pairingModal(o = {}) {
|
|
1049
1403
|
const ac = new AbortController();
|
|
1050
1404
|
let ui = null;
|
|
@@ -1061,20 +1415,37 @@ function pairingModal(o = {}) {
|
|
|
1061
1415
|
if (typeof document === "undefined") return;
|
|
1062
1416
|
close();
|
|
1063
1417
|
ui = mount();
|
|
1418
|
+
const app = o.mode === "app" || (o.mode ?? "auto") === "auto" && isTouchDevice();
|
|
1064
1419
|
const h = el("h2", "", o.title ?? "Connect bWalletX");
|
|
1420
|
+
const cancel = el("button", "bwx-btn", "Cancel");
|
|
1421
|
+
cancel.onclick = () => {
|
|
1422
|
+
o.onCancel?.();
|
|
1423
|
+
ac.abort();
|
|
1424
|
+
};
|
|
1425
|
+
codeEl = el("div", "bwx-code", "");
|
|
1426
|
+
codeEl.setAttribute("aria-live", "polite");
|
|
1427
|
+
if (app) {
|
|
1428
|
+
const p2 = el("p", "", "Open bWalletX, approve, then come back to this page.");
|
|
1429
|
+
const stack = el("div", "bwx-stack");
|
|
1430
|
+
const open = el("a", "bwx-btn bwx-primary", "Open bWalletX");
|
|
1431
|
+
open.href = link;
|
|
1432
|
+
open.rel = "noopener";
|
|
1433
|
+
const web = el("button", "bwx-btn", "Use web.bwalletx.com instead");
|
|
1434
|
+
web.onclick = () => {
|
|
1435
|
+
void navigator.clipboard?.writeText(link).catch(() => void 0);
|
|
1436
|
+
window.open(WEB_WALLET_URL, "_blank", "noopener");
|
|
1437
|
+
p2.textContent = "Link copied. In web.bwalletx.com tap Connect and paste it, then come back here.";
|
|
1438
|
+
};
|
|
1439
|
+
stack.append(open, web, cancel);
|
|
1440
|
+
ui.box.append(h, p2, codeEl, stack);
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1065
1443
|
const p = el("p", "", "Scan with bWalletX on your phone, or paste the link into web.bwalletx.com.");
|
|
1066
1444
|
const qr = el("div", "bwx-qr");
|
|
1067
1445
|
qr.innerHTML = qrSvg(link);
|
|
1068
|
-
codeEl = el("div", "bwx-code", "");
|
|
1069
|
-
codeEl.setAttribute("aria-live", "polite");
|
|
1070
1446
|
const row = el("div", "bwx-row");
|
|
1071
1447
|
const copy = el("button", "bwx-btn", "Copy link");
|
|
1072
1448
|
copy.onclick = () => void navigator.clipboard?.writeText(link).then(() => copy.textContent = "Copied");
|
|
1073
|
-
const cancel = el("button", "bwx-btn", "Cancel");
|
|
1074
|
-
cancel.onclick = () => {
|
|
1075
|
-
o.onCancel?.();
|
|
1076
|
-
ac.abort();
|
|
1077
|
-
};
|
|
1078
1449
|
row.append(copy, cancel);
|
|
1079
1450
|
ui.box.append(h, p, qr, codeEl, row);
|
|
1080
1451
|
},
|
|
@@ -1118,25 +1489,53 @@ function pickWallet(options, o = {}) {
|
|
|
1118
1489
|
ui.box.lastChild.append(cancel);
|
|
1119
1490
|
});
|
|
1120
1491
|
}
|
|
1492
|
+
|
|
1493
|
+
// src/theme.ts
|
|
1494
|
+
var WALLET_THEME_META = "bwalletx-theme";
|
|
1495
|
+
var ID = /^[a-z0-9-]{1,32}$/;
|
|
1496
|
+
function declareWalletTheme(theme) {
|
|
1497
|
+
if (typeof document === "undefined") return;
|
|
1498
|
+
const id = (theme ?? "").trim().toLowerCase();
|
|
1499
|
+
let meta = document.head.querySelector(`meta[name="${WALLET_THEME_META}"]`);
|
|
1500
|
+
if (!id || !ID.test(id)) {
|
|
1501
|
+
meta?.remove();
|
|
1502
|
+
return;
|
|
1503
|
+
}
|
|
1504
|
+
if (!meta) {
|
|
1505
|
+
meta = document.createElement("meta");
|
|
1506
|
+
meta.name = WALLET_THEME_META;
|
|
1507
|
+
document.head.appendChild(meta);
|
|
1508
|
+
}
|
|
1509
|
+
if (meta.content !== id) meta.content = id;
|
|
1510
|
+
}
|
|
1121
1511
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1122
1512
|
0 && (module.exports = {
|
|
1513
|
+
ACCESS_ERROR_STATUS,
|
|
1514
|
+
ACCESS_PROTOCOL,
|
|
1515
|
+
ACCESS_VERSION,
|
|
1516
|
+
AccessError,
|
|
1123
1517
|
BRC29_PROTOCOL,
|
|
1124
1518
|
BWALLETX_RDNS,
|
|
1125
1519
|
GET_URL,
|
|
1126
1520
|
LOGIN_PROTOCOL,
|
|
1127
1521
|
LOGO_URL,
|
|
1522
|
+
PROTOCOL_MEDIA,
|
|
1128
1523
|
PaymentError,
|
|
1129
1524
|
RDNS_EXTENSION,
|
|
1130
1525
|
RDNS_MOBILE,
|
|
1131
1526
|
SIGNIN_CSS,
|
|
1132
1527
|
SIGNIN_TAG,
|
|
1528
|
+
WALLET_THEME_META,
|
|
1133
1529
|
WEB_WALLET_URL,
|
|
1530
|
+
accessErrorMessage,
|
|
1134
1531
|
amountInSats,
|
|
1135
1532
|
brc100Option,
|
|
1136
1533
|
buildAuthorizeUrl,
|
|
1137
1534
|
buyToken,
|
|
1535
|
+
canonicalJson,
|
|
1138
1536
|
clearPairing,
|
|
1139
1537
|
connectBwalletX,
|
|
1538
|
+
declareWalletTheme,
|
|
1140
1539
|
defineBwalletxSignin,
|
|
1141
1540
|
discoverBwalletX,
|
|
1142
1541
|
discoverWallets,
|
|
@@ -1145,18 +1544,24 @@ function pickWallet(options, o = {}) {
|
|
|
1145
1544
|
inOrder,
|
|
1146
1545
|
isIdentityKeyHex,
|
|
1147
1546
|
isPaymail,
|
|
1547
|
+
isTouchDevice,
|
|
1148
1548
|
markSvg,
|
|
1149
1549
|
pairBwalletX,
|
|
1150
1550
|
pairingModal,
|
|
1151
1551
|
pairingOption,
|
|
1152
1552
|
pay,
|
|
1153
1553
|
pickWallet,
|
|
1554
|
+
protocolMediaUrl,
|
|
1555
|
+
proveHoldings,
|
|
1154
1556
|
qrSvg,
|
|
1155
1557
|
renderButton,
|
|
1558
|
+
requestAccess,
|
|
1156
1559
|
resolvePaymailP2P,
|
|
1157
1560
|
restorePairing,
|
|
1158
1561
|
signInWithBwalletX,
|
|
1159
1562
|
signinText,
|
|
1160
|
-
|
|
1563
|
+
throwIfAccessError,
|
|
1564
|
+
tip,
|
|
1565
|
+
toAccessError
|
|
1161
1566
|
});
|
|
1162
1567
|
//# sourceMappingURL=index.cjs.map
|