@bwalletx/connect 0.3.0 → 0.4.1

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/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,33 +17,57 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
21
31
  var src_exports = {};
22
32
  __export(src_exports, {
33
+ BRC29_PROTOCOL: () => BRC29_PROTOCOL,
23
34
  BWALLETX_RDNS: () => BWALLETX_RDNS,
24
35
  GET_URL: () => GET_URL,
25
36
  LOGIN_PROTOCOL: () => LOGIN_PROTOCOL,
26
37
  LOGO_URL: () => LOGO_URL,
38
+ PaymentError: () => PaymentError,
27
39
  RDNS_EXTENSION: () => RDNS_EXTENSION,
28
40
  RDNS_MOBILE: () => RDNS_MOBILE,
29
41
  SIGNIN_CSS: () => SIGNIN_CSS,
30
42
  SIGNIN_TAG: () => SIGNIN_TAG,
31
43
  WEB_WALLET_URL: () => WEB_WALLET_URL,
44
+ amountInSats: () => amountInSats,
45
+ brc100Option: () => brc100Option,
32
46
  buildAuthorizeUrl: () => buildAuthorizeUrl,
47
+ buyToken: () => buyToken,
33
48
  clearPairing: () => clearPairing,
34
49
  connectBwalletX: () => connectBwalletX,
35
50
  defineBwalletxSignin: () => defineBwalletxSignin,
36
51
  discoverBwalletX: () => discoverBwalletX,
52
+ discoverWallets: () => discoverWallets,
37
53
  findBwalletX: () => findBwalletX,
54
+ handcashAdapter: () => handcashAdapter,
38
55
  inOrder: () => inOrder,
56
+ isIdentityKeyHex: () => isIdentityKeyHex,
57
+ isPaymail: () => isPaymail,
39
58
  markSvg: () => markSvg,
40
59
  pairBwalletX: () => pairBwalletX,
60
+ pairingModal: () => pairingModal,
61
+ pairingOption: () => pairingOption,
62
+ pay: () => pay,
63
+ pickWallet: () => pickWallet,
64
+ qrSvg: () => qrSvg,
41
65
  renderButton: () => renderButton,
66
+ resolvePaymailP2P: () => resolvePaymailP2P,
42
67
  restorePairing: () => restorePairing,
43
68
  signInWithBwalletX: () => signInWithBwalletX,
44
- signinText: () => signinText
69
+ signinText: () => signinText,
70
+ tip: () => tip
45
71
  });
46
72
  module.exports = __toCommonJS(src_exports);
47
73
 
@@ -480,9 +506,9 @@ var CSS = `
480
506
  .bwx-signin .bwx-mark{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background:#000;flex:none}
481
507
  .bwx-signin small{display:block;font-size:11px;font-weight:500;color:rgba(0,0,0,.6)}`;
482
508
  var LOGO_URL = "https://bwalletx.com/logo.svg";
