@xrpl-wallet-kit/browser 0.1.12 → 0.1.13

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.
@@ -1,4 +1,4 @@
1
- /*! @xrpl-wallet-kit/browser v0.1.12 | MIT | https://github.com/XRPDomains/xrpl-wallet-kit */
1
+ /*! @xrpl-wallet-kit/browser v0.1.13 | MIT | https://github.com/XRPDomains/xrpl-wallet-kit */
2
2
  var __defProp = Object.defineProperty;
3
3
  var __typeError = (msg) => {
4
4
  throw TypeError(msg);
@@ -1860,16 +1860,90 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
1860
1860
  WalletKitErrorCode2["UNSUPPORTED_METHOD"] = "UNSUPPORTED_METHOD";
1861
1861
  WalletKitErrorCode2["INVALID_ADAPTER"] = "INVALID_ADAPTER";
1862
1862
  WalletKitErrorCode2["NETWORK_MISMATCH"] = "NETWORK_MISMATCH";
1863
+ WalletKitErrorCode2["NETWORK_NOT_SUPPORTED"] = "NETWORK_NOT_SUPPORTED";
1863
1864
  WalletKitErrorCode2["NOT_CONNECTED"] = "NOT_CONNECTED";
1864
1865
  WalletKitErrorCode2["ALREADY_CONNECTED"] = "ALREADY_CONNECTED";
1865
1866
  WalletKitErrorCode2["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
1866
1867
  return WalletKitErrorCode2;
1867
1868
  })(WalletKitErrorCode || {});
1869
+ var WalletKitErrorCategory = /* @__PURE__ */ ((WalletKitErrorCategory2) => {
1870
+ WalletKitErrorCategory2["WALLET_UNAVAILABLE"] = "WALLET_UNAVAILABLE";
1871
+ WalletKitErrorCategory2["USER_ACTION"] = "USER_ACTION";
1872
+ WalletKitErrorCategory2["NETWORK"] = "NETWORK";
1873
+ WalletKitErrorCategory2["INVALID_INPUT"] = "INVALID_INPUT";
1874
+ WalletKitErrorCategory2["TIMEOUT"] = "TIMEOUT";
1875
+ WalletKitErrorCategory2["INTERNAL"] = "INTERNAL";
1876
+ return WalletKitErrorCategory2;
1877
+ })(WalletKitErrorCategory || {});
1878
+ const WALLET_KIT_ERROR_CATEGORY_BY_CODE = {
1879
+ [
1880
+ "WALLET_NOT_FOUND"
1881
+ /* WALLET_NOT_FOUND */
1882
+ ]: "WALLET_UNAVAILABLE",
1883
+ [
1884
+ "WALLET_NOT_INSTALLED"
1885
+ /* WALLET_NOT_INSTALLED */
1886
+ ]: "WALLET_UNAVAILABLE",
1887
+ [
1888
+ "WALLET_NOT_AVAILABLE"
1889
+ /* WALLET_NOT_AVAILABLE */
1890
+ ]: "WALLET_UNAVAILABLE",
1891
+ [
1892
+ "CONNECTION_FAILED"
1893
+ /* CONNECTION_FAILED */
1894
+ ]: "INTERNAL",
1895
+ [
1896
+ "CONNECTION_REJECTED"
1897
+ /* CONNECTION_REJECTED */
1898
+ ]: "USER_ACTION",
1899
+ [
1900
+ "SIGN_FAILED"
1901
+ /* SIGN_FAILED */
1902
+ ]: "INTERNAL",
1903
+ [
1904
+ "SIGN_REJECTED"
1905
+ /* SIGN_REJECTED */
1906
+ ]: "USER_ACTION",
1907
+ [
1908
+ "REQUEST_TIMEOUT"
1909
+ /* REQUEST_TIMEOUT */
1910
+ ]: "TIMEOUT",
1911
+ [
1912
+ "UNSUPPORTED_METHOD"
1913
+ /* UNSUPPORTED_METHOD */
1914
+ ]: "INVALID_INPUT",
1915
+ [
1916
+ "INVALID_ADAPTER"
1917
+ /* INVALID_ADAPTER */
1918
+ ]: "INVALID_INPUT",
1919
+ [
1920
+ "NETWORK_MISMATCH"
1921
+ /* NETWORK_MISMATCH */
1922
+ ]: "NETWORK",
1923
+ [
1924
+ "NETWORK_NOT_SUPPORTED"
1925
+ /* NETWORK_NOT_SUPPORTED */
1926
+ ]: "NETWORK",
1927
+ [
1928
+ "NOT_CONNECTED"
1929
+ /* NOT_CONNECTED */
1930
+ ]: "USER_ACTION",
1931
+ [
1932
+ "ALREADY_CONNECTED"
1933
+ /* ALREADY_CONNECTED */
1934
+ ]: "USER_ACTION",
1935
+ [
1936
+ "UNKNOWN_ERROR"
1937
+ /* UNKNOWN_ERROR */
1938
+ ]: "INTERNAL"
1939
+ /* INTERNAL */
1940
+ };
1868
1941
  class WalletKitError extends Error {
1869
1942
  constructor(code, message, options = {}) {
1870
1943
  super(message);
1871
1944
  this.name = "WalletKitError";
1872
1945
  this.code = code;
1946
+ this.category = options.category ?? WALLET_KIT_ERROR_CATEGORY_BY_CODE[code] ?? "INTERNAL";
1873
1947
  this.cause = options.cause;
1874
1948
  this.details = options.details;
1875
1949
  }
@@ -1937,6 +2011,16 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
1937
2011
  `Wallet adapter is invalid: ${adapterId}`,
1938
2012
  { details: { adapterId, issues } }
1939
2013
  ),
2014
+ networkMismatch: (walletName, expected, actual, cause) => new WalletKitError(
2015
+ "NETWORK_MISMATCH",
2016
+ `${walletName} is connected to ${actual ?? "an unknown network"} but the app requested ${expected ?? "a different network"}`,
2017
+ { cause, details: { walletName, expected, actual } }
2018
+ ),
2019
+ networkNotSupported: (walletName, network, cause) => new WalletKitError(
2020
+ "NETWORK_NOT_SUPPORTED",
2021
+ `${walletName} does not support ${network ?? "the requested network"}`,
2022
+ { cause, details: { walletName, network } }
2023
+ ),
1940
2024
  notConnected: () => new WalletKitError(
1941
2025
  "NOT_CONNECTED",
1942
2026
  "No wallet is connected"
@@ -2464,6 +2548,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
2464
2548
  const RECOVER_SESSION_RETRY_DELAYS_MS = [0, 700, 1600, 3e3];
2465
2549
  const DEFAULT_AUTO_RECONNECT_RESTORE_TIMEOUT_MS = 3e3;
2466
2550
  const DEFAULT_PENDING_RETURN_RECOVERY_TIMEOUT_MS = 1e4;
2551
+ const DEFAULT_AVAILABILITY_CHECK_TIMEOUT_MS = 1e3;
2467
2552
  const DEFAULT_ACCOUNT_STATUS_TIMEOUT_MS = 2500;
2468
2553
  const DEFAULT_AUTHENTICATE_EXPIRES_IN_SECONDS = 3600;
2469
2554
  const DEFAULT_TX_CONFIRMATION_ATTEMPTS = 6;
@@ -2505,7 +2590,12 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
2505
2590
  const entries = await Promise.all([...this.adapters.values()].map(async (adapter) => {
2506
2591
  if (!adapter.isAvailable) return [adapter.metadata.id, false];
2507
2592
  try {
2508
- return [adapter.metadata.id, Boolean(await adapter.isAvailable())];
2593
+ const availability = await this.withTimeout(Promise.resolve(adapter.isAvailable()), DEFAULT_AVAILABILITY_CHECK_TIMEOUT_MS);
2594
+ if (availability.timedOut) {
2595
+ this.logger.warn(`Availability check timed out for ${adapter.metadata.id}`);
2596
+ return [adapter.metadata.id, false];
2597
+ }
2598
+ return [adapter.metadata.id, Boolean(availability.value)];
2509
2599
  } catch (error) {
2510
2600
  this.logger.warn(`Availability check failed for ${adapter.metadata.id}`, error);
2511
2601
  return [adapter.metadata.id, false];
@@ -2517,7 +2607,12 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
2517
2607
  const results2 = await Promise.all([...this.adapters.values()].map(async (adapter) => {
2518
2608
  if (!adapter.isAvailable) return null;
2519
2609
  try {
2520
- return await adapter.isAvailable() ? adapter : null;
2610
+ const availability = await this.withTimeout(Promise.resolve(adapter.isAvailable()), DEFAULT_AVAILABILITY_CHECK_TIMEOUT_MS);
2611
+ if (availability.timedOut) {
2612
+ this.logger.warn(`Availability check timed out for ${adapter.metadata.id}`);
2613
+ return null;
2614
+ }
2615
+ return availability.value ? adapter : null;
2521
2616
  } catch (error) {
2522
2617
  this.logger.warn(`Availability check failed for ${adapter.metadata.id}`, error);
2523
2618
  return null;
@@ -2581,6 +2676,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
2581
2676
  await this.clearStoredSessionAsStale(session, "restore_unavailable");
2582
2677
  return null;
2583
2678
  }
2679
+ this.assertSessionNetwork(adapter, restored.session, this.getNetwork(), "restoreSession");
2584
2680
  const enrichedSession2 = await this.enrichSession(this.withWalletMetadata(restored.session, adapter));
2585
2681
  this.setSession(enrichedSession2);
2586
2682
  await this.loadPersistedTransactions(enrichedSession2);
@@ -2604,6 +2700,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
2604
2700
  return null;
2605
2701
  }
2606
2702
  const enrichedSession = await this.enrichSession(this.withWalletMetadata(session, adapter));
2703
+ this.assertSessionNetwork(adapter, enrichedSession, this.getNetwork(), "autoReconnect");
2607
2704
  this.setSession(enrichedSession);
2608
2705
  await this.loadPersistedTransactions(enrichedSession);
2609
2706
  this.emit("session_restored", { adapterId: enrichedSession.adapterId, account: enrichedSession.account, session: enrichedSession, stale: true });
@@ -2660,6 +2757,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
2660
2757
  }
2661
2758
  const recovered = recovery.value;
2662
2759
  if (!(recovered == null ? void 0 : recovered.session)) continue;
2760
+ this.assertSessionNetwork(adapter, recovered.session, network, "recoverSession");
2663
2761
  const enrichedSession = await this.enrichSession(this.withWalletMetadata(recovered.session, adapter));
2664
2762
  this.setSession(enrichedSession);
2665
2763
  await this.saveSession(enrichedSession);
@@ -2698,7 +2796,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
2698
2796
  this.pendingAdapterId = adapterId;
2699
2797
  this.pendingAbortController = new AbortController();
2700
2798
  this.emit("connecting", { adapterId });
2701
- if (adapter.isAvailable && !await adapter.isAvailable()) {
2799
+ if (adapter.isAvailable && !await this.isAdapterAvailable(adapter)) {
2702
2800
  throw createWalletError.walletNotAvailable(adapter.metadata.name);
2703
2801
  }
2704
2802
  const signal = options.signal ?? this.pendingAbortController.signal;
@@ -2706,6 +2804,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
2706
2804
  if (signal.aborted || this.pendingAdapterId !== adapterId) {
2707
2805
  throw new Error("Wallet connection was cancelled");
2708
2806
  }
2807
+ this.assertAccountNetwork(adapter, result.account, network, "connect");
2709
2808
  const session = await this.enrichSession(this.withWalletMetadata(result.session ?? { adapterId, account: { ...result.account, network }, connectedAt: Date.now() }, adapter));
2710
2809
  this.setSession(session);
2711
2810
  await this.saveSession(session);
@@ -3181,6 +3280,31 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
3181
3280
  if (timer) clearTimeout(timer);
3182
3281
  }
3183
3282
  }
3283
+ async isAdapterAvailable(adapter) {
3284
+ if (!adapter.isAvailable) return true;
3285
+ const availability = await this.withTimeout(Promise.resolve(adapter.isAvailable()), DEFAULT_AVAILABILITY_CHECK_TIMEOUT_MS);
3286
+ if (availability.timedOut) {
3287
+ this.logger.warn(`Availability check timed out for ${adapter.metadata.id}`);
3288
+ return false;
3289
+ }
3290
+ return Boolean(availability.value);
3291
+ }
3292
+ assertSessionNetwork(adapter, session, expected, source) {
3293
+ this.assertAccountNetwork(adapter, session.account, expected, source);
3294
+ }
3295
+ assertAccountNetwork(adapter, account, expected, source) {
3296
+ const actualNetwork = account.network;
3297
+ const actualId = actualNetwork == null ? void 0 : actualNetwork.id;
3298
+ const actualType = (actualNetwork == null ? void 0 : actualNetwork.networkType) ?? account.networkType;
3299
+ const expectedId = expected.id;
3300
+ const expectedType = expected.networkType;
3301
+ if (actualId && actualId !== expectedId) {
3302
+ throw createWalletError.networkMismatch(adapter.metadata.name, String(expectedId), String(actualId), new Error(`${source} returned a different network id`));
3303
+ }
3304
+ if (actualType && actualType !== expectedType) {
3305
+ throw createWalletError.networkMismatch(adapter.metadata.name, expectedType, actualType, new Error(`${source} returned a different network type`));
3306
+ }
3307
+ }
3184
3308
  normalizeConnectionError(adapter, error) {
3185
3309
  if (isWalletKitError(error)) return error;
3186
3310
  const message = error instanceof Error ? error.message : String(error);
@@ -3216,6 +3340,21 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
3216
3340
  const encoder2 = new TextEncoder();
3217
3341
  return [...encoder2.encode(value)].map((byte) => byte.toString(16).padStart(2, "0")).join("").toUpperCase();
3218
3342
  }
3343
+ const EXECUTABLE_URL_PROTOCOLS = /* @__PURE__ */ new Set(["blob:", "data:", "file:", "javascript:", "vbscript:"]);
3344
+ const SAFE_DATA_IMAGE_PATTERN = /^data:image\/(?:avif|gif|jpeg|jpg|png|svg\+xml|webp);base64,[a-z0-9+/]+=*$/i;
3345
+ function isSafeWalletUrl(value, options = {}) {
3346
+ var _a2, _b;
3347
+ if (typeof value !== "string") return false;
3348
+ const url = value.trim();
3349
+ if (!url) return false;
3350
+ if (options.allowDataImage && SAFE_DATA_IMAGE_PATTERN.test(url)) return true;
3351
+ const protocol = (_b = (_a2 = url.match(/^([a-z][a-z0-9+.-]*):/i)) == null ? void 0 : _a2[1]) == null ? void 0 : _b.toLowerCase();
3352
+ if (!protocol) return true;
3353
+ return !EXECUTABLE_URL_PROTOCOLS.has(`${protocol}:`);
3354
+ }
3355
+ function sanitizeWalletUrl(value, options = {}) {
3356
+ return isSafeWalletUrl(value, options) ? value.trim() : void 0;
3357
+ }
3219
3358
  var umd$1 = { exports: {} };
3220
3359
  var umd = umd$1.exports;
3221
3360
  var hasRequiredUmd;
@@ -9167,6 +9306,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
9167
9306
  }
9168
9307
  async signAndSubmit(request) {
9169
9308
  if (!this.session) throw createWalletError.notConnected();
9309
+ this.assertSingleSignTransaction(request.txJson);
9170
9310
  try {
9171
9311
  const result = await this.session.signTransaction(request.txJson, request.submit ?? true);
9172
9312
  return {
@@ -9184,6 +9324,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
9184
9324
  }
9185
9325
  async signTransaction(request) {
9186
9326
  if (!this.session) throw createWalletError.notConnected();
9327
+ this.assertSingleSignTransaction(request.txJson);
9187
9328
  try {
9188
9329
  const result = await this.session.signTransaction(request.txJson, false);
9189
9330
  return {
@@ -9247,6 +9388,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
9247
9388
  async signWithDefaultLedger(tx, submit2 = true) {
9248
9389
  if (!this.xrp || !this.session) throw createWalletError.notConnected();
9249
9390
  if (!this.network) throw createWalletError.connectionFailed(this.metadata.name, new Error("XRPL network is required for Ledger signing"));
9391
+ this.assertSingleSignTransaction(tx);
9250
9392
  const { Client, encode: encode2 } = await Promise.resolve().then(() => index$4);
9251
9393
  const client2 = new Client(this.network.rpcUrl);
9252
9394
  await client2.connect();
@@ -9354,6 +9496,12 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
9354
9496
  if (timer) clearTimeout(timer);
9355
9497
  }
9356
9498
  }
9499
+ assertSingleSignTransaction(tx) {
9500
+ const txJson = asRecord(tx);
9501
+ if (txJson.SigningPubKey === "" || Array.isArray(txJson.Signers)) {
9502
+ throw createWalletError.unsupportedMethod("XRPL multisigning", this.metadata.name);
9503
+ }
9504
+ }
9357
9505
  }
9358
9506
  function createLedgerAdapter(options) {
9359
9507
  return new LedgerAdapter(options);
@@ -15844,7 +15992,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
15844
15992
  this.activeAddress = void 0;
15845
15993
  this.activeProvider = ethereum;
15846
15994
  await this.selectSnapNetwork(options);
15847
- const snap = await this.withAbort(ethereum.request({ method: "wallet_invokeSnap", params: { snapId: this.snapId, request: { method: "xrpl_getAccount" } } }), options.signal);
15995
+ const snap = await this.withAbort(this.invokeSnap("xrpl_getAccount", void 0), options.signal);
15848
15996
  const address = snap.account;
15849
15997
  const publicKey = snap.publicKey;
15850
15998
  if (!address) throw new Error("XRPL Snap did not return an XRPL address");
@@ -15939,10 +16087,27 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
15939
16087
  }
15940
16088
  async invokeSnap(method, params) {
15941
16089
  const ethereum = await this.ethereum();
15942
- return ethereum.request({
16090
+ const request = () => ethereum.request({
15943
16091
  method: "wallet_invokeSnap",
15944
16092
  params: { snapId: this.snapId, request: { method, params } }
15945
16093
  });
16094
+ const retryDelays = this.options.snapRequestRetryDelaysMs ?? [120, 350, 800];
16095
+ try {
16096
+ return await request();
16097
+ } catch (error) {
16098
+ if (!this.isSnapKeyringHydratingError(error)) throw error;
16099
+ let lastError = error;
16100
+ for (const delayMs of retryDelays) {
16101
+ await this.delay(delayMs);
16102
+ try {
16103
+ return await request();
16104
+ } catch (retryError) {
16105
+ lastError = retryError;
16106
+ if (!this.isSnapKeyringHydratingError(retryError)) throw retryError;
16107
+ }
16108
+ }
16109
+ throw lastError;
16110
+ }
15946
16111
  }
15947
16112
  createSignMessagePaymentTx(request) {
15948
16113
  var _a2;
@@ -16031,8 +16196,9 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
16031
16196
  const injected = globalThis.ethereum;
16032
16197
  this.startEip6963Discovery();
16033
16198
  const configured = this.options.ethereum;
16199
+ if (this.activeProvider) return this.activeProvider;
16034
16200
  if (configured) return await this.pickSnapProvider(configured, true) ?? this.pickStrongMetaMaskProvider(configured);
16035
- const ethereum = this.activeProvider ?? await this.pickSnapProvider(injected, false) ?? await this.discoverMetaMaskProvider() ?? [...discoveredMetaMaskProviders][0] ?? this.pickStrongMetaMaskProvider(injected);
16201
+ const ethereum = await this.pickSnapProvider(injected, false) ?? await this.discoverMetaMaskProvider() ?? [...discoveredMetaMaskProviders][0] ?? this.pickStrongMetaMaskProvider(injected);
16036
16202
  if (!ethereum && required) throw new Error("No MetaMask provider installed");
16037
16203
  if (ethereum) this.activeProvider = ethereum;
16038
16204
  return ethereum;
@@ -16134,6 +16300,14 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
16134
16300
  const message = this.getErrorMessage(error);
16135
16301
  return /-32601|wallet_requestSnaps|wallet_getSnaps|does not exist|not available|unsupported|method not found|unknown method/i.test(message);
16136
16302
  }
16303
+ isSnapKeyringHydratingError(error) {
16304
+ const message = this.getErrorMessage(error);
16305
+ return /KeyringController\s*-\s*Keyring not found|Keyring not found/i.test(message);
16306
+ }
16307
+ delay(ms2) {
16308
+ if (ms2 <= 0) return Promise.resolve();
16309
+ return new Promise((resolve) => setTimeout(resolve, ms2));
16310
+ }
16137
16311
  withAbort(promise, signal) {
16138
16312
  if (!signal) return promise;
16139
16313
  if (signal.aborted) return Promise.reject(createWalletError.connectionRejected(this.metadata.name, new Error("Connection was cancelled")));
@@ -20651,7 +20825,7 @@ ${new this._window.XMLSerializer().serializeToString(e4)}`;
20651
20825
  const textSize = this.options.textSize ?? "sm";
20652
20826
  const hasReadyUri = state2.status === "ready" && Boolean(state2.uri);
20653
20827
  state2.status === "ready" ? state2.uri : void 0;
20654
- const deeplink = state2.status === "ready" ? state2.deeplink : void 0;
20828
+ const deeplink = state2.status === "ready" ? sanitizeWalletUrl(state2.deeplink) : void 0;
20655
20829
  const qrCodeAttributes = hasReadyUri ? ` aria-hidden="true"` : "";
20656
20830
  const openAction = hasReadyUri && deeplink ? `<a class="xwk-action xwk-action-primary" data-xwk-open href="${this.escapeHtml(deeplink)}">${this.escapeHtml(messages.openWallet)}</a>` : "";
20657
20831
  const copyAction = hasReadyUri ? `<button class="xwk-action xwk-copy-inside" data-xwk-copy type="button">${this.renderQrCopyButtonContent()}</button>` : "";
@@ -20771,7 +20945,8 @@ ${new this._window.XMLSerializer().serializeToString(e4)}`;
20771
20945
  const previewLimit = group.maxPreviewIcons ?? 5;
20772
20946
  const previewWallets = wallets.slice(0, previewLimit);
20773
20947
  const overflow = wallets.length - previewWallets.length;
20774
- const icon = group.icon ? `<img src="${this.escapeHtml(group.icon)}" alt="">` : `<span class="xwk-icon-fallback">${this.escapeHtml(group.name.slice(0, 1).toUpperCase())}</span>`;
20948
+ const iconUrl = sanitizeWalletUrl(group.icon, { allowDataImage: true });
20949
+ const icon = iconUrl ? `<img src="${this.escapeHtml(iconUrl)}" alt="">` : `<span class="xwk-icon-fallback">${this.escapeHtml(group.name.slice(0, 1).toUpperCase())}</span>`;
20775
20950
  const secondary = layout === "list" ? `<span class="xwk-group">${this.escapeHtml(messages.walletCount(wallets.length))}</span>` : layout === "card" || layout === "grid" ? `<span class="xwk-group">+${this.escapeHtml(messages.walletCount(wallets.length))}</span>` : "";
20776
20951
  const preview = previewWallets.length ? `<span class="xwk-group-icons">${previewWallets.map((wallet) => this.renderMiniWalletIcon(wallet)).join("")}${overflow > 0 ? `<span class="xwk-mini-more" aria-label="${this.escapeHtml(messages.moreWallets(overflow))}">+${overflow}</span>` : ""}</span>` : "";
20777
20952
  return `<button class="xwk-wallet xwk-wallet-group" data-wallet-group-id="${this.escapeHtml(group.id)}">${icon}<span class="xwk-wallet-info"><span class="xwk-name">${this.escapeHtml(group.name)}</span>${secondary}${preview}</span></button>`;
@@ -20828,14 +21003,16 @@ ${new this._window.XMLSerializer().serializeToString(e4)}`;
20828
21003
  }
20829
21004
  }
20830
21005
  renderWalletIcon(wallet) {
20831
- if (wallet == null ? void 0 : wallet.icon)
20832
- return `<img src="${this.escapeHtml(wallet.icon)}" alt="">`;
21006
+ const icon = sanitizeWalletUrl(wallet == null ? void 0 : wallet.icon, { allowDataImage: true });
21007
+ if (icon)
21008
+ return `<img src="${this.escapeHtml(icon)}" alt="">`;
20833
21009
  const letter = (wallet == null ? void 0 : wallet.name.slice(0, 1).toUpperCase()) ?? "W";
20834
21010
  return `<span class="xwk-icon-fallback">${this.escapeHtml(letter)}</span>`;
20835
21011
  }
20836
21012
  renderMiniWalletIcon(wallet) {
20837
- if (wallet.icon)
20838
- return `<img class="xwk-mini-icon" src="${this.escapeHtml(wallet.icon)}" alt="">`;
21013
+ const icon = sanitizeWalletUrl(wallet.icon, { allowDataImage: true });
21014
+ if (icon)
21015
+ return `<img class="xwk-mini-icon" src="${this.escapeHtml(icon)}" alt="">`;
20839
21016
  return `<span class="xwk-mini-icon xwk-mini-fallback">${this.escapeHtml(wallet.name.slice(0, 1).toUpperCase())}</span>`;
20840
21017
  }
20841
21018
  backIcon() {
@@ -21800,7 +21977,8 @@ ${new this._window.XMLSerializer().serializeToString(e4)}`;
21800
21977
  return `<div class="xwk-account-art xwk-account-avatar-skeleton" role="status" aria-label="${this.escapeHtml(this.messages().connecting)}"><span class="xwk-skeleton xwk-skeleton-circle"></span></div>`;
21801
21978
  }
21802
21979
  if (this.identityAvatar) {
21803
- return `<img class="xwk-account-avatar" src="${this.escapeHtml(this.identityAvatar)}" alt="">`;
21980
+ const avatar = sanitizeWalletUrl(this.identityAvatar, { allowDataImage: true });
21981
+ if (avatar) return `<img class="xwk-account-avatar" src="${this.escapeHtml(avatar)}" alt="">`;
21804
21982
  }
21805
21983
  const [from2, to2, spot] = this.getAddressGradient(this.getSessionAddress(session));
21806
21984
  return `<div class="xwk-account-art" style="--xwk-avatar-from:${from2};--xwk-avatar-to:${to2};--xwk-avatar-spot:${spot}"><span></span></div>`;
@@ -21836,7 +22014,7 @@ ${new this._window.XMLSerializer().serializeToString(e4)}`;
21836
22014
  return resolveWalletUiMessages(this.options.language, this.options.messages);
21837
22015
  }
21838
22016
  renderWalletIcon(wallet, fallbackIcon) {
21839
- const icon = (wallet == null ? void 0 : wallet.icon) ?? fallbackIcon;
22017
+ const icon = sanitizeWalletUrl((wallet == null ? void 0 : wallet.icon) ?? fallbackIcon, { allowDataImage: true });
21840
22018
  if (icon) return `<img class="xwk-button-icon" src="${this.escapeHtml(icon)}" alt="">`;
21841
22019
  if (!wallet) return `<span class="xwk-button-icon xwk-button-icon-fallback xwk-button-icon-svg-fallback" aria-hidden="true">${this.walletIcon()}</span>`;
21842
22020
  const label = wallet.name.slice(0, 1).toUpperCase();
@@ -21846,8 +22024,10 @@ ${new this._window.XMLSerializer().serializeToString(e4)}`;
21846
22024
  const icon = this.options.icon;
21847
22025
  if (!icon || icon.type === "default") return this.renderWalletIcon(void 0);
21848
22026
  if (icon.type === "image") {
22027
+ const src2 = sanitizeWalletUrl(icon.src, { allowDataImage: true });
22028
+ if (!src2) return this.renderWalletIcon(void 0);
21849
22029
  const aria = icon.alt ? ` role="img" aria-label="${this.escapeHtml(icon.alt)}"` : ` aria-hidden="true"`;
21850
- return `<span class="xwk-button-icon xwk-button-icon-custom xwk-button-icon-custom-image"${aria}><img src="${this.escapeHtml(icon.src)}" alt="" decoding="async"></span>`;
22030
+ return `<span class="xwk-button-icon xwk-button-icon-custom xwk-button-icon-custom-image"${aria}><img src="${this.escapeHtml(src2)}" alt="" decoding="async"></span>`;
21851
22031
  }
21852
22032
  return this.renderCustomHtmlIcon(icon);
21853
22033
  }
@@ -77899,6 +78079,7 @@ ${e2.length}`, n2 = new TextEncoder().encode(t2 + e2);
77899
78079
  exports.WALLETCONNECT_GROUP_ICON = WALLETCONNECT_GROUP_ICON;
77900
78080
  exports.WALLETCONNECT_ICON = WALLETCONNECT_ICON;
77901
78081
  exports.WALLET_ADAPTER_API_VERSION = WALLET_ADAPTER_API_VERSION;
78082
+ exports.WALLET_KIT_ERROR_CATEGORY_BY_CODE = WALLET_KIT_ERROR_CATEGORY_BY_CODE;
77902
78083
  exports.WALLET_STORAGE_VERSION = WALLET_STORAGE_VERSION;
77903
78084
  exports.WalletButton = WalletButtonController;
77904
78085
  exports.WalletButtonController = WalletButtonController;
@@ -77906,6 +78087,7 @@ ${e2.length}`, n2 = new TextEncoder().encode(t2 + e2);
77906
78087
  exports.WalletEventEmitter = WalletEventEmitter;
77907
78088
  exports.WalletInline = WalletInline;
77908
78089
  exports.WalletKitError = WalletKitError;
78090
+ exports.WalletKitErrorCategory = WalletKitErrorCategory;
77909
78091
  exports.WalletKitErrorCode = WalletKitErrorCode;
77910
78092
  exports.WalletManager = WalletManager;
77911
78093
  exports.WalletModal = WalletModal;
@@ -77962,6 +78144,7 @@ ${e2.length}`, n2 = new TextEncoder().encode(t2 + e2);
77962
78144
  exports.getNativeAsset = getNativeAsset;
77963
78145
  exports.glassTheme = glassTheme;
77964
78146
  exports.isMainnetNetwork = isMainnetNetwork;
78147
+ exports.isSafeWalletUrl = isSafeWalletUrl;
77965
78148
  exports.isSuccessResult = isSuccessResult;
77966
78149
  exports.isWalletKitError = isWalletKitError;
77967
78150
  exports.lightTheme = lightTheme;
@@ -77978,6 +78161,7 @@ ${e2.length}`, n2 = new TextEncoder().encode(t2 + e2);
77978
78161
  exports.resolveWalletUiMessages = resolveWalletUiMessages;
77979
78162
  exports.resolveWalletUiOptions = resolveWalletUiOptions;
77980
78163
  exports.roundedTheme = roundedTheme;
78164
+ exports.sanitizeWalletUrl = sanitizeWalletUrl;
77981
78165
  exports.softTheme = softTheme;
77982
78166
  exports.utf8ToHex = utf8ToHex;
77983
78167
  exports.validateWalletAdapter = validateWalletAdapter;