483
- function renderButton(el, opts = {}) {
484
- const host = typeof el === "string" ? document.querySelector(el) : el;
485
- if (!host) throw new Error(`renderButton: no element ${String(el)}`);
509
+ function renderButton(el2, opts = {}) {
510
+ const host = typeof el2 === "string" ? document.querySelector(el2) : el2;
511
+ if (!host) throw new Error(`renderButton: no element ${String(el2)}`);
486
512
  if (!document.getElementById("bwx-signin-css")) {
487
513
  const style = document.createElement("style");
488
514
  style.id = "bwx-signin-css";
@@ -714,29 +740,423 @@ function defineBwalletxSignin(tag = SIGNIN_TAG) {
714
740
  customElements.define(tag, C);
715
741
  return C;
716
742
  }
743
+
744
+ // src/pay.ts
745
+ var import_sdk3 = require("@bsv/sdk");
746
+ var BRC29_PROTOCOL = [2, "3241645161d8"];
747
+ var PaymentError = class extends Error {
748
+ constructor(code, message, maybeSent = false, cause) {
749
+ super(message);
750
+ this.code = code;
751
+ this.maybeSent = maybeSent;
752
+ this.cause = cause;
753
+ this.name = "PaymentError";
754
+ }
755
+ code;
756
+ maybeSent;
757
+ cause;
758
+ };
759
+ var isLegacy = (s) => typeof s.pay === "function" && typeof s.createAction !== "function";
760
+ var isIdentityKeyHex = (s) => /^0[23][0-9a-fA-F]{64}$/.test(s);
761
+ var isPaymail = (s) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(s);
762
+ function randomB64(n) {
763
+ const b = new Uint8Array(n);
764
+ globalThis.crypto.getRandomValues(b);
765
+ return import_sdk3.Utils.toBase64(Array.from(b));
766
+ }
767
+ function opReturn(text) {
768
+ const d = import_sdk3.Utils.toArray(text, "utf8");
769
+ const len = d.length;
770
+ const push = len < 76 ? [len] : len <= 255 ? [76, len] : [77, len & 255, len >> 8];
771
+ return import_sdk3.Utils.toHex([0, 106, ...push, ...d]);
772
+ }
773
+ var clip = (s, n) => s.length > n ? s.slice(0, n - 1) + "\u2026" : s;
774
+ var describe = (s) => clip(s.length < 5 ? `${s} payment`.trim() : s, 50);
775
+ async function usdRate(o) {
776
+ if (typeof o.usdPerBsv === "number") return o.usdPerBsv;
777
+ try {
778
+ if (typeof o.usdPerBsv === "function") return await o.usdPerBsv();
779
+ const r = await (o.fetch ?? fetch)("https://api.whatsonchain.com/v1/bsv/main/exchangerate");
780
+ const j = await r.json();
781
+ if (!r.ok || !(Number(j.rate) > 0)) throw new Error(`status ${r.status}`);
782
+ return Number(j.rate);
783
+ } catch (e) {
784
+ throw new PaymentError("RATE_FAILED", `Could not get the BSV/USD rate: ${e.message}`, false, e);
785
+ }
786
+ }
787
+ async function amountInSats(req, o = {}) {
788
+ if (req.sats != null) {
789
+ if (!Number.isSafeInteger(req.sats) || req.sats <= 0) throw new PaymentError("BAD_REQUEST", "sats must be a positive integer");
790
+ return req.sats;
791
+ }
792
+ if (req.usd != null) {
793
+ if (!(req.usd > 0)) throw new PaymentError("BAD_REQUEST", "usd must be positive");
794
+ return Math.max(1, Math.ceil(req.usd / await usdRate(o) * 1e8));
795
+ }
796
+ throw new PaymentError("BAD_REQUEST", "Give sats or usd");
797
+ }
798
+ async function resolvePaymailP2P(paymail, sats, f = fetch) {
799
+ const [alias, domain] = paymail.split("@");
800
+ const fail = (m, e) => new PaymentError("RESOLVE_FAILED", `Could not resolve ${paymail}: ${m}`, false, e);
801
+ let caps;
802
+ try {
803
+ const r = await f(`https://${domain}/.well-known/bsvalias`);
804
+ caps = (await r.json()).capabilities;
805
+ } catch (e) {
806
+ throw fail("no bsvalias document (or CORS blocked it; resolve on your server and pass resolvePaymail)", e);
807
+ }
808
+ const fill = (u) => u.replace("{alias}", encodeURIComponent(alias)).replace("{domain.tld}", domain);
809
+ const dest = caps?.["2a40af698840"];
810
+ if (!dest) throw fail("it does not offer P2P payment destinations");
811
+ let body;
812
+ try {
813
+ const r = await f(fill(dest), { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ satoshis: sats }) });
814
+ if (!r.ok) throw new Error(`status ${r.status}`);
815
+ body = await r.json();
816
+ } catch (e) {
817
+ throw fail(e.message, e);
818
+ }
819
+ if (!body.outputs?.length) throw fail("no outputs returned");
820
+ const receive = caps["5f1323cddf31"];
821
+ return {
822
+ outputs: body.outputs.map((o) => ({ script: o.script, satoshis: o.satoshis })),
823
+ reference: body.reference,
824
+ submit: receive ? async (hex) => {
825
+ await f(fill(receive), {
826
+ method: "POST",
827
+ headers: { "content-type": "application/json" },
828
+ body: JSON.stringify({ hex, reference: body.reference, metadata: {} })
829
+ });
830
+ } : void 0
831
+ };
832
+ }
833
+ async function runAction(wallet, description, outputs, labels) {
834
+ try {
835
+ return await wallet.createAction({
836
+ description: describe(description),
837
+ outputs: outputs.map((o) => ({ lockingScript: o.script, satoshis: o.satoshis, outputDescription: describe(o.description ?? "payment") })),
838
+ labels: labels?.length ? labels : void 0,
839
+ options: { randomizeOutputs: false }
840
+ });
841
+ } catch (e) {
842
+ const msg = e?.message ?? String(e);
843
+ const rejected = /denied|reject|cancel|abort|user/i.test(msg) || e?.code === 4001;
844
+ throw new PaymentError(rejected ? "WALLET_REJECTED" : "WALLET_ERROR", rejected ? "The payment was declined in the wallet." : `The wallet could not make the payment: ${msg}`, !rejected, e);
845
+ }
846
+ }
847
+ async function pay(source, req, o = {}) {
848
+ const to = (req.to ?? "").trim();
849
+ if (!to) throw new PaymentError("BAD_REQUEST", "Give a recipient (to)");
850
+ if (req.memo && req.memo.length > 1e3) throw new PaymentError("BAD_REQUEST", "memo is too long");
851
+ const sats = await amountInSats(req, o);
852
+ if (isLegacy(source)) return source.pay({ ...req, to, sats });
853
+ let outputs;
854
+ let remittance;
855
+ let submit;
856
+ if (isIdentityKeyHex(to)) {
857
+ const derivationPrefix = randomB64(8);
858
+ const derivationSuffix = randomB64(8);
859
+ let pk;
860
+ let me;
861
+ try {
862
+ ({ publicKey: pk } = await source.getPublicKey({ protocolID: BRC29_PROTOCOL, keyID: `${derivationPrefix} ${derivationSuffix}`, counterparty: to.toLowerCase() }));
863
+ ({ publicKey: me } = await source.getPublicKey({ identityKey: true }));
864
+ } catch (e) {
865
+ throw new PaymentError("WALLET_ERROR", `The wallet could not derive the payment key: ${e.message}`, false, e);
866
+ }
867
+ outputs = [{ script: new import_sdk3.P2PKH().lock(import_sdk3.PublicKey.fromString(pk).toHash()).toHex(), satoshis: sats, description: "payment" }];
868
+ remittance = { senderIdentityKey: me, derivationPrefix, derivationSuffix, outputIndex: 0 };
869
+ } else if (isPaymail(to)) {
870
+ const r2 = await (o.resolvePaymail ?? ((p, s) => resolvePaymailP2P(p, s, o.fetch ?? fetch)))(to, sats);
871
+ outputs = r2.outputs;
872
+ submit = r2.submit;
873
+ } else {
874
+ try {
875
+ outputs = [{ script: new import_sdk3.P2PKH().lock(to).toHex(), satoshis: sats, description: "payment" }];
876
+ } catch {
877
+ throw new PaymentError("BAD_REQUEST", `Not a paymail, address or identity key: ${to}`);
878
+ }
879
+ }
880
+ if (req.memo && req.memoOnChain) outputs = [...outputs, { script: opReturn(req.memo), satoshis: 0, description: "memo" }];
881
+ const r = await runAction(source, req.memo || `Pay ${clip(to, 30)}`, outputs, req.labels);
882
+ if (!r.txid) throw new PaymentError("WALLET_ERROR", "The wallet did not return a txid", true);
883
+ const tx = r.tx ? Array.from(r.tx) : void 0;
884
+ if (submit && tx) {
885
+ await submit(import_sdk3.Transaction.fromAtomicBEEF(tx).toHex()).catch(() => {
886
+ });
887
+ }
888
+ return { txid: r.txid, tx, sats, outputs, remittance };
889
+ }
890
+ function tip(source, req, o = {}) {
891
+ return pay(source, { memo: "Tip", ...req, labels: [...req.labels ?? [], "tip"] }, o);
892
+ }
893
+ async function buyToken(source, req) {
894
+ if (isLegacy(source)) throw new PaymentError("NOT_SUPPORTED", "This wallet cannot buy tokens. Use a BRC-100 wallet such as bWalletX.");
895
+ const q = await req.quote({ token: req.token, amount: req.amount });
896
+ if (!q?.outputs?.length) throw new PaymentError("BAD_REQUEST", "The quote returned no outputs");
897
+ const sats = q.outputs.reduce((n, x) => n + x.satoshis, 0);
898
+ const r = await runAction(source, q.description ?? `Buy ${clip(req.token, 30)}`, q.outputs, [...req.labels ?? [], "token-buy"]);
899
+ if (!r.txid) throw new PaymentError("WALLET_ERROR", "The wallet did not return a txid", true);
900
+ const res = { txid: r.txid, tx: r.tx ? Array.from(r.tx) : void 0, sats, outputs: q.outputs };
901
+ await q.onPaid?.(res);
902
+ return res;
903
+ }
904
+
905
+ // src/wallets.ts
906
+ var import_sdk4 = require("@bsv/sdk");
907
+ async function brc100Connected(wallet, o) {
908
+ await wallet.waitForAuthentication({}).catch(() => {
909
+ });
910
+ const { publicKey } = await wallet.getPublicKey({ identityKey: true });
911
+ return { wallet, payer: wallet, identityKey: publicKey, optionId: o.id, kind: o.kind };
912
+ }
913
+ function brc100Option(wallet, info) {
914
+ const opt = {
915
+ id: info.id,
916
+ name: info.name,
917
+ icon: info.icon,
918
+ rdns: info.rdns,
919
+ kind: "brc100",
920
+ isBwalletX: info.isBwalletX ?? false,
921
+ connect: () => brc100Connected(wallet, opt)
922
+ };
923
+ return opt;
924
+ }
925
+ function pairingOption(pairing) {
926
+ const opt = {
927
+ id: "bwalletx-pairing",
928
+ name: "bWalletX on your phone",
929
+ kind: "pairing",
930
+ isBwalletX: true,
931
+ async connect() {
932
+ const p = typeof pairing === "function" ? pairing() : pairing;
933
+ const w = await restorePairing(p) ?? await pairBwalletX(p);
934
+ return brc100Connected(w, opt);
935
+ }
936
+ };
937
+ return opt;
938
+ }
939
+ function handcashAdapter(o) {
940
+ const opt = {
941
+ id: "handcash",
942
+ name: "HandCash",
943
+ icon: o.icon,
944
+ kind: "handcash",
945
+ isBwalletX: false,
946
+ async connect() {
947
+ const p = await o.login();
948
+ return {
949
+ wallet: null,
950
+ payer: o.pay ? { pay: o.pay } : null,
951
+ identityKey: p.identityKey ?? null,
952
+ handle: p.handle,
953
+ paymail: p.paymail ?? `${p.handle.replace(/^\$/, "")}@handcash.io`,
954
+ optionId: opt.id,
955
+ kind: "handcash",
956
+ transitional: true
957
+ };
958
+ }
959
+ };
960
+ return opt;
961
+ }
962
+ var NAMES = { [RDNS_EXTENSION]: "bWalletX", "space.bwallet.mobile": "bWalletX" };
963
+ async function probe(substrate, ms) {
964
+ try {
965
+ const w = new import_sdk4.WalletClient(substrate);
966
+ const ok = await Promise.race([w.isAuthenticated({}).then(() => true), new Promise((r) => setTimeout(() => r(false), ms))]);
967
+ return ok ? w : null;
968
+ } catch {
969
+ return null;
970
+ }
971
+ }
972
+ async function discoverWallets(o = {}) {
973
+ const out = [];
974
+ const ms = o.ms ?? 1200;
975
+ if (typeof window !== "undefined") {
976
+ const seen = /* @__PURE__ */ new Map();
977
+ const onAnnounce = (e) => {
978
+ const d = e.detail;
979
+ if (!d?.wallet) return;
980
+ const rdns = d.info?.rdns ?? d.info?.uuid ?? `wallet-${seen.size}`;
981
+ if (seen.has(rdns)) return;
982
+ const isB = BWALLETX_RDNS.includes(rdns);
983
+ seen.set(rdns, brc100Option(d.wallet, { id: rdns, rdns, name: NAMES[rdns] ?? d.info?.name ?? rdns, icon: d.info?.icon, isBwalletX: isB }));
984
+ };
985
+ window.addEventListener("brc100:announceWallet", onAnnounce);
986
+ window.dispatchEvent(new Event("brc100:requestWallet"));
987
+ const local = o.probeLocal ? Promise.all([probe("json-api", ms), probe("Cicada", ms)]) : Promise.resolve([null, null]);
988
+ await new Promise((r) => setTimeout(r, ms));
989
+ window.removeEventListener("brc100:announceWallet", onAnnounce);
990
+ out.push(...seen.values());
991
+ const cwi = window.CWI;
992
+ if (cwi && ![...seen.values()].some((x) => x.rdns === "space.bwallet.mobile")) {
993
+ out.push(brc100Option(cwi, { id: "window.CWI", name: "This app\u2019s wallet", isBwalletX: false }));
994
+ }
995
+ const [json, cicada] = await local;
996
+ if (json) out.push(brc100Option(json, { id: "localhost:3321", name: "Desktop wallet (localhost:3321)" }));
997
+ if (cicada) out.push(brc100Option(cicada, { id: "localhost:3301", name: "Desktop wallet (localhost:3301)" }));
998
+ }
999
+ if (o.pairing) out.push(pairingOption(o.pairing));
1000
+ out.push(...o.extra ?? []);
1001
+ const rank = (w) => w.isBwalletX ? 0 : w.kind === "handcash" ? 2 : 1;
1002
+ return out.map((w, i) => ({ w, i })).sort((a, b) => rank(a.w) - rank(b.w) || a.i - b.i).map((x) => x.w);
1003
+ }
1004
+
1005
+ // src/modal.ts
1006
+ var import_qrcode_generator = __toESM(require("qrcode-generator"), 1);
1007
+ var CSS2 = `
1008
+ .bwx-ov{position:fixed;inset:0;z-index:2147483000;background:rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center;padding:16px;font:15px/1.4 system-ui,-apple-system,Segoe UI,Roboto,sans-serif}
1009
+ .bwx-box{background:#0b0b0b;color:#f4f1e8;border:1px solid #3a3220;border-radius:16px;width:min(360px,100%);padding:20px;box-shadow:0 20px 60px rgba(0,0,0,.5)}
1010
+ .bwx-box h2{margin:0 0 6px;font-size:18px;color:#e8c766}
1011
+ .bwx-box p{margin:0 0 14px;color:#bdb6a3;font-size:14px}
1012
+ .bwx-qr{background:#fff;border-radius:12px;padding:12px;display:flex;justify-content:center}
1013
+ .bwx-qr svg{width:100%;height:auto;max-width:260px}
1014
+ .bwx-code{margin:14px 0 0;text-align:center;font-size:28px;letter-spacing:.3em;color:#e8c766;font-variant-numeric:tabular-nums}
1015
+ .bwx-row{display:flex;gap:8px;margin-top:14px}
1016
+ .bwx-btn{flex:1;border:1px solid #3a3220;background:#15130e;color:#f4f1e8;border-radius:10px;padding:10px 12px;font:inherit;cursor:pointer}
1017
+ .bwx-btn:hover{border-color:#e8c766}
1018
+ .bwx-list{display:flex;flex-direction:column;gap:8px}
1019
+ .bwx-opt{display:flex;align-items:center;gap:10px;text-align:left}
1020
+ .bwx-opt img{width:24px;height:24px;border-radius:6px}
1021
+ .bwx-tag{margin-left:auto;font-size:11px;color:#8d866f}
1022
+ `;
1023
+ function mount() {
1024
+ const root = document.createElement("div");
1025
+ root.className = "bwx-ov";
1026
+ root.setAttribute("role", "dialog");
1027
+ root.setAttribute("aria-modal", "true");
1028
+ const style = document.createElement("style");
1029
+ style.textContent = CSS2;
1030
+ const box = document.createElement("div");
1031
+ box.className = "bwx-box";
1032
+ root.append(style, box);
1033
+ document.body.appendChild(root);
1034
+ return { root, box, close: () => root.remove() };
1035
+ }
1036
+ function el(tag, cls, text) {
1037
+ const e = document.createElement(tag);
1038
+ if (cls) e.className = cls;
1039
+ if (text != null) e.textContent = text;
1040
+ return e;
1041
+ }
1042
+ function qrSvg(text) {
1043
+ const q = (0, import_qrcode_generator.default)(0, "M");
1044
+ q.addData(text);
1045
+ q.make();
1046
+ return q.createSvgTag({ cellSize: 4, margin: 2, scalable: true });
1047
+ }
1048
+ function pairingModal(o = {}) {
1049
+ const ac = new AbortController();
1050
+ let ui = null;
1051
+ let codeEl = null;
1052
+ const close = () => {
1053
+ ui?.close();
1054
+ ui = null;
1055
+ };
1056
+ ac.signal.addEventListener("abort", close);
1057
+ return {
1058
+ signal: ac.signal,
1059
+ close,
1060
+ onLink(link) {
1061
+ if (typeof document === "undefined") return;
1062
+ close();
1063
+ ui = mount();
1064
+ const h = el("h2", "", o.title ?? "Connect bWalletX");
1065
+ const p = el("p", "", "Scan with bWalletX on your phone, or paste the link into web.bwalletx.com.");
1066
+ const qr = el("div", "bwx-qr");
1067
+ qr.innerHTML = qrSvg(link);
1068
+ codeEl = el("div", "bwx-code", "");
1069
+ codeEl.setAttribute("aria-live", "polite");
1070
+ const row = el("div", "bwx-row");
1071
+ const copy = el("button", "bwx-btn", "Copy link");
1072
+ 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
+ row.append(copy, cancel);
1079
+ ui.box.append(h, p, qr, codeEl, row);
1080
+ },
1081
+ onCode(code) {
1082
+ if (codeEl) {
1083
+ codeEl.textContent = code;
1084
+ const p = ui?.box.querySelector("p");
1085
+ if (p) p.textContent = "Check bWalletX shows the same code, then tap Connect.";
1086
+ }
1087
+ }
1088
+ };
1089
+ }
1090
+ function pickWallet(options, o = {}) {
1091
+ if (typeof document === "undefined") return Promise.resolve(null);
1092
+ return new Promise((resolve) => {
1093
+ const ui = mount();
1094
+ const done = (w) => {
1095
+ ui.close();
1096
+ resolve(w);
1097
+ };
1098
+ ui.box.append(el("h2", "", o.title ?? "Choose a wallet"));
1099
+ if (!options.length) ui.box.append(el("p", "", "No wallet found. Get bWalletX at bwalletx.com."));
1100
+ const list = el("div", "bwx-list");
1101
+ for (const w of options) {
1102
+ const b = el("button", "bwx-btn bwx-opt");
1103
+ if (w.icon) {
1104
+ const img = el("img");
1105
+ img.src = w.icon;
1106
+ img.alt = "";
1107
+ b.append(img);
1108
+ }
1109
+ b.append(el("span", "", w.name));
1110
+ if (w.kind === "handcash") b.append(el("span", "bwx-tag", "until BRC-100"));
1111
+ b.onclick = () => done(w);
1112
+ list.append(b);
1113
+ }
1114
+ const cancel = el("button", "bwx-btn", "Cancel");
1115
+ cancel.onclick = () => done(null);
1116
+ ui.root.onclick = (e) => e.target === ui.root && done(null);
1117
+ ui.box.append(list, el("div", "bwx-row"));
1118
+ ui.box.lastChild.append(cancel);
1119
+ });
1120
+ }
717
1121
  // Annotate the CommonJS export names for ESM import in node:
718
1122
  0 && (module.exports = {
1123
+ BRC29_PROTOCOL,
719
1124
  BWALLETX_RDNS,
720
1125
  GET_URL,
721
1126
  LOGIN_PROTOCOL,
722
1127
  LOGO_URL,
1128
+ PaymentError,
723
1129
  RDNS_EXTENSION,
724
1130
  RDNS_MOBILE,
725
1131
  SIGNIN_CSS,
726
1132
  SIGNIN_TAG,
727
1133
  WEB_WALLET_URL,
1134
+ amountInSats,
1135
+ brc100Option,
728
1136
  buildAuthorizeUrl,
1137
+ buyToken,
729
1138
  clearPairing,
730
1139
  connectBwalletX,
731
1140
  defineBwalletxSignin,
732
1141
  discoverBwalletX,
1142
+ discoverWallets,
733
1143
  findBwalletX,
1144
+ handcashAdapter,
734
1145
  inOrder,
1146
+ isIdentityKeyHex,
1147
+ isPaymail,
735
1148
  markSvg,
736
1149
  pairBwalletX,
1150
+ pairingModal,
1151
+ pairingOption,
1152
+ pay,
1153
+ pickWallet,
1154
+ qrSvg,
737
1155
  renderButton,
1156
+ resolvePaymailP2P,
738
1157
  restorePairing,
739
1158
  signInWithBwalletX,
740
- signinText
1159
+ signinText,
1160
+ tip
741
1161
  });
742
1162
  //# sourceMappingURL=index.cjs.map