@solana-mobile/wallet-standard-mobile 0.5.0 → 0.5.2

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,13 +1,44 @@
1
- 'use strict';
2
-
3
- var walletStandardFeatures = require('@solana/wallet-standard-features');
4
- var QRCode = require('qrcode');
5
- var mobileWalletAdapterProtocol = require('@solana-mobile/mobile-wallet-adapter-protocol');
6
- var features = require('@wallet-standard/features');
7
- var base58 = require('bs58');
8
- var wallet = require('@wallet-standard/wallet');
9
- var walletStandardChains = require('@solana/wallet-standard-chains');
10
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let _solana_wallet_standard_features = require("@solana/wallet-standard-features");
25
+ let _solana_mobile_mobile_wallet_adapter_protocol = require("@solana-mobile/mobile-wallet-adapter-protocol");
26
+ let _wallet_standard_features = require("@wallet-standard/features");
27
+ let bs58 = require("bs58");
28
+ bs58 = __toESM(bs58);
29
+ let qrcode = require("qrcode");
30
+ qrcode = __toESM(qrcode);
31
+ let _wallet_standard_wallet = require("@wallet-standard/wallet");
32
+ let _solana_wallet_standard_chains = require("@solana/wallet-standard-chains");
33
+ //#region src/base64Utils.ts
34
+ function fromUint8Array(byteArray) {
35
+ return window.btoa(String.fromCharCode.call(null, ...byteArray));
36
+ }
37
+ function toUint8Array(base64EncodedByteArray) {
38
+ return new Uint8Array(window.atob(base64EncodedByteArray).split("").map((c) => c.charCodeAt(0)));
39
+ }
40
+ //#endregion
41
+ //#region src/embedded-modal/loadingSpinner.ts
11
42
  const modalHtml$1 = `
12
43
  <div class="mobile-wallet-adapter-embedded-loading-indicator" role="dialog" aria-modal="true" aria-labelledby="modal-title">
13
44
  <div data-modal-close style="position: absolute; width: 100%; height: 100%;"></div>
@@ -88,92 +119,76 @@ const css$6 = `
88
119
  }
89
120
  }
90
121
  `;
91
- class EmbeddedLoadingSpinner {
92
- #root = null;
93
- #eventListeners = {};
94
- #listenersAttached = false;
95
- dom = null;
96
- constructor() {
97
- // Bind methods to ensure `this` context is correct
98
- this.init = this.init.bind(this);
99
- this.#root = document.getElementById('mobile-wallet-adapter-embedded-root-ui');
100
- }
101
- async init() {
102
- console.log('Injecting modal');
103
- this.#injectHTML();
104
- }
105
- open = () => {
106
- console.debug('Modal open');
107
- this.#attachEventListeners();
108
- if (this.#root) {
109
- this.#root.style.display = 'flex';
110
- }
111
- };
112
- close = (event = undefined) => {
113
- console.debug('Modal close');
114
- this.#removeEventListeners();
115
- if (this.#root) {
116
- this.#root.style.display = 'none';
117
- }
118
- this.#eventListeners['close']?.forEach((listener) => listener(event));
119
- };
120
- addEventListener(event, listener) {
121
- this.#eventListeners[event]?.push(listener) || (this.#eventListeners[event] = [listener]);
122
- return () => this.removeEventListener(event, listener);
123
- }
124
- removeEventListener(event, listener) {
125
- this.#eventListeners[event] = this.#eventListeners[event]?.filter((existingListener) => listener !== existingListener);
126
- }
127
- #injectHTML() {
128
- // Check if already injected by checking if shadow DOM exists
129
- if (this.dom) {
130
- return;
131
- }
132
- // Create a container for the modal
133
- this.#root = document.createElement('div');
134
- this.#root.id = 'mobile-wallet-adapter-embedded-root-ui';
135
- this.#root.innerHTML = modalHtml$1;
136
- this.#root.style.display = 'none';
137
- // Apply styles
138
- const styles = document.createElement('style');
139
- styles.id = 'mobile-wallet-adapter-embedded-modal-styles';
140
- styles.textContent = css$6;
141
- // Create a shadow DOM to encapsulate the modal
142
- const host = document.createElement('div');
143
- this.dom = host.attachShadow({ mode: 'closed' });
144
- // Pass the CSS variable to the Shadow DOM
145
- host.style.setProperty('--spinner-color', '#FFFFFF');
146
- this.dom.appendChild(styles);
147
- this.dom.appendChild(this.#root);
148
- // Append the shadow DOM host to the body
149
- document.body.appendChild(host);
150
- }
151
- #attachEventListeners() {
152
- if (!this.#root || this.#listenersAttached)
153
- return;
154
- const closers = [...this.#root.querySelectorAll('[data-modal-close]')];
155
- closers.forEach(closer => closer?.addEventListener('click', (event) => { this.close(event); }));
156
- window.addEventListener('load', this.close);
157
- document.addEventListener('keydown', this.#handleKeyDown);
158
- this.#listenersAttached = true;
159
- }
160
- #removeEventListeners() {
161
- if (!this.#listenersAttached)
162
- return;
163
- window.removeEventListener('load', this.close);
164
- document.removeEventListener('keydown', this.#handleKeyDown);
165
- if (!this.#root)
166
- return;
167
- const closers = [...this.#root.querySelectorAll('[data-modal-close]')];
168
- closers.forEach(closer => closer?.removeEventListener('click', this.close));
169
- this.#listenersAttached = false;
170
- }
171
- #handleKeyDown = (event) => {
172
- if (event.key === 'Escape')
173
- this.close(event);
174
- };
175
- }
176
-
122
+ var EmbeddedLoadingSpinner = class {
123
+ #root = null;
124
+ #eventListeners = {};
125
+ #listenersAttached = false;
126
+ dom = null;
127
+ constructor() {
128
+ this.init = this.init.bind(this);
129
+ this.#root = document.getElementById("mobile-wallet-adapter-embedded-root-ui");
130
+ }
131
+ async init() {
132
+ console.log("Injecting modal");
133
+ this.#injectHTML();
134
+ }
135
+ open = () => {
136
+ console.debug("Modal open");
137
+ this.#attachEventListeners();
138
+ if (this.#root) this.#root.style.display = "flex";
139
+ };
140
+ close = (event = void 0) => {
141
+ console.debug("Modal close");
142
+ this.#removeEventListeners();
143
+ if (this.#root) this.#root.style.display = "none";
144
+ this.#eventListeners["close"]?.forEach((listener) => listener(event));
145
+ };
146
+ addEventListener(event, listener) {
147
+ this.#eventListeners[event]?.push(listener) || (this.#eventListeners[event] = [listener]);
148
+ return () => this.removeEventListener(event, listener);
149
+ }
150
+ removeEventListener(event, listener) {
151
+ this.#eventListeners[event] = this.#eventListeners[event]?.filter((existingListener) => listener !== existingListener);
152
+ }
153
+ #injectHTML() {
154
+ if (this.dom) return;
155
+ this.#root = document.createElement("div");
156
+ this.#root.id = "mobile-wallet-adapter-embedded-root-ui";
157
+ this.#root.innerHTML = modalHtml$1;
158
+ this.#root.style.display = "none";
159
+ const styles = document.createElement("style");
160
+ styles.id = "mobile-wallet-adapter-embedded-modal-styles";
161
+ styles.textContent = css$6;
162
+ const host = document.createElement("div");
163
+ this.dom = host.attachShadow({ mode: "closed" });
164
+ host.style.setProperty("--spinner-color", "#FFFFFF");
165
+ this.dom.appendChild(styles);
166
+ this.dom.appendChild(this.#root);
167
+ document.body.appendChild(host);
168
+ }
169
+ #attachEventListeners() {
170
+ if (!this.#root || this.#listenersAttached) return;
171
+ [...this.#root.querySelectorAll("[data-modal-close]")].forEach((closer) => closer?.addEventListener("click", (event) => {
172
+ this.close(event);
173
+ }));
174
+ window.addEventListener("load", this.close);
175
+ document.addEventListener("keydown", this.#handleKeyDown);
176
+ this.#listenersAttached = true;
177
+ }
178
+ #removeEventListeners() {
179
+ if (!this.#listenersAttached) return;
180
+ window.removeEventListener("load", this.close);
181
+ document.removeEventListener("keydown", this.#handleKeyDown);
182
+ if (!this.#root) return;
183
+ [...this.#root.querySelectorAll("[data-modal-close]")].forEach((closer) => closer?.removeEventListener("click", this.close));
184
+ this.#listenersAttached = false;
185
+ }
186
+ #handleKeyDown = (event) => {
187
+ if (event.key === "Escape") this.close(event);
188
+ };
189
+ };
190
+ //#endregion
191
+ //#region src/embedded-modal/modal.ts
177
192
  const modalHtml = `
178
193
  <div class="mobile-wallet-adapter-embedded-modal-container" role="dialog" aria-modal="true" aria-labelledby="modal-title">
179
194
  <div data-modal-close style="position: absolute; width: 100%; height: 100%;"></div>
@@ -195,7 +210,7 @@ const css$5 = `
195
210
  justify-content: center; /* Center horizontally */
196
211
  align-items: center; /* Center vertically */
197
212
  position: fixed; /* Stay in place */
198
- z-index: 1; /* Sit on top */
213
+ z-index: 2147483647; /* Sit on top */
199
214
  left: 0;
200
215
  top: 0;
201
216
  width: 100%; /* Full width */
@@ -251,124 +266,100 @@ const fonts = `
251
266
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
252
267
  <link href="https://fonts.googleapis.com/css2?family=Inter+Tight:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
253
268
  `;
254
- class EmbeddedModal {
255
- #root = null;
256
- #eventListeners = {};
257
- #listenersAttached = false;
258
- dom = null;
259
- constructor() {
260
- // Bind methods to ensure `this` context is correct
261
- this.init = this.init.bind(this);
262
- this.#root = document.getElementById('mobile-wallet-adapter-embedded-root-ui');
263
- }
264
- async init() {
265
- console.log('Injecting modal');
266
- this.#injectHTML();
267
- }
268
- open = () => {
269
- console.debug('Modal open');
270
- this.#attachEventListeners();
271
- if (this.#root) {
272
- this.#root.style.display = 'flex';
273
- }
274
- };
275
- close = (event = undefined) => {
276
- console.debug('Modal close');
277
- this.#removeEventListeners();
278
- if (this.#root) {
279
- this.#root.style.display = 'none';
280
- }
281
- this.#eventListeners['close']?.forEach((listener) => listener(event));
282
- };
283
- addEventListener(event, listener) {
284
- this.#eventListeners[event]?.push(listener) || (this.#eventListeners[event] = [listener]);
285
- return () => this.removeEventListener(event, listener);
286
- }
287
- removeEventListener(event, listener) {
288
- this.#eventListeners[event] = this.#eventListeners[event]?.filter((existingListener) => listener !== existingListener);
289
- }
290
- #injectHTML() {
291
- // Check if the HTML has already been injected
292
- if (document.getElementById('mobile-wallet-adapter-embedded-root-ui')) {
293
- if (!this.#root)
294
- this.#root = document.getElementById('mobile-wallet-adapter-embedded-root-ui');
295
- return;
296
- }
297
- // Create a container for the modal
298
- this.#root = document.createElement('div');
299
- this.#root.id = 'mobile-wallet-adapter-embedded-root-ui';
300
- this.#root.innerHTML = modalHtml;
301
- this.#root.style.display = 'none';
302
- // Add modal content
303
- const content = this.#root.querySelector('.mobile-wallet-adapter-embedded-modal-content');
304
- if (content)
305
- content.innerHTML = this.contentHtml;
306
- // Apply styles
307
- const styles = document.createElement('style');
308
- styles.id = 'mobile-wallet-adapter-embedded-modal-styles';
309
- styles.textContent = css$5 + this.contentStyles;
310
- // Create a shadow DOM to encapsulate the modal
311
- const host = document.createElement('div');
312
- host.innerHTML = fonts;
313
- this.dom = host.attachShadow({ mode: 'closed' });
314
- this.dom.appendChild(styles);
315
- this.dom.appendChild(this.#root);
316
- // Append the shadow DOM host to the body
317
- document.body.appendChild(host);
318
- }
319
- #attachEventListeners() {
320
- if (!this.#root || this.#listenersAttached)
321
- return;
322
- const closers = [...this.#root.querySelectorAll('[data-modal-close]')];
323
- closers.forEach(closer => closer?.addEventListener('click', this.close));
324
- window.addEventListener('load', this.close);
325
- document.addEventListener('keydown', this.#handleKeyDown);
326
- this.#listenersAttached = true;
327
- }
328
- #removeEventListeners() {
329
- if (!this.#listenersAttached)
330
- return;
331
- window.removeEventListener('load', this.close);
332
- document.removeEventListener('keydown', this.#handleKeyDown);
333
- if (!this.#root)
334
- return;
335
- const closers = [...this.#root.querySelectorAll('[data-modal-close]')];
336
- closers.forEach(closer => closer?.removeEventListener('click', this.close));
337
- this.#listenersAttached = false;
338
- }
339
- #handleKeyDown = (event) => {
340
- if (event.key === 'Escape')
341
- this.close(event);
342
- };
343
- }
344
-
345
- class RemoteConnectionModal extends EmbeddedModal {
346
- contentStyles = css$4;
347
- contentHtml = QRCodeHtml;
348
- async initWithQR(qrCode) {
349
- super.init();
350
- this.populateQRCode(qrCode);
351
- }
352
- async populateQRCode(qrUrl) {
353
- const qrcodeContainer = this.dom?.getElementById('mobile-wallet-adapter-embedded-modal-qr-code-container');
354
- if (qrcodeContainer) {
355
- const qrCodeElement = await QRCode.toCanvas(qrUrl, { width: 200, margin: 0 });
356
- if (qrcodeContainer.firstElementChild !== null) {
357
- qrcodeContainer.replaceChild(qrCodeElement, qrcodeContainer.firstElementChild);
358
- }
359
- else
360
- qrcodeContainer.appendChild(qrCodeElement);
361
- // remove the loading placeholder for cleanup
362
- const qrPlaceholder = this.dom?.getElementById('mobile-wallet-adapter-embedded-modal-qr-placeholder');
363
- if (qrPlaceholder) {
364
- qrPlaceholder.style.display = 'none';
365
- }
366
- }
367
- else {
368
- console.error('QRCode Container not found');
369
- }
370
- }
371
- }
269
+ var EmbeddedModal = class {
270
+ #root = null;
271
+ #eventListeners = {};
272
+ #listenersAttached = false;
273
+ dom = null;
274
+ constructor() {
275
+ this.init = this.init.bind(this);
276
+ this.#root = document.getElementById("mobile-wallet-adapter-embedded-root-ui");
277
+ }
278
+ async init() {
279
+ console.log("Injecting modal");
280
+ this.#injectHTML();
281
+ }
282
+ open = () => {
283
+ console.debug("Modal open");
284
+ this.#attachEventListeners();
285
+ if (this.#root) this.#root.style.display = "flex";
286
+ };
287
+ close = (event = void 0) => {
288
+ console.debug("Modal close");
289
+ this.#removeEventListeners();
290
+ if (this.#root) this.#root.style.display = "none";
291
+ this.#eventListeners["close"]?.forEach((listener) => listener(event));
292
+ };
293
+ addEventListener(event, listener) {
294
+ this.#eventListeners[event]?.push(listener) || (this.#eventListeners[event] = [listener]);
295
+ return () => this.removeEventListener(event, listener);
296
+ }
297
+ removeEventListener(event, listener) {
298
+ this.#eventListeners[event] = this.#eventListeners[event]?.filter((existingListener) => listener !== existingListener);
299
+ }
300
+ #injectHTML() {
301
+ if (document.getElementById("mobile-wallet-adapter-embedded-root-ui")) {
302
+ if (!this.#root) this.#root = document.getElementById("mobile-wallet-adapter-embedded-root-ui");
303
+ return;
304
+ }
305
+ this.#root = document.createElement("div");
306
+ this.#root.id = "mobile-wallet-adapter-embedded-root-ui";
307
+ this.#root.innerHTML = modalHtml;
308
+ this.#root.style.display = "none";
309
+ const content = this.#root.querySelector(".mobile-wallet-adapter-embedded-modal-content");
310
+ if (content) content.innerHTML = this.contentHtml;
311
+ const styles = document.createElement("style");
312
+ styles.id = "mobile-wallet-adapter-embedded-modal-styles";
313
+ styles.textContent = css$5 + this.contentStyles;
314
+ const host = document.createElement("div");
315
+ host.innerHTML = fonts;
316
+ this.dom = host.attachShadow({ mode: "closed" });
317
+ this.dom.appendChild(styles);
318
+ this.dom.appendChild(this.#root);
319
+ document.body.appendChild(host);
320
+ }
321
+ #attachEventListeners() {
322
+ if (!this.#root || this.#listenersAttached) return;
323
+ [...this.#root.querySelectorAll("[data-modal-close]")].forEach((closer) => closer?.addEventListener("click", this.close));
324
+ window.addEventListener("load", this.close);
325
+ document.addEventListener("keydown", this.#handleKeyDown);
326
+ this.#listenersAttached = true;
327
+ }
328
+ #removeEventListeners() {
329
+ if (!this.#listenersAttached) return;
330
+ window.removeEventListener("load", this.close);
331
+ document.removeEventListener("keydown", this.#handleKeyDown);
332
+ if (!this.#root) return;
333
+ [...this.#root.querySelectorAll("[data-modal-close]")].forEach((closer) => closer?.removeEventListener("click", this.close));
334
+ this.#listenersAttached = false;
335
+ }
336
+ #handleKeyDown = (event) => {
337
+ if (event.key === "Escape") this.close(event);
338
+ };
339
+ };
340
+ //#endregion
341
+ //#region src/embedded-modal/remoteConnectionModal.ts
342
+ var RemoteConnectionModal = class extends EmbeddedModal {
343
+ contentStyles = css$4;
344
+ contentHtml = QRCodeHtml;
345
+ async initWithQR(qrCode) {
346
+ super.init();
347
+ this.populateQRCode(qrCode);
348
+ }
349
+ async populateQRCode(qrUrl) {
350
+ const qrcodeContainer = this.dom?.getElementById("mobile-wallet-adapter-embedded-modal-qr-code-container");
351
+ if (qrcodeContainer) {
352
+ const qrCodeElement = await qrcode.default.toCanvas(qrUrl, {
353
+ width: 200,
354
+ margin: 0
355
+ });
356
+ if (qrcodeContainer.firstElementChild !== null) qrcodeContainer.replaceChild(qrCodeElement, qrcodeContainer.firstElementChild);
357
+ else qrcodeContainer.appendChild(qrCodeElement);
358
+ const qrPlaceholder = this.dom?.getElementById("mobile-wallet-adapter-embedded-modal-qr-placeholder");
359
+ if (qrPlaceholder) qrPlaceholder.style.display = "none";
360
+ } else console.error("QRCode Container not found");
361
+ }
362
+ };
372
363
  const QRCodeHtml = `
373
364
  <div class="mobile-wallet-adapter-embedded-modal-qr-content">
374
365
  <div>
@@ -628,36 +619,25 @@ const css$4 = `
628
619
  animation: spinRight 2.5s cubic-bezier(.2,0,.8,1) infinite;
629
620
  }
630
621
  `;
631
-
632
- const icon = 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03IDIuNUgxN0MxNy44Mjg0IDIuNSAxOC41IDMuMTcxNTcgMTguNSA0VjIwQzE4LjUgMjAuODI4NCAxNy44Mjg0IDIxLjUgMTcgMjEuNUg3QzYuMTcxNTcgMjEuNSA1LjUgMjAuODI4NCA1LjUgMjBWNEM1LjUgMy4xNzE1NyA2LjE3MTU3IDIuNSA3IDIuNVpNMyA0QzMgMS43OTA4NiA0Ljc5MDg2IDAgNyAwSDE3QzE5LjIwOTEgMCAyMSAxLjc5MDg2IDIxIDRWMjBDMjEgMjIuMjA5MSAxOS4yMDkxIDI0IDE3IDI0SDdDNC43OTA4NiAyNCAzIDIyLjIwOTEgMyAyMFY0Wk0xMSA0LjYxNTM4QzEwLjQ0NzcgNC42MTUzOCAxMCA1LjA2MzEgMTAgNS42MTUzOFY2LjM4NDYyQzEwIDYuOTM2OSAxMC40NDc3IDcuMzg0NjIgMTEgNy4zODQ2MkgxM0MxMy41NTIzIDcuMzg0NjIgMTQgNi45MzY5IDE0IDYuMzg0NjJWNS42MTUzOEMxNCA1LjA2MzEgMTMuNTUyMyA0LjYxNTM4IDEzIDQuNjE1MzhIMTFaIiBmaWxsPSIjRENCOEZGIi8+Cjwvc3ZnPgo=';
633
-
634
- function fromUint8Array(byteArray) {
635
- return window.btoa(String.fromCharCode.call(null, ...byteArray));
636
- }
637
- function toUint8Array(base64EncodedByteArray) {
638
- return new Uint8Array(window
639
- .atob(base64EncodedByteArray)
640
- .split('')
641
- .map((c) => c.charCodeAt(0)));
642
- }
643
-
644
- class LocalConnectionModal extends EmbeddedModal {
645
- contentStyles = css$3;
646
- contentHtml = ErrorDialogHtml$3;
647
- initWithCallback(callback) {
648
- super.init();
649
- this.#prepareLaunchAction(callback);
650
- }
651
- #prepareLaunchAction(callback) {
652
- const launchButton = this.dom?.getElementById("mobile-wallet-adapter-launch-action");
653
- const listener = async () => {
654
- launchButton?.removeEventListener('click', listener);
655
- this.close();
656
- callback();
657
- };
658
- launchButton?.addEventListener('click', listener);
659
- }
660
- }
622
+ //#endregion
623
+ //#region src/embedded-modal/localConnectionModal.ts
624
+ var LocalConnectionModal = class extends EmbeddedModal {
625
+ contentStyles = css$3;
626
+ contentHtml = ErrorDialogHtml$3;
627
+ initWithCallback(callback) {
628
+ super.init();
629
+ this.#prepareLaunchAction(callback);
630
+ }
631
+ #prepareLaunchAction(callback) {
632
+ const launchButton = this.dom?.getElementById("mobile-wallet-adapter-launch-action");
633
+ const listener = async () => {
634
+ launchButton?.removeEventListener("click", listener);
635
+ this.close();
636
+ callback();
637
+ };
638
+ launchButton?.addEventListener("click", listener);
639
+ }
640
+ };
661
641
  const ErrorDialogHtml$3 = `
662
642
  <svg class="mobile-wallet-adapter-embedded-modal-launch-icon" width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
663
643
  <path d="M21.6 48C7.2 48 0 40.8 0 26.4V21.6C0 7.2 7.2 0 21.6 0H26.4C40.8 0 48 7.2 48 21.6V26.4C48 40.8 40.8 48 26.4 48H21.6Z" fill="#15994E"/>
@@ -715,28 +695,27 @@ const css$3 = `
715
695
  }
716
696
  }
717
697
  `;
718
-
719
- class LoopbackPermissionBlockedModal extends EmbeddedModal {
720
- contentStyles = css$2;
721
- get contentHtml() {
722
- const instructions = getIsPwaLaunchedAsApp()
723
- ? 'Long press the app icon on your home screen to open site settings'
724
- : 'Tap the lock or settings icon in the address bar to open site settings';
725
- return ErrorDialogHtml$2.replace('{{PERMISSION_INSTRUCTION_DETAIL}}', instructions);
726
- }
727
- async init() {
728
- super.init();
729
- this.#prepareLaunchAction();
730
- }
731
- #prepareLaunchAction() {
732
- const launchButton = this.dom?.getElementById("mobile-wallet-adapter-launch-action");
733
- const listener = async (event) => {
734
- launchButton?.removeEventListener('click', listener);
735
- this.close(event);
736
- };
737
- launchButton?.addEventListener('click', listener);
738
- }
739
- }
698
+ //#endregion
699
+ //#region src/embedded-modal/loopbackBlockedModal.ts
700
+ var LoopbackPermissionBlockedModal = class extends EmbeddedModal {
701
+ contentStyles = css$2;
702
+ get contentHtml() {
703
+ const instructions = getIsPwaLaunchedAsApp() ? "Long press the app icon on your home screen to open site settings" : "Tap the lock or settings icon in the address bar to open site settings";
704
+ return ErrorDialogHtml$2.replace("{{PERMISSION_INSTRUCTION_DETAIL}}", instructions);
705
+ }
706
+ async init() {
707
+ super.init();
708
+ this.#prepareLaunchAction();
709
+ }
710
+ #prepareLaunchAction() {
711
+ const launchButton = this.dom?.getElementById("mobile-wallet-adapter-launch-action");
712
+ const listener = async (event) => {
713
+ launchButton?.removeEventListener("click", listener);
714
+ this.close(event);
715
+ };
716
+ launchButton?.addEventListener("click", listener);
717
+ }
718
+ };
740
719
  const ErrorDialogHtml$2 = `
741
720
  <div class="mobile-wallet-adapter-embedded-modal-header">
742
721
  Local Wallet Connection
@@ -877,28 +856,27 @@ const css$2 = `
877
856
  }
878
857
  }
879
858
  `;
880
-
881
- class LoopbackPermissionModal extends EmbeddedModal {
882
- contentStyles = css$1;
883
- contentHtml = ErrorDialogHtml$1;
884
- async init() {
885
- super.init();
886
- this.#prepareLaunchAction();
887
- }
888
- #prepareLaunchAction() {
889
- const launchButton = this.dom?.getElementById("mobile-wallet-adapter-launch-action");
890
- const listener = async () => {
891
- launchButton?.removeEventListener('click', listener);
892
- try {
893
- // Trigger LNA permission prompting
894
- await fetch('http://localhost');
895
- }
896
- catch (e) { /* Ignore errors from fetch */ }
897
- this.close();
898
- };
899
- launchButton?.addEventListener('click', listener);
900
- }
901
- }
859
+ //#endregion
860
+ //#region src/embedded-modal/loopbackPermissionModal.ts
861
+ var LoopbackPermissionModal = class extends EmbeddedModal {
862
+ contentStyles = css$1;
863
+ contentHtml = ErrorDialogHtml$1;
864
+ async init() {
865
+ super.init();
866
+ this.#prepareLaunchAction();
867
+ }
868
+ #prepareLaunchAction() {
869
+ const launchButton = this.dom?.getElementById("mobile-wallet-adapter-launch-action");
870
+ const listener = async () => {
871
+ launchButton?.removeEventListener("click", listener);
872
+ try {
873
+ await fetch("http://localhost");
874
+ } catch {}
875
+ this.close();
876
+ };
877
+ launchButton?.addEventListener("click", listener);
878
+ }
879
+ };
902
880
  const ErrorDialogHtml$1 = `
903
881
  <div class="mobile-wallet-adapter-embedded-modal-title">Allow connections to your wallet</div>
904
882
  <div id="mobile-wallet-adapter-local-launch-message" class="mobile-wallet-adapter-embedded-modal-subtitle">
@@ -972,1015 +950,842 @@ const css$1 = `
972
950
  }
973
951
  }
974
952
  `;
975
-
953
+ //#endregion
954
+ //#region src/getIsSupported.ts
976
955
  function getIsLocalAssociationSupported() {
977
- return (typeof window !== 'undefined' &&
978
- window.isSecureContext &&
979
- typeof document !== 'undefined' &&
980
- /android/i.test(navigator.userAgent));
956
+ return typeof window !== "undefined" && window.isSecureContext && typeof document !== "undefined" && /android/i.test(navigator.userAgent);
981
957
  }
982
958
  function getIsRemoteAssociationSupported() {
983
- return (typeof window !== 'undefined' &&
984
- window.isSecureContext &&
985
- typeof document !== 'undefined' &&
986
- !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
959
+ return typeof window !== "undefined" && window.isSecureContext && typeof document !== "undefined" && !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
987
960
  }
988
- // Source: https://github.com/anza-xyz/wallet-adapter/blob/master/packages/core/react/src/getEnvironment.ts#L14
989
- // This is the same implementation that gated MWA in the Anza wallet-adapter-react library.
990
961
  function isWebView(userAgentString) {
991
- return /(WebView|Version\/.+(Chrome)\/(\d+)\.(\d+)\.(\d+)\.(\d+)|; wv\).+(Chrome)\/(\d+)\.(\d+)\.(\d+)\.(\d+))/i.test(userAgentString);
962
+ return /(WebView|Version\/.+(Chrome)\/(\d+)\.(\d+)\.(\d+)\.(\d+)|; wv\).+(Chrome)\/(\d+)\.(\d+)\.(\d+)\.(\d+))/i.test(userAgentString);
963
+ }
964
+ function isSolanaMobileWebShell(userAgentString) {
965
+ return userAgentString.includes("Solana Mobile Web Shell");
992
966
  }
993
- // Source: https://web.dev/learn/pwa/detection/
994
967
  function getIsPwaLaunchedAsApp() {
995
- // Check for Android TWA
996
- const isAndroidTwa = typeof document !== 'undefined' && document.referrer.startsWith('android-app://');
997
- // Check for display-mode: standalone, fullscreen, or minimal-ui
998
- if (typeof window == 'undefined')
999
- return isAndroidTwa;
1000
- const isStandalone = window.matchMedia('(display-mode: standalone)').matches;
1001
- const isFullscreen = window.matchMedia('(display-mode: fullscreen)').matches;
1002
- const isMinimalUI = window.matchMedia('(display-mode: minimal-ui)').matches;
1003
- // App mode if any of these conditions are true
1004
- return isAndroidTwa || isStandalone || isFullscreen || isMinimalUI;
968
+ const isAndroidTwa = typeof document !== "undefined" && document.referrer.startsWith("android-app://");
969
+ if (typeof window == "undefined") return isAndroidTwa;
970
+ const isStandalone = window.matchMedia("(display-mode: standalone)").matches;
971
+ const isFullscreen = window.matchMedia("(display-mode: fullscreen)").matches;
972
+ const isMinimalUI = window.matchMedia("(display-mode: minimal-ui)").matches;
973
+ return isAndroidTwa || isStandalone || isFullscreen || isMinimalUI;
1005
974
  }
1006
975
  async function checkLocalNetworkAccessPermission() {
1007
- try {
1008
- let lnaPermission = await navigator.permissions.query({ name: "loopback-network" });
1009
- if (lnaPermission.state === "granted") {
1010
- // LNA permission already granted, continuing
1011
- return;
1012
- }
1013
- else if (lnaPermission.state === "denied") {
1014
- // LNA permission denied, aborting
1015
- const modal = new LoopbackPermissionBlockedModal();
1016
- modal.init();
1017
- modal.open();
1018
- throw new mobileWalletAdapterProtocol.SolanaMobileWalletAdapterError(mobileWalletAdapterProtocol.SolanaMobileWalletAdapterErrorCode.ERROR_LOOPBACK_ACCESS_BLOCKED, 'Local Network Access permission denied');
1019
- }
1020
- else if (lnaPermission.state === "prompt") {
1021
- // Show permission explainer to user, and wait for the permission to change
1022
- const modal = new LoopbackPermissionModal();
1023
- const updatedState = await new Promise((resolve, reject) => {
1024
- modal.addEventListener('close', (event) => {
1025
- if (event) {
1026
- reject(new mobileWalletAdapterProtocol.SolanaMobileWalletAdapterError(mobileWalletAdapterProtocol.SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_CANCELLED, 'Wallet connection cancelled by user', { event }));
1027
- }
1028
- });
1029
- lnaPermission.onchange = () => {
1030
- lnaPermission.onchange = null; // cleanup
1031
- resolve(lnaPermission.state);
1032
- };
1033
- modal.init();
1034
- modal.open();
1035
- });
1036
- if (updatedState === "granted") {
1037
- // User has granted the permission, now we need another click to continue
1038
- // Note: this is required to avoid being blocked by the browsers pop-up blocker
1039
- const modal = new LocalConnectionModal();
1040
- await new Promise((resolve, reject) => {
1041
- modal.addEventListener('close', (event) => {
1042
- if (event) {
1043
- reject(new mobileWalletAdapterProtocol.SolanaMobileWalletAdapterError(mobileWalletAdapterProtocol.SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_CANCELLED, 'Wallet connection cancelled by user', { event }));
1044
- }
1045
- });
1046
- modal.initWithCallback(async () => {
1047
- resolve(true);
1048
- });
1049
- modal.open();
1050
- });
1051
- return;
1052
- }
1053
- else {
1054
- // recurse, to avoid duplicating above logic
1055
- return await checkLocalNetworkAccessPermission();
1056
- }
1057
- }
1058
- // Shouldn't ever get here
1059
- throw new mobileWalletAdapterProtocol.SolanaMobileWalletAdapterError(mobileWalletAdapterProtocol.SolanaMobileWalletAdapterErrorCode.ERROR_LOOPBACK_ACCESS_BLOCKED, 'Local Network Access permission unknown');
1060
- }
1061
- catch (e) {
1062
- if (e instanceof TypeError &&
1063
- (e.message.includes('loopback-network') ||
1064
- e.message.includes('local-network-access'))) {
1065
- // LNA permission API not found, continuing
1066
- return;
1067
- }
1068
- // Re-throw existing adapter errors as-is
1069
- if (e instanceof mobileWalletAdapterProtocol.SolanaMobileWalletAdapterError) {
1070
- throw e;
1071
- }
1072
- // An unknown error occurred, wrap it
1073
- throw new mobileWalletAdapterProtocol.SolanaMobileWalletAdapterError(mobileWalletAdapterProtocol.SolanaMobileWalletAdapterErrorCode.ERROR_LOOPBACK_ACCESS_BLOCKED, e instanceof Error ? e.message : 'Local Network Access permission unknown');
1074
- }
1075
- }
1076
-
1077
- const SolanaMobileWalletAdapterWalletName = 'Mobile Wallet Adapter';
1078
- const SolanaMobileWalletAdapterRemoteWalletName = 'Remote Mobile Wallet Adapter';
976
+ if (typeof navigator !== "undefined" && isSolanaMobileWebShell(navigator.userAgent)) return;
977
+ try {
978
+ const lnaPermission = await navigator.permissions.query({ name: "loopback-network" });
979
+ if (lnaPermission.state === "granted") return;
980
+ else if (lnaPermission.state === "denied") {
981
+ const modal = new LoopbackPermissionBlockedModal();
982
+ modal.init();
983
+ modal.open();
984
+ throw new _solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterError(_solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterErrorCode.ERROR_LOOPBACK_ACCESS_BLOCKED, "Local Network Access permission denied");
985
+ } else if (lnaPermission.state === "prompt") {
986
+ const modal = new LoopbackPermissionModal();
987
+ if (await new Promise((resolve, reject) => {
988
+ modal.addEventListener("close", (event) => {
989
+ if (event) reject(new _solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterError(_solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_CANCELLED, "Wallet connection cancelled by user", { event }));
990
+ });
991
+ lnaPermission.onchange = () => {
992
+ lnaPermission.onchange = null;
993
+ resolve(lnaPermission.state);
994
+ };
995
+ modal.init();
996
+ modal.open();
997
+ }) === "granted") {
998
+ const modal = new LocalConnectionModal();
999
+ await new Promise((resolve, reject) => {
1000
+ modal.addEventListener("close", (event) => {
1001
+ if (event) reject(new _solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterError(_solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_CANCELLED, "Wallet connection cancelled by user", { event }));
1002
+ });
1003
+ modal.initWithCallback(async () => {
1004
+ resolve(true);
1005
+ });
1006
+ modal.open();
1007
+ });
1008
+ return;
1009
+ } else return await checkLocalNetworkAccessPermission();
1010
+ }
1011
+ throw new _solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterError(_solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterErrorCode.ERROR_LOOPBACK_ACCESS_BLOCKED, "Local Network Access permission unknown");
1012
+ } catch (e) {
1013
+ if (e instanceof TypeError && (e.message.includes("loopback-network") || e.message.includes("local-network-access"))) return;
1014
+ if (e instanceof _solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterError) throw e;
1015
+ throw new _solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterError(_solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterErrorCode.ERROR_LOOPBACK_ACCESS_BLOCKED, e instanceof Error ? e.message : "Local Network Access permission unknown");
1016
+ }
1017
+ }
1018
+ //#endregion
1019
+ //#region src/icon.ts
1020
+ const icon = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03IDIuNUgxN0MxNy44Mjg0IDIuNSAxOC41IDMuMTcxNTcgMTguNSA0VjIwQzE4LjUgMjAuODI4NCAxNy44Mjg0IDIxLjUgMTcgMjEuNUg3QzYuMTcxNTcgMjEuNSA1LjUgMjAuODI4NCA1LjUgMjBWNEM1LjUgMy4xNzE1NyA2LjE3MTU3IDIuNSA3IDIuNVpNMyA0QzMgMS43OTA4NiA0Ljc5MDg2IDAgNyAwSDE3QzE5LjIwOTEgMCAyMSAxLjc5MDg2IDIxIDRWMjBDMjEgMjIuMjA5MSAxOS4yMDkxIDI0IDE3IDI0SDdDNC43OTA4NiAyNCAzIDIyLjIwOTEgMyAyMFY0Wk0xMSA0LjYxNTM4QzEwLjQ0NzcgNC42MTUzOCAxMCA1LjA2MzEgMTAgNS42MTUzOFY2LjM4NDYyQzEwIDYuOTM2OSAxMC40NDc3IDcuMzg0NjIgMTEgNy4zODQ2MkgxM0MxMy41NTIzIDcuMzg0NjIgMTQgNi45MzY5IDE0IDYuMzg0NjJWNS42MTUzOEMxNCA1LjA2MzEgMTMuNTUyMyA0LjYxNTM4IDEzIDQuNjE1MzhIMTFaIiBmaWxsPSIjRENCOEZGIi8+Cjwvc3ZnPgo=";
1021
+ //#endregion
1022
+ //#region src/wallet.ts
1023
+ const SolanaMobileWalletAdapterWalletName = "Mobile Wallet Adapter";
1024
+ const SolanaMobileWalletAdapterRemoteWalletName = "Remote Mobile Wallet Adapter";
1079
1025
  const SIGNATURE_LENGTH_IN_BYTES = 64;
1080
- const DEFAULT_FEATURES = [walletStandardFeatures.SolanaSignAndSendTransaction, walletStandardFeatures.SolanaSignTransaction, walletStandardFeatures.SolanaSignMessage, walletStandardFeatures.SolanaSignIn];
1081
- const WALLET_ASSOCIATION_TIMEOUT = 30_000;
1082
- class LocalSolanaMobileWalletAdapterWallet {
1083
- #listeners = {};
1084
- #version = '1.0.0'; // wallet-standard version
1085
- #name = SolanaMobileWalletAdapterWalletName;
1086
- #url = 'https://solanamobile.com/wallets';
1087
- #icon = icon;
1088
- #appIdentity;
1089
- #authorization;
1090
- #authorizationCache;
1091
- #connecting = false;
1092
- /**
1093
- * Every time the connection is recycled in some way (eg. `disconnect()` is called)
1094
- * increment this and use it to make sure that `transact` calls from the previous
1095
- * 'generation' don't continue to do work and throw exceptions.
1096
- */
1097
- #connectionGeneration = 0;
1098
- #chains = [];
1099
- #chainSelector;
1100
- #optionalFeatures;
1101
- #onWalletNotFound;
1102
- get version() {
1103
- return this.#version;
1104
- }
1105
- get name() {
1106
- return this.#name;
1107
- }
1108
- get url() {
1109
- return this.#url;
1110
- }
1111
- get icon() {
1112
- return this.#icon;
1113
- }
1114
- get chains() {
1115
- return this.#chains;
1116
- }
1117
- get features() {
1118
- return {
1119
- [features.StandardConnect]: {
1120
- version: '1.0.0',
1121
- connect: this.#connect,
1122
- },
1123
- [features.StandardDisconnect]: {
1124
- version: '1.0.0',
1125
- disconnect: this.#disconnect,
1126
- },
1127
- [features.StandardEvents]: {
1128
- version: '1.0.0',
1129
- on: this.#on,
1130
- },
1131
- [walletStandardFeatures.SolanaSignMessage]: {
1132
- version: '1.0.0',
1133
- signMessage: this.#signMessage,
1134
- },
1135
- [walletStandardFeatures.SolanaSignIn]: {
1136
- version: '1.0.0',
1137
- signIn: this.#signIn,
1138
- },
1139
- ...this.#optionalFeatures,
1140
- };
1141
- }
1142
- get accounts() {
1143
- return this.#authorization?.accounts ?? [];
1144
- }
1145
- constructor(config) {
1146
- this.#authorizationCache = config.authorizationCache;
1147
- this.#appIdentity = config.appIdentity;
1148
- this.#chains = config.chains;
1149
- this.#chainSelector = config.chainSelector;
1150
- this.#onWalletNotFound = config.onWalletNotFound;
1151
- this.#optionalFeatures = {
1152
- // In MWA 1.0, signAndSend is optional and signTransaction is mandatory. Whereas in MWA 2.0+,
1153
- // signAndSend is mandatory and signTransaction is optional (and soft deprecated). As of mid
1154
- // 2025, all MWA wallets support both signAndSendTransaction and signTransaction so its safe
1155
- // assume both are supported here. The features will be updated based on the actual connected
1156
- // wallets capabilities during connection regardless, so this is safe.
1157
- [walletStandardFeatures.SolanaSignAndSendTransaction]: {
1158
- version: '1.0.0',
1159
- supportedTransactionVersions: ['legacy', 0],
1160
- signAndSendTransaction: this.#signAndSendTransaction,
1161
- },
1162
- [walletStandardFeatures.SolanaSignTransaction]: {
1163
- version: '1.0.0',
1164
- supportedTransactionVersions: ['legacy', 0],
1165
- signTransaction: this.#signTransaction,
1166
- },
1167
- };
1168
- }
1169
- get connected() {
1170
- return !!this.#authorization;
1171
- }
1172
- get isAuthorized() {
1173
- return !!this.#authorization;
1174
- }
1175
- get currentAuthorization() {
1176
- return this.#authorization;
1177
- }
1178
- get cachedAuthorizationResult() {
1179
- return this.#authorizationCache.get();
1180
- }
1181
- #on = (event, listener) => {
1182
- this.#listeners[event]?.push(listener) || (this.#listeners[event] = [listener]);
1183
- return () => this.#off(event, listener);
1184
- };
1185
- #emit(event, ...args) {
1186
- // eslint-disable-next-line prefer-spread
1187
- this.#listeners[event]?.forEach((listener) => listener.apply(null, args));
1188
- }
1189
- #off(event, listener) {
1190
- this.#listeners[event] = this.#listeners[event]?.filter((existingListener) => listener !== existingListener);
1191
- }
1192
- #connect = async ({ silent } = {}) => {
1193
- if (this.#connecting || this.connected) {
1194
- return { accounts: this.accounts };
1195
- }
1196
- this.#connecting = true;
1197
- try {
1198
- if (silent) {
1199
- const cachedAuthorization = await this.#authorizationCache.get();
1200
- if (cachedAuthorization) {
1201
- await this.#handleWalletCapabilitiesResult(cachedAuthorization.capabilities);
1202
- await this.#handleAuthorizationResult(cachedAuthorization);
1203
- }
1204
- else {
1205
- return { accounts: this.accounts };
1206
- }
1207
- }
1208
- else {
1209
- await this.#performAuthorization();
1210
- }
1211
- }
1212
- catch (e) {
1213
- throw new Error((e instanceof Error && e.message) || 'Unknown error');
1214
- }
1215
- finally {
1216
- this.#connecting = false;
1217
- }
1218
- return { accounts: this.accounts };
1219
- };
1220
- #performAuthorization = async (signInPayload) => {
1221
- try {
1222
- const cachedAuthorizationResult = await this.#authorizationCache.get();
1223
- if (cachedAuthorizationResult) {
1224
- // TODO: Evaluate whether there's any threat to not `awaiting` this expression
1225
- this.#handleAuthorizationResult(cachedAuthorizationResult);
1226
- return cachedAuthorizationResult;
1227
- }
1228
- const selectedChain = await this.#chainSelector.select(this.#chains);
1229
- return await this.#transact(async (wallet) => {
1230
- const [capabilities, mwaAuthorizationResult] = await Promise.all([
1231
- wallet.getCapabilities(),
1232
- wallet.authorize({
1233
- chain: selectedChain,
1234
- identity: this.#appIdentity,
1235
- sign_in_payload: signInPayload,
1236
- })
1237
- ]);
1238
- const accounts = this.#accountsToWalletStandardAccounts(mwaAuthorizationResult.accounts);
1239
- const authorization = { ...mwaAuthorizationResult,
1240
- accounts, chain: selectedChain, capabilities: capabilities };
1241
- // TODO: Evaluate whether there's any threat to not `awaiting` this expression
1242
- Promise.all([
1243
- this.#handleWalletCapabilitiesResult(capabilities),
1244
- this.#authorizationCache.set(authorization),
1245
- this.#handleAuthorizationResult(authorization),
1246
- ]);
1247
- return authorization;
1248
- });
1249
- }
1250
- catch (e) {
1251
- throw new Error((e instanceof Error && e.message) || 'Unknown error');
1252
- }
1253
- };
1254
- #handleAuthorizationResult = async (authorization) => {
1255
- const didPublicKeysChange =
1256
- // Case 1: We started from having no authorization.
1257
- this.#authorization == null ||
1258
- // Case 2: The number of authorized accounts changed.
1259
- this.#authorization?.accounts.length !== authorization.accounts.length ||
1260
- // Case 3: The new list of addresses isn't exactly the same as the old list, in the same order.
1261
- this.#authorization.accounts.some((account, ii) => account.address !== authorization.accounts[ii].address);
1262
- this.#authorization = authorization;
1263
- if (didPublicKeysChange) {
1264
- this.#emit('change', { accounts: this.accounts });
1265
- }
1266
- };
1267
- #handleWalletCapabilitiesResult = async (capabilities) => {
1268
- // TODO: investigate why using SolanaSignTransactions constant breaks treeshaking
1269
- const supportsSignTransaction = capabilities.features.includes('solana:signTransactions'); //SolanaSignTransactions);
1270
- const supportsSignAndSendTransaction = capabilities.supports_sign_and_send_transactions;
1271
- const didCapabilitiesChange = walletStandardFeatures.SolanaSignAndSendTransaction in this.features !== supportsSignAndSendTransaction ||
1272
- walletStandardFeatures.SolanaSignTransaction in this.features !== supportsSignTransaction;
1273
- this.#optionalFeatures = {
1274
- ...((supportsSignAndSendTransaction || (!supportsSignAndSendTransaction && !supportsSignTransaction)) && {
1275
- [walletStandardFeatures.SolanaSignAndSendTransaction]: {
1276
- version: '1.0.0',
1277
- supportedTransactionVersions: ['legacy', 0],
1278
- signAndSendTransaction: this.#signAndSendTransaction,
1279
- },
1280
- }),
1281
- ...(supportsSignTransaction && {
1282
- [walletStandardFeatures.SolanaSignTransaction]: {
1283
- version: '1.0.0',
1284
- supportedTransactionVersions: ['legacy', 0],
1285
- signTransaction: this.#signTransaction,
1286
- },
1287
- }),
1288
- };
1289
- if (didCapabilitiesChange) {
1290
- this.#emit('change', { features: this.features });
1291
- }
1292
- };
1293
- #performReauthorization = async (wallet, authToken, chain) => {
1294
- try {
1295
- const [capabilities, mwaAuthorizationResult] = await Promise.all([
1296
- this.#authorization?.capabilities ?? await wallet.getCapabilities(),
1297
- wallet.authorize({
1298
- auth_token: authToken,
1299
- identity: this.#appIdentity,
1300
- chain: chain
1301
- })
1302
- ]);
1303
- const accounts = this.#accountsToWalletStandardAccounts(mwaAuthorizationResult.accounts);
1304
- const authorization = { ...mwaAuthorizationResult,
1305
- accounts: accounts, chain: chain, capabilities: capabilities
1306
- };
1307
- // TODO: Evaluate whether there's any threat to not `awaiting` this expression
1308
- Promise.all([
1309
- this.#authorizationCache.set(authorization),
1310
- this.#handleAuthorizationResult(authorization),
1311
- ]);
1312
- }
1313
- catch (e) {
1314
- this.#disconnect();
1315
- throw new Error((e instanceof Error && e.message) || 'Unknown error');
1316
- }
1317
- };
1318
- #disconnect = async () => {
1319
- this.#authorizationCache.clear(); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
1320
- this.#connecting = false;
1321
- this.#connectionGeneration++;
1322
- this.#authorization = undefined;
1323
- this.#emit('change', { accounts: this.accounts });
1324
- };
1325
- #transact = async (callback) => {
1326
- const walletUriBase = this.#authorization?.wallet_uri_base;
1327
- const config = walletUriBase ? { baseUri: walletUriBase } : undefined;
1328
- const currentConnectionGeneration = this.#connectionGeneration;
1329
- const loadingSpinner = new EmbeddedLoadingSpinner();
1330
- try {
1331
- // check that we have permissions for local app connections, then run
1332
- // wallet association (transact). In case the user manually cancels
1333
- // the wallet association, cancel the connection after a timeout.
1334
- let associating = true;
1335
- let timeout = undefined;
1336
- const result = await Promise.race([
1337
- checkLocalNetworkAccessPermission()
1338
- .then(async () => {
1339
- // Begin local connection, show loading spinner while we connect
1340
- loadingSpinner.init();
1341
- const { wallet, close } = await mobileWalletAdapterProtocol.startScenario(config);
1342
- loadingSpinner.addEventListener('close', (event) => { if (event)
1343
- close(); });
1344
- loadingSpinner.open();
1345
- const result = await callback(await wallet);
1346
- loadingSpinner.close();
1347
- close();
1348
- return result;
1349
- }),
1350
- new Promise((_, reject) => {
1351
- timeout = setTimeout(() => {
1352
- if (associating) { // only timeout during association
1353
- reject(new mobileWalletAdapterProtocol.SolanaMobileWalletAdapterError(mobileWalletAdapterProtocol.SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_CANCELLED, 'Wallet connection timed out', { event: undefined }));
1354
- }
1355
- }, WALLET_ASSOCIATION_TIMEOUT);
1356
- })
1357
- ]);
1358
- clearTimeout(timeout);
1359
- return result;
1360
- }
1361
- catch (e) {
1362
- loadingSpinner.close();
1363
- if (this.#connectionGeneration !== currentConnectionGeneration) {
1364
- await new Promise(() => { }); // Never resolve.
1365
- }
1366
- if (e instanceof Error &&
1367
- e.name === 'SolanaMobileWalletAdapterError' &&
1368
- e.code === 'ERROR_WALLET_NOT_FOUND') {
1369
- await this.#onWalletNotFound(this);
1370
- }
1371
- throw e;
1372
- }
1373
- };
1374
- #assertIsAuthorized = () => {
1375
- if (!this.#authorization)
1376
- throw new Error('Wallet not connected');
1377
- return { authToken: this.#authorization.auth_token, chain: this.#authorization.chain };
1378
- };
1379
- #accountsToWalletStandardAccounts = (accounts) => {
1380
- return accounts.map((account) => {
1381
- const publicKey = toUint8Array(account.address);
1382
- return {
1383
- address: base58.encode(publicKey),
1384
- publicKey,
1385
- label: account.label,
1386
- icon: account.icon,
1387
- chains: account.chains ?? this.#chains,
1388
- // TODO: get supported features from getCapabilities API
1389
- features: account.features ?? DEFAULT_FEATURES
1390
- };
1391
- });
1392
- };
1393
- #performSignTransactions = async (transactions) => {
1394
- const { authToken, chain } = this.#assertIsAuthorized();
1395
- try {
1396
- const base64Transactions = transactions.map((tx) => { return fromUint8Array(tx); });
1397
- return await this.#transact(async (wallet) => {
1398
- await this.#performReauthorization(wallet, authToken, chain);
1399
- const signedTransactions = (await wallet.signTransactions({
1400
- payloads: base64Transactions,
1401
- })).signed_payloads.map(toUint8Array);
1402
- return signedTransactions;
1403
- });
1404
- }
1405
- catch (e) {
1406
- throw new Error((e instanceof Error && e.message) || 'Unknown error');
1407
- }
1408
- };
1409
- #performSignAndSendTransaction = async (transaction, options) => {
1410
- const { authToken, chain } = this.#assertIsAuthorized();
1411
- try {
1412
- return await this.#transact(async (wallet) => {
1413
- const [capabilities, _1] = await Promise.all([
1414
- wallet.getCapabilities(),
1415
- this.#performReauthorization(wallet, authToken, chain)
1416
- ]);
1417
- if (capabilities.supports_sign_and_send_transactions) {
1418
- const base64Transaction = fromUint8Array(transaction);
1419
- const signatures = (await wallet.signAndSendTransactions({
1420
- ...options,
1421
- payloads: [base64Transaction],
1422
- })).signatures.map(toUint8Array);
1423
- return signatures[0];
1424
- }
1425
- else {
1426
- throw new Error('connected wallet does not support signAndSendTransaction');
1427
- }
1428
- });
1429
- }
1430
- catch (e) {
1431
- throw new Error((e instanceof Error && e.message) || 'Unknown error');
1432
- }
1433
- };
1434
- #signAndSendTransaction = async (...inputs) => {
1435
- const outputs = [];
1436
- for (const input of inputs) {
1437
- const signature = await this.#performSignAndSendTransaction(input.transaction, input.options);
1438
- outputs.push({ signature });
1439
- }
1440
- return outputs;
1441
- };
1442
- #signTransaction = async (...inputs) => {
1443
- return (await this.#performSignTransactions(inputs.map(({ transaction }) => transaction)))
1444
- .map((signedTransaction) => {
1445
- return { signedTransaction };
1446
- });
1447
- };
1448
- #signMessage = async (...inputs) => {
1449
- const { authToken, chain } = this.#assertIsAuthorized();
1450
- const addresses = inputs.map(({ account }) => fromUint8Array(new Uint8Array(account.publicKey)));
1451
- const messages = inputs.map(({ message }) => fromUint8Array(message));
1452
- try {
1453
- return await this.#transact(async (wallet) => {
1454
- await this.#performReauthorization(wallet, authToken, chain);
1455
- const signedMessages = (await wallet.signMessages({
1456
- addresses: addresses,
1457
- payloads: messages,
1458
- })).signed_payloads.map(toUint8Array);
1459
- return signedMessages.map((signedMessage) => {
1460
- return { signedMessage: signedMessage, signature: signedMessage.slice(-SIGNATURE_LENGTH_IN_BYTES) };
1461
- });
1462
- });
1463
- }
1464
- catch (e) {
1465
- throw new Error((e instanceof Error && e.message) || 'Unknown error');
1466
- }
1467
- };
1468
- #signIn = async (...inputs) => {
1469
- const outputs = [];
1470
- if (inputs.length > 1) {
1471
- for (const input of inputs) {
1472
- outputs.push(await this.#performSignIn(input));
1473
- }
1474
- }
1475
- else {
1476
- return [await this.#performSignIn(inputs[0])];
1477
- }
1478
- return outputs;
1479
- };
1480
- #performSignIn = async (input) => {
1481
- this.#connecting = true;
1482
- try {
1483
- const authorizationResult = await this.#performAuthorization({
1484
- ...input,
1485
- domain: input?.domain ?? window.location.host
1486
- });
1487
- if (!authorizationResult.sign_in_result) {
1488
- throw new Error("Sign in failed, no sign in result returned by wallet");
1489
- }
1490
- const signedInAddress = authorizationResult.sign_in_result.address;
1491
- const signedInAccount = authorizationResult.accounts.find(acc => acc.address == signedInAddress);
1492
- return {
1493
- account: {
1494
- ...signedInAccount ?? {
1495
- address: base58.encode(toUint8Array(signedInAddress))
1496
- },
1497
- publicKey: toUint8Array(signedInAddress),
1498
- chains: signedInAccount?.chains ?? this.#chains,
1499
- features: signedInAccount?.features ?? authorizationResult.capabilities.features
1500
- },
1501
- signedMessage: toUint8Array(authorizationResult.sign_in_result.signed_message),
1502
- signature: toUint8Array(authorizationResult.sign_in_result.signature)
1503
- };
1504
- }
1505
- catch (e) {
1506
- throw new Error((e instanceof Error && e.message) || 'Unknown error');
1507
- }
1508
- finally {
1509
- this.#connecting = false;
1510
- }
1511
- };
1512
- }
1513
- class RemoteSolanaMobileWalletAdapterWallet {
1514
- #listeners = {};
1515
- #version = '1.0.0'; // wallet-standard version
1516
- #name = SolanaMobileWalletAdapterRemoteWalletName;
1517
- #url = 'https://solanamobile.com/wallets';
1518
- #icon = icon;
1519
- #appIdentity;
1520
- #authorization;
1521
- #authorizationCache;
1522
- #connecting = false;
1523
- /**
1524
- * Every time the connection is recycled in some way (eg. `disconnect()` is called)
1525
- * increment this and use it to make sure that `transact` calls from the previous
1526
- * 'generation' don't continue to do work and throw exceptions.
1527
- */
1528
- #connectionGeneration = 0;
1529
- #chains = [];
1530
- #chainSelector;
1531
- #optionalFeatures;
1532
- #onWalletNotFound;
1533
- #hostAuthority;
1534
- #session;
1535
- get version() {
1536
- return this.#version;
1537
- }
1538
- get name() {
1539
- return this.#name;
1540
- }
1541
- get url() {
1542
- return this.#url;
1543
- }
1544
- get icon() {
1545
- return this.#icon;
1546
- }
1547
- get chains() {
1548
- return this.#chains;
1549
- }
1550
- get features() {
1551
- return {
1552
- [features.StandardConnect]: {
1553
- version: '1.0.0',
1554
- connect: this.#connect,
1555
- },
1556
- [features.StandardDisconnect]: {
1557
- version: '1.0.0',
1558
- disconnect: this.#disconnect,
1559
- },
1560
- [features.StandardEvents]: {
1561
- version: '1.0.0',
1562
- on: this.#on,
1563
- },
1564
- [walletStandardFeatures.SolanaSignMessage]: {
1565
- version: '1.0.0',
1566
- signMessage: this.#signMessage,
1567
- },
1568
- [walletStandardFeatures.SolanaSignIn]: {
1569
- version: '1.0.0',
1570
- signIn: this.#signIn,
1571
- },
1572
- ...this.#optionalFeatures,
1573
- };
1574
- }
1575
- get accounts() {
1576
- return this.#authorization?.accounts ?? [];
1577
- }
1578
- constructor(config) {
1579
- this.#authorizationCache = config.authorizationCache;
1580
- this.#appIdentity = config.appIdentity;
1581
- this.#chains = config.chains;
1582
- this.#chainSelector = config.chainSelector;
1583
- this.#hostAuthority = config.remoteHostAuthority;
1584
- this.#onWalletNotFound = config.onWalletNotFound;
1585
- this.#optionalFeatures = {
1586
- // In MWA 1.0, signAndSend is optional and signTransaction is mandatory. Whereas in MWA 2.0+,
1587
- // signAndSend is mandatory and signTransaction is optional (and soft deprecated). As of mid
1588
- // 2025, all MWA wallets support both signAndSendTransaction and signTransaction so its safe
1589
- // assume both are supported here. The features will be updated based on the actual connected
1590
- // wallets capabilities during connection regardless, so this is safe.
1591
- [walletStandardFeatures.SolanaSignAndSendTransaction]: {
1592
- version: '1.0.0',
1593
- supportedTransactionVersions: ['legacy', 0],
1594
- signAndSendTransaction: this.#signAndSendTransaction,
1595
- },
1596
- [walletStandardFeatures.SolanaSignTransaction]: {
1597
- version: '1.0.0',
1598
- supportedTransactionVersions: ['legacy', 0],
1599
- signTransaction: this.#signTransaction,
1600
- },
1601
- };
1602
- }
1603
- get connected() {
1604
- return !!this.#session && !!this.#authorization;
1605
- }
1606
- get isAuthorized() {
1607
- return !!this.#authorization;
1608
- }
1609
- get currentAuthorization() {
1610
- return this.#authorization;
1611
- }
1612
- get cachedAuthorizationResult() {
1613
- return this.#authorizationCache.get();
1614
- }
1615
- #on = (event, listener) => {
1616
- this.#listeners[event]?.push(listener) || (this.#listeners[event] = [listener]);
1617
- return () => this.#off(event, listener);
1618
- };
1619
- #emit(event, ...args) {
1620
- // eslint-disable-next-line prefer-spread
1621
- this.#listeners[event]?.forEach((listener) => listener.apply(null, args));
1622
- }
1623
- #off(event, listener) {
1624
- this.#listeners[event] = this.#listeners[event]?.filter((existingListener) => listener !== existingListener);
1625
- }
1626
- #connect = async ({ silent } = {}) => {
1627
- if (this.#connecting || this.connected) {
1628
- return { accounts: this.accounts };
1629
- }
1630
- this.#connecting = true;
1631
- try {
1632
- await this.#performAuthorization();
1633
- }
1634
- catch (e) {
1635
- throw new Error((e instanceof Error && e.message) || 'Unknown error');
1636
- }
1637
- finally {
1638
- this.#connecting = false;
1639
- }
1640
- return { accounts: this.accounts };
1641
- };
1642
- #performAuthorization = async (signInPayload) => {
1643
- try {
1644
- const cachedAuthorizationResult = await this.#authorizationCache.get();
1645
- if (cachedAuthorizationResult) {
1646
- // TODO: Evaluate whether there's any threat to not `awaiting` this expression
1647
- this.#handleAuthorizationResult(cachedAuthorizationResult);
1648
- return cachedAuthorizationResult;
1649
- }
1650
- if (this.#session)
1651
- this.#session = undefined;
1652
- const selectedChain = await this.#chainSelector.select(this.#chains);
1653
- return await this.#transact(async (wallet) => {
1654
- const [capabilities, mwaAuthorizationResult] = await Promise.all([
1655
- wallet.getCapabilities(),
1656
- wallet.authorize({
1657
- chain: selectedChain,
1658
- identity: this.#appIdentity,
1659
- sign_in_payload: signInPayload,
1660
- })
1661
- ]);
1662
- const accounts = this.#accountsToWalletStandardAccounts(mwaAuthorizationResult.accounts);
1663
- const authorizationResult = { ...mwaAuthorizationResult,
1664
- accounts, chain: selectedChain, capabilities: capabilities };
1665
- // TODO: Evaluate whether there's any threat to not `awaiting` this expression
1666
- Promise.all([
1667
- this.#handleWalletCapabilitiesResult(capabilities),
1668
- this.#authorizationCache.set(authorizationResult),
1669
- this.#handleAuthorizationResult(authorizationResult),
1670
- ]);
1671
- return authorizationResult;
1672
- });
1673
- }
1674
- catch (e) {
1675
- throw new Error((e instanceof Error && e.message) || 'Unknown error');
1676
- }
1677
- };
1678
- #handleAuthorizationResult = async (authorization) => {
1679
- const didPublicKeysChange =
1680
- // Case 1: We started from having no authorization.
1681
- this.#authorization == null ||
1682
- // Case 2: The number of authorized accounts changed.
1683
- this.#authorization?.accounts.length !== authorization.accounts.length ||
1684
- // Case 3: The new list of addresses isn't exactly the same as the old list, in the same order.
1685
- this.#authorization.accounts.some((account, ii) => account.address !== authorization.accounts[ii].address);
1686
- this.#authorization = authorization;
1687
- if (didPublicKeysChange) {
1688
- this.#emit('change', { accounts: this.accounts });
1689
- }
1690
- };
1691
- #handleWalletCapabilitiesResult = async (capabilities) => {
1692
- // TODO: investigate why using SolanaSignTransactions constant breaks treeshaking
1693
- const supportsSignTransaction = capabilities.features.includes('solana:signTransactions'); //SolanaSignTransactions);
1694
- const supportsSignAndSendTransaction = capabilities.supports_sign_and_send_transactions ||
1695
- capabilities.features.includes('solana:signAndSendTransaction');
1696
- const didCapabilitiesChange = walletStandardFeatures.SolanaSignAndSendTransaction in this.features !== supportsSignAndSendTransaction ||
1697
- walletStandardFeatures.SolanaSignTransaction in this.features !== supportsSignTransaction;
1698
- this.#optionalFeatures = {
1699
- ...(supportsSignAndSendTransaction && {
1700
- [walletStandardFeatures.SolanaSignAndSendTransaction]: {
1701
- version: '1.0.0',
1702
- supportedTransactionVersions: capabilities.supported_transaction_versions,
1703
- signAndSendTransaction: this.#signAndSendTransaction,
1704
- },
1705
- }),
1706
- ...(supportsSignTransaction && {
1707
- [walletStandardFeatures.SolanaSignTransaction]: {
1708
- version: '1.0.0',
1709
- supportedTransactionVersions: capabilities.supported_transaction_versions,
1710
- signTransaction: this.#signTransaction,
1711
- },
1712
- }),
1713
- };
1714
- if (didCapabilitiesChange) {
1715
- this.#emit('change', { features: this.features });
1716
- }
1717
- };
1718
- #performReauthorization = async (wallet, authToken, chain) => {
1719
- try {
1720
- const [capabilities, mwaAuthorizationResult] = await Promise.all([
1721
- this.#authorization?.capabilities ?? await wallet.getCapabilities(),
1722
- wallet.authorize({
1723
- auth_token: authToken,
1724
- identity: this.#appIdentity,
1725
- chain: chain
1726
- })
1727
- ]);
1728
- const accounts = this.#accountsToWalletStandardAccounts(mwaAuthorizationResult.accounts);
1729
- const authorization = { ...mwaAuthorizationResult,
1730
- accounts: accounts, chain: chain, capabilities: capabilities };
1731
- // TODO: Evaluate whether there's any threat to not `awaiting` this expression
1732
- Promise.all([
1733
- this.#authorizationCache.set(authorization),
1734
- this.#handleAuthorizationResult(authorization),
1735
- ]);
1736
- }
1737
- catch (e) {
1738
- this.#disconnect();
1739
- throw new Error((e instanceof Error && e.message) || 'Unknown error');
1740
- }
1741
- };
1742
- #disconnect = async () => {
1743
- this.#session?.close();
1744
- this.#authorizationCache.clear(); // TODO: Evaluate whether there's any threat to not `awaiting` this expression
1745
- this.#connecting = false;
1746
- this.#connectionGeneration++;
1747
- this.#authorization = undefined;
1748
- this.#session = undefined;
1749
- this.#emit('change', { accounts: this.accounts });
1750
- };
1751
- #transact = async (callback) => {
1752
- const walletUriBase = this.#authorization?.wallet_uri_base;
1753
- const baseConfig = walletUriBase ? { baseUri: walletUriBase } : undefined;
1754
- const remoteConfig = { ...baseConfig, remoteHostAuthority: this.#hostAuthority };
1755
- const currentConnectionGeneration = this.#connectionGeneration;
1756
- const modal = new RemoteConnectionModal();
1757
- if (this.#session) {
1758
- return callback(this.#session.wallet);
1759
- }
1760
- try {
1761
- // Begin remote connection, show modal with loading anim while we connect
1762
- modal.init();
1763
- modal.open();
1764
- const { associationUrl, close, wallet } = await mobileWalletAdapterProtocol.startRemoteScenario(remoteConfig);
1765
- // Reflector is now connected, update the connection modal with qr code
1766
- const removeCloseListener = modal.addEventListener('close', (event) => {
1767
- if (event)
1768
- close();
1769
- });
1770
- modal.populateQRCode(associationUrl.toString());
1771
- // Wait for the wallet to be connected, then close the connection modal and proceed
1772
- this.#session = { close, wallet: await wallet };
1773
- removeCloseListener();
1774
- modal.close();
1775
- return await callback(this.#session.wallet);
1776
- }
1777
- catch (e) {
1778
- modal.close();
1779
- if (this.#connectionGeneration !== currentConnectionGeneration) {
1780
- await new Promise(() => { }); // Never resolve.
1781
- }
1782
- if (e instanceof Error &&
1783
- e.name === 'SolanaMobileWalletAdapterError' &&
1784
- e.code === 'ERROR_WALLET_NOT_FOUND') {
1785
- await this.#onWalletNotFound(this);
1786
- }
1787
- throw e;
1788
- }
1789
- };
1790
- #assertIsAuthorized = () => {
1791
- if (!this.#authorization)
1792
- throw new Error('Wallet not connected');
1793
- return { authToken: this.#authorization.auth_token, chain: this.#authorization.chain };
1794
- };
1795
- #accountsToWalletStandardAccounts = (accounts) => {
1796
- return accounts.map((account) => {
1797
- const publicKey = toUint8Array(account.address);
1798
- return {
1799
- address: base58.encode(publicKey),
1800
- publicKey,
1801
- label: account.label,
1802
- icon: account.icon,
1803
- chains: account.chains ?? this.#chains,
1804
- // TODO: get supported features from getCapabilities API
1805
- features: account.features ?? DEFAULT_FEATURES
1806
- };
1807
- });
1808
- };
1809
- #performSignTransactions = async (transactions) => {
1810
- const { authToken, chain } = this.#assertIsAuthorized();
1811
- try {
1812
- return await this.#transact(async (wallet) => {
1813
- await this.#performReauthorization(wallet, authToken, chain);
1814
- const signedTransactions = (await wallet.signTransactions({
1815
- payloads: transactions.map(fromUint8Array),
1816
- })).signed_payloads.map(toUint8Array);
1817
- return signedTransactions;
1818
- });
1819
- }
1820
- catch (e) {
1821
- throw new Error((e instanceof Error && e.message) || 'Unknown error');
1822
- }
1823
- };
1824
- #performSignAndSendTransaction = async (transaction, options) => {
1825
- const { authToken, chain } = this.#assertIsAuthorized();
1826
- try {
1827
- return await this.#transact(async (wallet) => {
1828
- const [capabilities, _1] = await Promise.all([
1829
- wallet.getCapabilities(),
1830
- this.#performReauthorization(wallet, authToken, chain)
1831
- ]);
1832
- if (capabilities.supports_sign_and_send_transactions) {
1833
- const signatures = (await wallet.signAndSendTransactions({
1834
- ...options,
1835
- payloads: [fromUint8Array(transaction)],
1836
- })).signatures.map(toUint8Array);
1837
- return signatures[0];
1838
- }
1839
- else {
1840
- throw new Error('connected wallet does not support signAndSendTransaction');
1841
- }
1842
- });
1843
- }
1844
- catch (e) {
1845
- throw new Error((e instanceof Error && e.message) || 'Unknown error');
1846
- }
1847
- };
1848
- #signAndSendTransaction = async (...inputs) => {
1849
- const outputs = [];
1850
- for (const input of inputs) {
1851
- const signature = (await this.#performSignAndSendTransaction(input.transaction, input.options));
1852
- outputs.push({ signature });
1853
- }
1854
- return outputs;
1855
- };
1856
- #signTransaction = async (...inputs) => {
1857
- return (await this.#performSignTransactions(inputs.map(({ transaction }) => transaction)))
1858
- .map((signedTransaction) => {
1859
- return { signedTransaction };
1860
- });
1861
- };
1862
- #signMessage = async (...inputs) => {
1863
- const { authToken, chain } = this.#assertIsAuthorized();
1864
- const addresses = inputs.map(({ account }) => fromUint8Array(new Uint8Array(account.publicKey)));
1865
- const messages = inputs.map(({ message }) => fromUint8Array(message));
1866
- try {
1867
- return await this.#transact(async (wallet) => {
1868
- await this.#performReauthorization(wallet, authToken, chain);
1869
- const signedMessages = (await wallet.signMessages({
1870
- addresses: addresses,
1871
- payloads: messages,
1872
- })).signed_payloads.map(toUint8Array);
1873
- return signedMessages.map((signedMessage) => {
1874
- return { signedMessage: signedMessage, signature: signedMessage.slice(-SIGNATURE_LENGTH_IN_BYTES) };
1875
- });
1876
- });
1877
- }
1878
- catch (e) {
1879
- throw new Error((e instanceof Error && e.message) || 'Unknown error');
1880
- }
1881
- };
1882
- #signIn = async (...inputs) => {
1883
- const outputs = [];
1884
- if (inputs.length > 1) {
1885
- for (const input of inputs) {
1886
- outputs.push(await this.#performSignIn(input));
1887
- }
1888
- }
1889
- else {
1890
- return [await this.#performSignIn(inputs[0])];
1891
- }
1892
- return outputs;
1893
- };
1894
- #performSignIn = async (input) => {
1895
- this.#connecting = true;
1896
- try {
1897
- const authorizationResult = await this.#performAuthorization({
1898
- ...input,
1899
- domain: input?.domain ?? window.location.host
1900
- });
1901
- if (!authorizationResult.sign_in_result) {
1902
- throw new Error("Sign in failed, no sign in result returned by wallet");
1903
- }
1904
- const signedInAddress = authorizationResult.sign_in_result.address;
1905
- const signedInAccount = authorizationResult.accounts.find(acc => acc.address == signedInAddress);
1906
- return {
1907
- account: {
1908
- ...signedInAccount ?? {
1909
- address: base58.encode(toUint8Array(signedInAddress))
1910
- },
1911
- publicKey: toUint8Array(signedInAddress),
1912
- chains: signedInAccount?.chains ?? this.#chains,
1913
- features: signedInAccount?.features ?? authorizationResult.capabilities.features
1914
- },
1915
- signedMessage: toUint8Array(authorizationResult.sign_in_result.signed_message),
1916
- signature: toUint8Array(authorizationResult.sign_in_result.signature)
1917
- };
1918
- }
1919
- catch (e) {
1920
- throw new Error((e instanceof Error && e.message) || 'Unknown error');
1921
- }
1922
- finally {
1923
- this.#connecting = false;
1924
- }
1925
- };
1926
- }
1927
-
1026
+ const DEFAULT_FEATURES = [
1027
+ _solana_wallet_standard_features.SolanaSignAndSendTransaction,
1028
+ _solana_wallet_standard_features.SolanaSignTransaction,
1029
+ _solana_wallet_standard_features.SolanaSignMessage,
1030
+ _solana_wallet_standard_features.SolanaSignIn
1031
+ ];
1032
+ const WALLET_ASSOCIATION_TIMEOUT = 3e4;
1033
+ function getErrorMessage(error) {
1034
+ return error instanceof Error ? error.message : "Unknown error";
1035
+ }
1036
+ var LocalSolanaMobileWalletAdapterWallet = class {
1037
+ #listeners = {};
1038
+ #version = "1.0.0";
1039
+ #name = SolanaMobileWalletAdapterWalletName;
1040
+ #url = "https://solanamobile.com/wallets";
1041
+ #icon = icon;
1042
+ #appIdentity;
1043
+ #authorization;
1044
+ #authorizationCache;
1045
+ #connecting = false;
1046
+ /**
1047
+ * Every time the connection is recycled in some way (eg. `disconnect()` is called)
1048
+ * increment this and use it to make sure that `transact` calls from the previous
1049
+ * 'generation' don't continue to do work and throw exceptions.
1050
+ */
1051
+ #connectionGeneration = 0;
1052
+ #chains = [];
1053
+ #chainSelector;
1054
+ #optionalFeatures;
1055
+ #onWalletNotFound;
1056
+ get version() {
1057
+ return this.#version;
1058
+ }
1059
+ get name() {
1060
+ return this.#name;
1061
+ }
1062
+ get url() {
1063
+ return this.#url;
1064
+ }
1065
+ get icon() {
1066
+ return this.#icon;
1067
+ }
1068
+ get chains() {
1069
+ return this.#chains;
1070
+ }
1071
+ get features() {
1072
+ return {
1073
+ [_wallet_standard_features.StandardConnect]: {
1074
+ version: "1.0.0",
1075
+ connect: this.#connect
1076
+ },
1077
+ [_wallet_standard_features.StandardDisconnect]: {
1078
+ version: "1.0.0",
1079
+ disconnect: this.#disconnect
1080
+ },
1081
+ [_wallet_standard_features.StandardEvents]: {
1082
+ version: "1.0.0",
1083
+ on: this.#on
1084
+ },
1085
+ [_solana_wallet_standard_features.SolanaSignMessage]: {
1086
+ version: "1.0.0",
1087
+ signMessage: this.#signMessage
1088
+ },
1089
+ [_solana_wallet_standard_features.SolanaSignIn]: {
1090
+ version: "1.0.0",
1091
+ signIn: this.#signIn
1092
+ },
1093
+ ...this.#optionalFeatures
1094
+ };
1095
+ }
1096
+ get accounts() {
1097
+ return this.#authorization?.accounts ?? [];
1098
+ }
1099
+ constructor(config) {
1100
+ this.#authorizationCache = config.authorizationCache;
1101
+ this.#appIdentity = config.appIdentity;
1102
+ this.#chains = config.chains;
1103
+ this.#chainSelector = config.chainSelector;
1104
+ this.#onWalletNotFound = config.onWalletNotFound;
1105
+ this.#optionalFeatures = {
1106
+ [_solana_wallet_standard_features.SolanaSignAndSendTransaction]: {
1107
+ version: "1.0.0",
1108
+ supportedTransactionVersions: ["legacy", 0],
1109
+ signAndSendTransaction: this.#signAndSendTransaction
1110
+ },
1111
+ [_solana_wallet_standard_features.SolanaSignTransaction]: {
1112
+ version: "1.0.0",
1113
+ supportedTransactionVersions: ["legacy", 0],
1114
+ signTransaction: this.#signTransaction
1115
+ }
1116
+ };
1117
+ }
1118
+ get connected() {
1119
+ return !!this.#authorization;
1120
+ }
1121
+ get isAuthorized() {
1122
+ return !!this.#authorization;
1123
+ }
1124
+ get currentAuthorization() {
1125
+ return this.#authorization;
1126
+ }
1127
+ get cachedAuthorizationResult() {
1128
+ return this.#authorizationCache.get();
1129
+ }
1130
+ #on = (event, listener) => {
1131
+ this.#listeners[event]?.push(listener) || (this.#listeners[event] = [listener]);
1132
+ return () => this.#off(event, listener);
1133
+ };
1134
+ #emit(event, ...args) {
1135
+ this.#listeners[event]?.forEach((listener) => listener.apply(null, args));
1136
+ }
1137
+ #off(event, listener) {
1138
+ this.#listeners[event] = this.#listeners[event]?.filter((existingListener) => listener !== existingListener);
1139
+ }
1140
+ #connect = async ({ silent } = {}) => {
1141
+ if (this.#connecting || this.connected) return { accounts: this.accounts };
1142
+ this.#connecting = true;
1143
+ try {
1144
+ if (silent) {
1145
+ const cachedAuthorization = await this.#authorizationCache.get();
1146
+ if (cachedAuthorization) {
1147
+ await this.#handleWalletCapabilitiesResult(cachedAuthorization.capabilities);
1148
+ await this.#handleAuthorizationResult(cachedAuthorization);
1149
+ } else return { accounts: this.accounts };
1150
+ } else await this.#performAuthorization();
1151
+ } catch (e) {
1152
+ throw new Error(getErrorMessage(e), { cause: e });
1153
+ } finally {
1154
+ this.#connecting = false;
1155
+ }
1156
+ return { accounts: this.accounts };
1157
+ };
1158
+ #performAuthorization = async (signInPayload) => {
1159
+ try {
1160
+ const cachedAuthorizationResult = await this.#authorizationCache.get();
1161
+ if (cachedAuthorizationResult) {
1162
+ this.#handleAuthorizationResult(cachedAuthorizationResult);
1163
+ return cachedAuthorizationResult;
1164
+ }
1165
+ const selectedChain = await this.#chainSelector.select(this.#chains);
1166
+ return await this.#transact(async (wallet) => {
1167
+ const [capabilities, mwaAuthorizationResult] = await Promise.all([wallet.getCapabilities(), wallet.authorize({
1168
+ chain: selectedChain,
1169
+ identity: this.#appIdentity,
1170
+ sign_in_payload: signInPayload
1171
+ })]);
1172
+ const accounts = this.#accountsToWalletStandardAccounts(mwaAuthorizationResult.accounts);
1173
+ const authorization = {
1174
+ ...mwaAuthorizationResult,
1175
+ accounts,
1176
+ chain: selectedChain,
1177
+ capabilities
1178
+ };
1179
+ Promise.all([
1180
+ this.#handleWalletCapabilitiesResult(capabilities),
1181
+ this.#authorizationCache.set(authorization),
1182
+ this.#handleAuthorizationResult(authorization)
1183
+ ]);
1184
+ return authorization;
1185
+ });
1186
+ } catch (e) {
1187
+ throw new Error(getErrorMessage(e), { cause: e });
1188
+ }
1189
+ };
1190
+ #handleAuthorizationResult = async (authorization) => {
1191
+ const didPublicKeysChange = this.#authorization == null || this.#authorization?.accounts.length !== authorization.accounts.length || this.#authorization.accounts.some((account, ii) => account.address !== authorization.accounts[ii].address);
1192
+ this.#authorization = authorization;
1193
+ if (didPublicKeysChange) this.#emit("change", { accounts: this.accounts });
1194
+ };
1195
+ #handleWalletCapabilitiesResult = async (capabilities) => {
1196
+ const supportsSignTransaction = capabilities.features.includes("solana:signTransactions");
1197
+ const supportsSignAndSendTransaction = capabilities.supports_sign_and_send_transactions;
1198
+ const didCapabilitiesChange = _solana_wallet_standard_features.SolanaSignAndSendTransaction in this.features !== supportsSignAndSendTransaction || _solana_wallet_standard_features.SolanaSignTransaction in this.features !== supportsSignTransaction;
1199
+ this.#optionalFeatures = {
1200
+ ...(supportsSignAndSendTransaction || !supportsSignAndSendTransaction && !supportsSignTransaction) && { [_solana_wallet_standard_features.SolanaSignAndSendTransaction]: {
1201
+ version: "1.0.0",
1202
+ supportedTransactionVersions: ["legacy", 0],
1203
+ signAndSendTransaction: this.#signAndSendTransaction
1204
+ } },
1205
+ ...supportsSignTransaction && { [_solana_wallet_standard_features.SolanaSignTransaction]: {
1206
+ version: "1.0.0",
1207
+ supportedTransactionVersions: ["legacy", 0],
1208
+ signTransaction: this.#signTransaction
1209
+ } }
1210
+ };
1211
+ if (didCapabilitiesChange) this.#emit("change", { features: this.features });
1212
+ };
1213
+ #performReauthorization = async (wallet, authToken, chain) => {
1214
+ try {
1215
+ const [capabilities, mwaAuthorizationResult] = await Promise.all([this.#authorization?.capabilities ?? await wallet.getCapabilities(), wallet.authorize({
1216
+ auth_token: authToken,
1217
+ identity: this.#appIdentity,
1218
+ chain
1219
+ })]);
1220
+ const accounts = this.#accountsToWalletStandardAccounts(mwaAuthorizationResult.accounts);
1221
+ const authorization = {
1222
+ ...mwaAuthorizationResult,
1223
+ accounts,
1224
+ chain,
1225
+ capabilities
1226
+ };
1227
+ Promise.all([this.#authorizationCache.set(authorization), this.#handleAuthorizationResult(authorization)]);
1228
+ } catch (e) {
1229
+ this.#disconnect();
1230
+ throw new Error(getErrorMessage(e), { cause: e });
1231
+ }
1232
+ };
1233
+ #disconnect = async () => {
1234
+ this.#authorizationCache.clear();
1235
+ this.#connecting = false;
1236
+ this.#connectionGeneration++;
1237
+ this.#authorization = void 0;
1238
+ this.#emit("change", { accounts: this.accounts });
1239
+ };
1240
+ #transact = async (callback) => {
1241
+ const walletUriBase = this.#authorization?.wallet_uri_base;
1242
+ const config = walletUriBase ? { baseUri: walletUriBase } : void 0;
1243
+ const currentConnectionGeneration = this.#connectionGeneration;
1244
+ const loadingSpinner = new EmbeddedLoadingSpinner();
1245
+ try {
1246
+ let associating = true;
1247
+ let timeout = void 0;
1248
+ const result = await Promise.race([checkLocalNetworkAccessPermission().then(async () => {
1249
+ loadingSpinner.init();
1250
+ const { wallet, close } = await (0, _solana_mobile_mobile_wallet_adapter_protocol.startScenario)(config);
1251
+ associating = false;
1252
+ loadingSpinner.addEventListener("close", (event) => {
1253
+ if (event) close();
1254
+ });
1255
+ loadingSpinner.open();
1256
+ const result = await callback(await wallet);
1257
+ loadingSpinner.close();
1258
+ close();
1259
+ return result;
1260
+ }), new Promise((_, reject) => {
1261
+ timeout = setTimeout(() => {
1262
+ if (associating) reject(new _solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterError(_solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_CANCELLED, "Wallet connection timed out", { event: void 0 }));
1263
+ }, WALLET_ASSOCIATION_TIMEOUT);
1264
+ })]);
1265
+ clearTimeout(timeout);
1266
+ return result;
1267
+ } catch (e) {
1268
+ loadingSpinner.close();
1269
+ if (this.#connectionGeneration !== currentConnectionGeneration) await new Promise(() => {});
1270
+ if (e instanceof Error && e.name === "SolanaMobileWalletAdapterError" && e.code === "ERROR_WALLET_NOT_FOUND") await this.#onWalletNotFound(this);
1271
+ throw e;
1272
+ }
1273
+ };
1274
+ #assertIsAuthorized = () => {
1275
+ if (!this.#authorization) throw new Error("Wallet not connected");
1276
+ return {
1277
+ authToken: this.#authorization.auth_token,
1278
+ chain: this.#authorization.chain
1279
+ };
1280
+ };
1281
+ #accountsToWalletStandardAccounts = (accounts) => {
1282
+ return accounts.map((account) => {
1283
+ const publicKey = toUint8Array(account.address);
1284
+ return {
1285
+ address: bs58.default.encode(publicKey),
1286
+ publicKey,
1287
+ label: account.label,
1288
+ icon: account.icon,
1289
+ chains: account.chains ?? this.#chains,
1290
+ features: account.features ?? DEFAULT_FEATURES
1291
+ };
1292
+ });
1293
+ };
1294
+ #performSignTransactions = async (transactions) => {
1295
+ const { authToken, chain } = this.#assertIsAuthorized();
1296
+ try {
1297
+ const base64Transactions = transactions.map((tx) => {
1298
+ return fromUint8Array(tx);
1299
+ });
1300
+ return await this.#transact(async (wallet) => {
1301
+ await this.#performReauthorization(wallet, authToken, chain);
1302
+ return (await wallet.signTransactions({ payloads: base64Transactions })).signed_payloads.map(toUint8Array);
1303
+ });
1304
+ } catch (e) {
1305
+ throw new Error(getErrorMessage(e), { cause: e });
1306
+ }
1307
+ };
1308
+ #performSignAndSendTransaction = async (transaction, options) => {
1309
+ const { authToken, chain } = this.#assertIsAuthorized();
1310
+ try {
1311
+ return await this.#transact(async (wallet) => {
1312
+ const [capabilities] = await Promise.all([wallet.getCapabilities(), this.#performReauthorization(wallet, authToken, chain)]);
1313
+ if (capabilities.supports_sign_and_send_transactions) {
1314
+ const base64Transaction = fromUint8Array(transaction);
1315
+ return (await wallet.signAndSendTransactions({
1316
+ ...options,
1317
+ payloads: [base64Transaction]
1318
+ })).signatures.map(toUint8Array)[0];
1319
+ } else throw new Error("connected wallet does not support signAndSendTransaction");
1320
+ });
1321
+ } catch (e) {
1322
+ throw new Error(getErrorMessage(e), { cause: e });
1323
+ }
1324
+ };
1325
+ #signAndSendTransaction = async (...inputs) => {
1326
+ const outputs = [];
1327
+ for (const input of inputs) {
1328
+ const signature = await this.#performSignAndSendTransaction(input.transaction, input.options);
1329
+ outputs.push({ signature });
1330
+ }
1331
+ return outputs;
1332
+ };
1333
+ #signTransaction = async (...inputs) => {
1334
+ return (await this.#performSignTransactions(inputs.map(({ transaction }) => transaction))).map((signedTransaction) => {
1335
+ return { signedTransaction };
1336
+ });
1337
+ };
1338
+ #signMessage = async (...inputs) => {
1339
+ const { authToken, chain } = this.#assertIsAuthorized();
1340
+ const addresses = inputs.map(({ account }) => fromUint8Array(new Uint8Array(account.publicKey)));
1341
+ const messages = inputs.map(({ message }) => fromUint8Array(message));
1342
+ try {
1343
+ return await this.#transact(async (wallet) => {
1344
+ await this.#performReauthorization(wallet, authToken, chain);
1345
+ return (await wallet.signMessages({
1346
+ addresses,
1347
+ payloads: messages
1348
+ })).signed_payloads.map(toUint8Array).map((signedMessage) => {
1349
+ return {
1350
+ signedMessage,
1351
+ signature: signedMessage.slice(-SIGNATURE_LENGTH_IN_BYTES)
1352
+ };
1353
+ });
1354
+ });
1355
+ } catch (e) {
1356
+ throw new Error(getErrorMessage(e), { cause: e });
1357
+ }
1358
+ };
1359
+ #signIn = async (...inputs) => {
1360
+ const outputs = [];
1361
+ if (inputs.length > 1) for (const input of inputs) outputs.push(await this.#performSignIn(input));
1362
+ else return [await this.#performSignIn(inputs[0])];
1363
+ return outputs;
1364
+ };
1365
+ #performSignIn = async (input) => {
1366
+ this.#connecting = true;
1367
+ try {
1368
+ const authorizationResult = await this.#performAuthorization({
1369
+ ...input,
1370
+ domain: input?.domain ?? window.location.host
1371
+ });
1372
+ if (!authorizationResult.sign_in_result) throw new Error("Sign in failed, no sign in result returned by wallet");
1373
+ const signedInAddress = authorizationResult.sign_in_result.address;
1374
+ const signedInAccount = authorizationResult.accounts.find((acc) => acc.address == signedInAddress);
1375
+ return {
1376
+ account: {
1377
+ ...signedInAccount ?? { address: bs58.default.encode(toUint8Array(signedInAddress)) },
1378
+ publicKey: toUint8Array(signedInAddress),
1379
+ chains: signedInAccount?.chains ?? this.#chains,
1380
+ features: signedInAccount?.features ?? authorizationResult.capabilities.features
1381
+ },
1382
+ signedMessage: toUint8Array(authorizationResult.sign_in_result.signed_message),
1383
+ signature: toUint8Array(authorizationResult.sign_in_result.signature)
1384
+ };
1385
+ } catch (e) {
1386
+ throw new Error(getErrorMessage(e), { cause: e });
1387
+ } finally {
1388
+ this.#connecting = false;
1389
+ }
1390
+ };
1391
+ };
1392
+ var RemoteSolanaMobileWalletAdapterWallet = class {
1393
+ #listeners = {};
1394
+ #version = "1.0.0";
1395
+ #name = SolanaMobileWalletAdapterRemoteWalletName;
1396
+ #url = "https://solanamobile.com/wallets";
1397
+ #icon = icon;
1398
+ #appIdentity;
1399
+ #authorization;
1400
+ #authorizationCache;
1401
+ #connecting = false;
1402
+ /**
1403
+ * Every time the connection is recycled in some way (eg. `disconnect()` is called)
1404
+ * increment this and use it to make sure that `transact` calls from the previous
1405
+ * 'generation' don't continue to do work and throw exceptions.
1406
+ */
1407
+ #connectionGeneration = 0;
1408
+ #chains = [];
1409
+ #chainSelector;
1410
+ #optionalFeatures;
1411
+ #onWalletNotFound;
1412
+ #hostAuthority;
1413
+ #session;
1414
+ get version() {
1415
+ return this.#version;
1416
+ }
1417
+ get name() {
1418
+ return this.#name;
1419
+ }
1420
+ get url() {
1421
+ return this.#url;
1422
+ }
1423
+ get icon() {
1424
+ return this.#icon;
1425
+ }
1426
+ get chains() {
1427
+ return this.#chains;
1428
+ }
1429
+ get features() {
1430
+ return {
1431
+ [_wallet_standard_features.StandardConnect]: {
1432
+ version: "1.0.0",
1433
+ connect: this.#connect
1434
+ },
1435
+ [_wallet_standard_features.StandardDisconnect]: {
1436
+ version: "1.0.0",
1437
+ disconnect: this.#disconnect
1438
+ },
1439
+ [_wallet_standard_features.StandardEvents]: {
1440
+ version: "1.0.0",
1441
+ on: this.#on
1442
+ },
1443
+ [_solana_wallet_standard_features.SolanaSignMessage]: {
1444
+ version: "1.0.0",
1445
+ signMessage: this.#signMessage
1446
+ },
1447
+ [_solana_wallet_standard_features.SolanaSignIn]: {
1448
+ version: "1.0.0",
1449
+ signIn: this.#signIn
1450
+ },
1451
+ ...this.#optionalFeatures
1452
+ };
1453
+ }
1454
+ get accounts() {
1455
+ return this.#authorization?.accounts ?? [];
1456
+ }
1457
+ constructor(config) {
1458
+ this.#authorizationCache = config.authorizationCache;
1459
+ this.#appIdentity = config.appIdentity;
1460
+ this.#chains = config.chains;
1461
+ this.#chainSelector = config.chainSelector;
1462
+ this.#hostAuthority = config.remoteHostAuthority;
1463
+ this.#onWalletNotFound = config.onWalletNotFound;
1464
+ this.#optionalFeatures = {
1465
+ [_solana_wallet_standard_features.SolanaSignAndSendTransaction]: {
1466
+ version: "1.0.0",
1467
+ supportedTransactionVersions: ["legacy", 0],
1468
+ signAndSendTransaction: this.#signAndSendTransaction
1469
+ },
1470
+ [_solana_wallet_standard_features.SolanaSignTransaction]: {
1471
+ version: "1.0.0",
1472
+ supportedTransactionVersions: ["legacy", 0],
1473
+ signTransaction: this.#signTransaction
1474
+ }
1475
+ };
1476
+ }
1477
+ get connected() {
1478
+ return !!this.#session && !!this.#authorization;
1479
+ }
1480
+ get isAuthorized() {
1481
+ return !!this.#authorization;
1482
+ }
1483
+ get currentAuthorization() {
1484
+ return this.#authorization;
1485
+ }
1486
+ get cachedAuthorizationResult() {
1487
+ return this.#authorizationCache.get();
1488
+ }
1489
+ #on = (event, listener) => {
1490
+ this.#listeners[event]?.push(listener) || (this.#listeners[event] = [listener]);
1491
+ return () => this.#off(event, listener);
1492
+ };
1493
+ #emit(event, ...args) {
1494
+ this.#listeners[event]?.forEach((listener) => listener.apply(null, args));
1495
+ }
1496
+ #off(event, listener) {
1497
+ this.#listeners[event] = this.#listeners[event]?.filter((existingListener) => listener !== existingListener);
1498
+ }
1499
+ #connect = async (_input = {}) => {
1500
+ if (this.#connecting || this.connected) return { accounts: this.accounts };
1501
+ this.#connecting = true;
1502
+ try {
1503
+ await this.#performAuthorization();
1504
+ } catch (e) {
1505
+ throw new Error(getErrorMessage(e), { cause: e });
1506
+ } finally {
1507
+ this.#connecting = false;
1508
+ }
1509
+ return { accounts: this.accounts };
1510
+ };
1511
+ #performAuthorization = async (signInPayload) => {
1512
+ try {
1513
+ const cachedAuthorizationResult = await this.#authorizationCache.get();
1514
+ if (cachedAuthorizationResult) {
1515
+ this.#handleAuthorizationResult(cachedAuthorizationResult);
1516
+ return cachedAuthorizationResult;
1517
+ }
1518
+ if (this.#session) this.#session = void 0;
1519
+ const selectedChain = await this.#chainSelector.select(this.#chains);
1520
+ return await this.#transact(async (wallet) => {
1521
+ const [capabilities, mwaAuthorizationResult] = await Promise.all([wallet.getCapabilities(), wallet.authorize({
1522
+ chain: selectedChain,
1523
+ identity: this.#appIdentity,
1524
+ sign_in_payload: signInPayload
1525
+ })]);
1526
+ const accounts = this.#accountsToWalletStandardAccounts(mwaAuthorizationResult.accounts);
1527
+ const authorizationResult = {
1528
+ ...mwaAuthorizationResult,
1529
+ accounts,
1530
+ chain: selectedChain,
1531
+ capabilities
1532
+ };
1533
+ Promise.all([
1534
+ this.#handleWalletCapabilitiesResult(capabilities),
1535
+ this.#authorizationCache.set(authorizationResult),
1536
+ this.#handleAuthorizationResult(authorizationResult)
1537
+ ]);
1538
+ return authorizationResult;
1539
+ });
1540
+ } catch (e) {
1541
+ throw new Error(getErrorMessage(e), { cause: e });
1542
+ }
1543
+ };
1544
+ #handleAuthorizationResult = async (authorization) => {
1545
+ const didPublicKeysChange = this.#authorization == null || this.#authorization?.accounts.length !== authorization.accounts.length || this.#authorization.accounts.some((account, ii) => account.address !== authorization.accounts[ii].address);
1546
+ this.#authorization = authorization;
1547
+ if (didPublicKeysChange) this.#emit("change", { accounts: this.accounts });
1548
+ };
1549
+ #handleWalletCapabilitiesResult = async (capabilities) => {
1550
+ const supportsSignTransaction = capabilities.features.includes("solana:signTransactions");
1551
+ const supportsSignAndSendTransaction = capabilities.supports_sign_and_send_transactions || capabilities.features.includes("solana:signAndSendTransaction");
1552
+ const didCapabilitiesChange = _solana_wallet_standard_features.SolanaSignAndSendTransaction in this.features !== supportsSignAndSendTransaction || _solana_wallet_standard_features.SolanaSignTransaction in this.features !== supportsSignTransaction;
1553
+ this.#optionalFeatures = {
1554
+ ...supportsSignAndSendTransaction && { [_solana_wallet_standard_features.SolanaSignAndSendTransaction]: {
1555
+ version: "1.0.0",
1556
+ supportedTransactionVersions: capabilities.supported_transaction_versions,
1557
+ signAndSendTransaction: this.#signAndSendTransaction
1558
+ } },
1559
+ ...supportsSignTransaction && { [_solana_wallet_standard_features.SolanaSignTransaction]: {
1560
+ version: "1.0.0",
1561
+ supportedTransactionVersions: capabilities.supported_transaction_versions,
1562
+ signTransaction: this.#signTransaction
1563
+ } }
1564
+ };
1565
+ if (didCapabilitiesChange) this.#emit("change", { features: this.features });
1566
+ };
1567
+ #performReauthorization = async (wallet, authToken, chain) => {
1568
+ try {
1569
+ const [capabilities, mwaAuthorizationResult] = await Promise.all([this.#authorization?.capabilities ?? await wallet.getCapabilities(), wallet.authorize({
1570
+ auth_token: authToken,
1571
+ identity: this.#appIdentity,
1572
+ chain
1573
+ })]);
1574
+ const accounts = this.#accountsToWalletStandardAccounts(mwaAuthorizationResult.accounts);
1575
+ const authorization = {
1576
+ ...mwaAuthorizationResult,
1577
+ accounts,
1578
+ chain,
1579
+ capabilities
1580
+ };
1581
+ Promise.all([this.#authorizationCache.set(authorization), this.#handleAuthorizationResult(authorization)]);
1582
+ } catch (e) {
1583
+ this.#disconnect();
1584
+ throw new Error(getErrorMessage(e), { cause: e });
1585
+ }
1586
+ };
1587
+ #disconnect = async () => {
1588
+ this.#session?.close();
1589
+ this.#authorizationCache.clear();
1590
+ this.#connecting = false;
1591
+ this.#connectionGeneration++;
1592
+ this.#authorization = void 0;
1593
+ this.#session = void 0;
1594
+ this.#emit("change", { accounts: this.accounts });
1595
+ };
1596
+ #transact = async (callback) => {
1597
+ const walletUriBase = this.#authorization?.wallet_uri_base;
1598
+ const remoteConfig = {
1599
+ ...walletUriBase ? { baseUri: walletUriBase } : void 0,
1600
+ remoteHostAuthority: this.#hostAuthority
1601
+ };
1602
+ const currentConnectionGeneration = this.#connectionGeneration;
1603
+ const modal = new RemoteConnectionModal();
1604
+ if (this.#session) return callback(this.#session.wallet);
1605
+ try {
1606
+ modal.init();
1607
+ modal.open();
1608
+ const { associationUrl, close, wallet } = await (0, _solana_mobile_mobile_wallet_adapter_protocol.startRemoteScenario)(remoteConfig);
1609
+ const removeCloseListener = modal.addEventListener("close", (event) => {
1610
+ if (event) close();
1611
+ });
1612
+ modal.populateQRCode(associationUrl.toString());
1613
+ this.#session = {
1614
+ close,
1615
+ wallet: await wallet
1616
+ };
1617
+ removeCloseListener();
1618
+ modal.close();
1619
+ return await callback(this.#session.wallet);
1620
+ } catch (e) {
1621
+ modal.close();
1622
+ if (this.#connectionGeneration !== currentConnectionGeneration) await new Promise(() => {});
1623
+ if (e instanceof Error && e.name === "SolanaMobileWalletAdapterError" && e.code === "ERROR_WALLET_NOT_FOUND") await this.#onWalletNotFound(this);
1624
+ throw e;
1625
+ }
1626
+ };
1627
+ #assertIsAuthorized = () => {
1628
+ if (!this.#authorization) throw new Error("Wallet not connected");
1629
+ return {
1630
+ authToken: this.#authorization.auth_token,
1631
+ chain: this.#authorization.chain
1632
+ };
1633
+ };
1634
+ #accountsToWalletStandardAccounts = (accounts) => {
1635
+ return accounts.map((account) => {
1636
+ const publicKey = toUint8Array(account.address);
1637
+ return {
1638
+ address: bs58.default.encode(publicKey),
1639
+ publicKey,
1640
+ label: account.label,
1641
+ icon: account.icon,
1642
+ chains: account.chains ?? this.#chains,
1643
+ features: account.features ?? DEFAULT_FEATURES
1644
+ };
1645
+ });
1646
+ };
1647
+ #performSignTransactions = async (transactions) => {
1648
+ const { authToken, chain } = this.#assertIsAuthorized();
1649
+ try {
1650
+ return await this.#transact(async (wallet) => {
1651
+ await this.#performReauthorization(wallet, authToken, chain);
1652
+ return (await wallet.signTransactions({ payloads: transactions.map(fromUint8Array) })).signed_payloads.map(toUint8Array);
1653
+ });
1654
+ } catch (e) {
1655
+ throw new Error(getErrorMessage(e), { cause: e });
1656
+ }
1657
+ };
1658
+ #performSignAndSendTransaction = async (transaction, options) => {
1659
+ const { authToken, chain } = this.#assertIsAuthorized();
1660
+ try {
1661
+ return await this.#transact(async (wallet) => {
1662
+ const [capabilities] = await Promise.all([wallet.getCapabilities(), this.#performReauthorization(wallet, authToken, chain)]);
1663
+ if (capabilities.supports_sign_and_send_transactions) return (await wallet.signAndSendTransactions({
1664
+ ...options,
1665
+ payloads: [fromUint8Array(transaction)]
1666
+ })).signatures.map(toUint8Array)[0];
1667
+ else throw new Error("connected wallet does not support signAndSendTransaction");
1668
+ });
1669
+ } catch (e) {
1670
+ throw new Error(getErrorMessage(e), { cause: e });
1671
+ }
1672
+ };
1673
+ #signAndSendTransaction = async (...inputs) => {
1674
+ const outputs = [];
1675
+ for (const input of inputs) {
1676
+ const signature = await this.#performSignAndSendTransaction(input.transaction, input.options);
1677
+ outputs.push({ signature });
1678
+ }
1679
+ return outputs;
1680
+ };
1681
+ #signTransaction = async (...inputs) => {
1682
+ return (await this.#performSignTransactions(inputs.map(({ transaction }) => transaction))).map((signedTransaction) => {
1683
+ return { signedTransaction };
1684
+ });
1685
+ };
1686
+ #signMessage = async (...inputs) => {
1687
+ const { authToken, chain } = this.#assertIsAuthorized();
1688
+ const addresses = inputs.map(({ account }) => fromUint8Array(new Uint8Array(account.publicKey)));
1689
+ const messages = inputs.map(({ message }) => fromUint8Array(message));
1690
+ try {
1691
+ return await this.#transact(async (wallet) => {
1692
+ await this.#performReauthorization(wallet, authToken, chain);
1693
+ return (await wallet.signMessages({
1694
+ addresses,
1695
+ payloads: messages
1696
+ })).signed_payloads.map(toUint8Array).map((signedMessage) => {
1697
+ return {
1698
+ signedMessage,
1699
+ signature: signedMessage.slice(-SIGNATURE_LENGTH_IN_BYTES)
1700
+ };
1701
+ });
1702
+ });
1703
+ } catch (e) {
1704
+ throw new Error(getErrorMessage(e), { cause: e });
1705
+ }
1706
+ };
1707
+ #signIn = async (...inputs) => {
1708
+ const outputs = [];
1709
+ if (inputs.length > 1) for (const input of inputs) outputs.push(await this.#performSignIn(input));
1710
+ else return [await this.#performSignIn(inputs[0])];
1711
+ return outputs;
1712
+ };
1713
+ #performSignIn = async (input) => {
1714
+ this.#connecting = true;
1715
+ try {
1716
+ const authorizationResult = await this.#performAuthorization({
1717
+ ...input,
1718
+ domain: input?.domain ?? window.location.host
1719
+ });
1720
+ if (!authorizationResult.sign_in_result) throw new Error("Sign in failed, no sign in result returned by wallet");
1721
+ const signedInAddress = authorizationResult.sign_in_result.address;
1722
+ const signedInAccount = authorizationResult.accounts.find((acc) => acc.address == signedInAddress);
1723
+ return {
1724
+ account: {
1725
+ ...signedInAccount ?? { address: bs58.default.encode(toUint8Array(signedInAddress)) },
1726
+ publicKey: toUint8Array(signedInAddress),
1727
+ chains: signedInAccount?.chains ?? this.#chains,
1728
+ features: signedInAccount?.features ?? authorizationResult.capabilities.features
1729
+ },
1730
+ signedMessage: toUint8Array(authorizationResult.sign_in_result.signed_message),
1731
+ signature: toUint8Array(authorizationResult.sign_in_result.signature)
1732
+ };
1733
+ } catch (e) {
1734
+ throw new Error(getErrorMessage(e), { cause: e });
1735
+ } finally {
1736
+ this.#connecting = false;
1737
+ }
1738
+ };
1739
+ };
1740
+ //#endregion
1741
+ //#region src/initialize.ts
1928
1742
  function registerMwa(config) {
1929
- if (typeof window === 'undefined') {
1930
- console.warn(`MWA not registered: no window object`);
1931
- return;
1932
- }
1933
- if (!window.isSecureContext) {
1934
- console.warn(`MWA not registered: secure context required (https)`);
1935
- return;
1936
- }
1937
- // Local association technically is possible in a webview, but we prevent registration
1938
- // by default because it usually fails in the most common cases (e.g wallet browsers).
1939
- if (getIsLocalAssociationSupported() && !isWebView(navigator.userAgent)) {
1940
- wallet.registerWallet(new LocalSolanaMobileWalletAdapterWallet(config));
1941
- }
1942
- else if (getIsRemoteAssociationSupported() && config.remoteHostAuthority !== undefined) {
1943
- wallet.registerWallet(new RemoteSolanaMobileWalletAdapterWallet({ ...config, remoteHostAuthority: config.remoteHostAuthority }));
1944
- }
1945
- else ;
1946
- }
1947
-
1948
- const WALLET_NOT_FOUND_ERROR_MESSAGE = 'To use mobile wallet adapter, you must have a compatible mobile wallet application installed on your device.';
1949
- const BROWSER_NOT_SUPPORTED_ERROR_MESSAGE = 'This browser appears to be incompatible with mobile wallet adapter. Open this page in a compatible mobile browser app and try again.';
1950
- class ErrorModal extends EmbeddedModal {
1951
- contentStyles = css;
1952
- contentHtml = ErrorDialogHtml;
1953
- initWithError(error) {
1954
- super.init();
1955
- this.populateError(error);
1956
- }
1957
- populateError(error) {
1958
- const errorMessageElement = this.dom?.getElementById('mobile-wallet-adapter-error-message');
1959
- const actionBtn = this.dom?.getElementById('mobile-wallet-adapter-error-action');
1960
- if (errorMessageElement) {
1961
- if (error.name === 'SolanaMobileWalletAdapterError') {
1962
- switch (error.code) {
1963
- case 'ERROR_WALLET_NOT_FOUND':
1964
- errorMessageElement.innerHTML = WALLET_NOT_FOUND_ERROR_MESSAGE;
1965
- if (actionBtn)
1966
- actionBtn.addEventListener('click', () => {
1967
- window.location.href = 'https://solanamobile.com/wallets';
1968
- });
1969
- return;
1970
- case 'ERROR_BROWSER_NOT_SUPPORTED':
1971
- errorMessageElement.innerHTML = BROWSER_NOT_SUPPORTED_ERROR_MESSAGE;
1972
- if (actionBtn)
1973
- actionBtn.style.display = 'none';
1974
- return;
1975
- }
1976
- }
1977
- errorMessageElement.innerHTML = `An unexpected error occurred: ${error.message}`;
1978
- }
1979
- else {
1980
- console.log('Failed to locate error dialog element');
1981
- }
1982
- }
1983
- }
1743
+ if (typeof window === "undefined") {
1744
+ console.warn(`MWA not registered: no window object`);
1745
+ return;
1746
+ }
1747
+ if (!window.isSecureContext) {
1748
+ console.warn(`MWA not registered: secure context required (https)`);
1749
+ return;
1750
+ }
1751
+ const userAgent = navigator.userAgent;
1752
+ if (getIsLocalAssociationSupported() && (!isWebView(userAgent) || isSolanaMobileWebShell(userAgent))) (0, _wallet_standard_wallet.registerWallet)(new LocalSolanaMobileWalletAdapterWallet(config));
1753
+ else if (getIsRemoteAssociationSupported() && config.remoteHostAuthority !== void 0) (0, _wallet_standard_wallet.registerWallet)(new RemoteSolanaMobileWalletAdapterWallet({
1754
+ ...config,
1755
+ remoteHostAuthority: config.remoteHostAuthority
1756
+ }));
1757
+ }
1758
+ //#endregion
1759
+ //#region src/embedded-modal/errorModal.ts
1760
+ const WALLET_NOT_FOUND_ERROR_MESSAGE = "To use mobile wallet adapter, you must have a compatible mobile wallet application installed on your device.";
1761
+ const BROWSER_NOT_SUPPORTED_ERROR_MESSAGE = "This browser appears to be incompatible with mobile wallet adapter. Open this page in a compatible mobile browser app and try again.";
1762
+ var ErrorModal = class extends EmbeddedModal {
1763
+ contentStyles = css;
1764
+ contentHtml = ErrorDialogHtml;
1765
+ initWithError(error) {
1766
+ super.init();
1767
+ this.populateError(error);
1768
+ }
1769
+ populateError(error) {
1770
+ const errorMessageElement = this.dom?.getElementById("mobile-wallet-adapter-error-message");
1771
+ const actionBtn = this.dom?.getElementById("mobile-wallet-adapter-error-action");
1772
+ if (errorMessageElement) {
1773
+ if (error.name === "SolanaMobileWalletAdapterError") switch (error.code) {
1774
+ case "ERROR_WALLET_NOT_FOUND":
1775
+ errorMessageElement.innerHTML = WALLET_NOT_FOUND_ERROR_MESSAGE;
1776
+ if (actionBtn) actionBtn.addEventListener("click", () => {
1777
+ window.location.href = "https://solanamobile.com/wallets";
1778
+ });
1779
+ return;
1780
+ case "ERROR_BROWSER_NOT_SUPPORTED":
1781
+ errorMessageElement.innerHTML = BROWSER_NOT_SUPPORTED_ERROR_MESSAGE;
1782
+ if (actionBtn) actionBtn.style.display = "none";
1783
+ return;
1784
+ }
1785
+ errorMessageElement.innerHTML = `An unexpected error occurred: ${error.message}`;
1786
+ } else console.log("Failed to locate error dialog element");
1787
+ }
1788
+ };
1984
1789
  const ErrorDialogHtml = `
1985
1790
  <svg class="mobile-wallet-adapter-embedded-modal-error-icon" xmlns="http://www.w3.org/2000/svg" height="50px" viewBox="0 -960 960 960" width="50px" fill="#000000"><path d="M 280,-80 Q 197,-80 138.5,-138.5 80,-197 80,-280 80,-363 138.5,-421.5 197,-480 280,-480 q 83,0 141.5,58.5 58.5,58.5 58.5,141.5 0,83 -58.5,141.5 Q 363,-80 280,-80 Z M 824,-120 568,-376 Q 556,-389 542.5,-402.5 529,-416 516,-428 q 38,-24 61,-64 23,-40 23,-88 0,-75 -52.5,-127.5 Q 495,-760 420,-760 345,-760 292.5,-707.5 240,-655 240,-580 q 0,6 0.5,11.5 0.5,5.5 1.5,11.5 -18,2 -39.5,8 -21.5,6 -38.5,14 -2,-11 -3,-22 -1,-11 -1,-23 0,-109 75.5,-184.5 Q 311,-840 420,-840 q 109,0 184.5,75.5 75.5,75.5 75.5,184.5 0,43 -13.5,81.5 Q 653,-460 629,-428 l 251,252 z m -615,-61 71,-71 70,71 29,-28 -71,-71 71,-71 -28,-28 -71,71 -71,-71 -28,28 71,71 -71,71 z"/></svg>
1986
1791
  <div class="mobile-wallet-adapter-embedded-modal-title">We can't find a wallet.</div>
@@ -2040,117 +1845,81 @@ const css = `
2040
1845
  }
2041
1846
  }
2042
1847
  `;
2043
-
1848
+ //#endregion
1849
+ //#region src/createDefaultWalletNotFoundHandler.ts
2044
1850
  async function defaultErrorModalWalletNotFoundHandler() {
2045
- if (typeof window !== 'undefined') {
2046
- const userAgent = window.navigator.userAgent.toLowerCase();
2047
- const errorDialog = new ErrorModal();
2048
- if (userAgent.includes('wv')) { // Android WebView
2049
- // MWA is not supported in this browser so we inform the user
2050
- // errorDialog.initWithError(
2051
- // new SolanaMobileWalletAdapterError(
2052
- // SolanaMobileWalletAdapterErrorCode.ERROR_BROWSER_NOT_SUPPORTED,
2053
- // ''
2054
- // )
2055
- // );
2056
- // TODO: investigate why instantiating a new SolanaMobileWalletAdapterError here breaks treeshaking
2057
- errorDialog.initWithError({
2058
- name: 'SolanaMobileWalletAdapterError',
2059
- code: 'ERROR_BROWSER_NOT_SUPPORTED',
2060
- message: ''
2061
- });
2062
- }
2063
- else { // Browser, user does not have a wallet installed.
2064
- // errorDialog.initWithError(
2065
- // new SolanaMobileWalletAdapterError(
2066
- // SolanaMobileWalletAdapterErrorCode.ERROR_WALLET_NOT_FOUND,
2067
- // ''
2068
- // )
2069
- // );
2070
- // TODO: investigate why instantiating a new SolanaMobileWalletAdapterError here breaks treeshaking
2071
- errorDialog.initWithError({
2072
- name: 'SolanaMobileWalletAdapterError',
2073
- code: 'ERROR_WALLET_NOT_FOUND',
2074
- message: ''
2075
- });
2076
- }
2077
- errorDialog.open();
2078
- }
1851
+ if (typeof window !== "undefined") {
1852
+ const userAgent = window.navigator.userAgent.toLowerCase();
1853
+ const errorDialog = new ErrorModal();
1854
+ if (userAgent.includes("wv")) errorDialog.initWithError({
1855
+ name: "SolanaMobileWalletAdapterError",
1856
+ code: "ERROR_BROWSER_NOT_SUPPORTED",
1857
+ message: ""
1858
+ });
1859
+ else errorDialog.initWithError({
1860
+ name: "SolanaMobileWalletAdapterError",
1861
+ code: "ERROR_WALLET_NOT_FOUND",
1862
+ message: ""
1863
+ });
1864
+ errorDialog.open();
1865
+ }
2079
1866
  }
2080
1867
  function createDefaultWalletNotFoundHandler() {
2081
- return async () => { defaultErrorModalWalletNotFoundHandler(); };
1868
+ return async () => {
1869
+ defaultErrorModalWalletNotFoundHandler();
1870
+ };
2082
1871
  }
2083
-
2084
- const CACHE_KEY = 'SolanaMobileWalletAdapterDefaultAuthorizationCache';
1872
+ //#endregion
1873
+ //#region src/createDefaultAuthorizationCache.ts
1874
+ const CACHE_KEY = "SolanaMobileWalletAdapterDefaultAuthorizationCache";
2085
1875
  function createDefaultAuthorizationCache() {
2086
- let storage;
2087
- try {
2088
- storage = window.localStorage;
2089
- // eslint-disable-next-line no-empty
2090
- }
2091
- catch { }
2092
- return {
2093
- async clear() {
2094
- if (!storage) {
2095
- return;
2096
- }
2097
- try {
2098
- storage.removeItem(CACHE_KEY);
2099
- // eslint-disable-next-line no-empty
2100
- }
2101
- catch { }
2102
- },
2103
- async get() {
2104
- if (!storage) {
2105
- return;
2106
- }
2107
- try {
2108
- const parsed = JSON.parse(storage.getItem(CACHE_KEY));
2109
- if (parsed && parsed.accounts) {
2110
- const parsedAccounts = parsed.accounts.map((account) => {
2111
- return {
2112
- ...account,
2113
- publicKey: 'publicKey' in account
2114
- ? new Uint8Array(Object.values(account.publicKey)) // Rebuild publicKey for WalletAccount
2115
- : base58.decode(account.address), // Fallback, get publicKey from address
2116
- };
2117
- });
2118
- return { ...parsed, accounts: parsedAccounts };
2119
- }
2120
- else
2121
- return parsed || undefined;
2122
- // eslint-disable-next-line no-empty
2123
- }
2124
- catch { }
2125
- },
2126
- async set(authorization) {
2127
- if (!storage) {
2128
- return;
2129
- }
2130
- try {
2131
- storage.setItem(CACHE_KEY, JSON.stringify(authorization));
2132
- // eslint-disable-next-line no-empty
2133
- }
2134
- catch { }
2135
- },
2136
- };
2137
- }
2138
-
1876
+ let storage;
1877
+ try {
1878
+ storage = window.localStorage;
1879
+ } catch {}
1880
+ return {
1881
+ async clear() {
1882
+ if (!storage) return;
1883
+ try {
1884
+ storage.removeItem(CACHE_KEY);
1885
+ } catch {}
1886
+ },
1887
+ async get() {
1888
+ if (!storage) return;
1889
+ try {
1890
+ const parsed = JSON.parse(storage.getItem(CACHE_KEY));
1891
+ if (parsed && parsed.accounts) {
1892
+ const parsedAccounts = parsed.accounts.map((account) => {
1893
+ return {
1894
+ ...account,
1895
+ publicKey: "publicKey" in account ? new Uint8Array(Object.values(account.publicKey)) : bs58.default.decode(account.address)
1896
+ };
1897
+ });
1898
+ return {
1899
+ ...parsed,
1900
+ accounts: parsedAccounts
1901
+ };
1902
+ } else return parsed || void 0;
1903
+ } catch {}
1904
+ },
1905
+ async set(authorization) {
1906
+ if (!storage) return;
1907
+ try {
1908
+ storage.setItem(CACHE_KEY, JSON.stringify(authorization));
1909
+ } catch {}
1910
+ }
1911
+ };
1912
+ }
1913
+ //#endregion
1914
+ //#region src/createDefaultChainSelector.ts
2139
1915
  function createDefaultChainSelector() {
2140
- return {
2141
- async select(chains) {
2142
- if (chains.length === 1) {
2143
- return chains[0];
2144
- }
2145
- else if (chains.includes(walletStandardChains.SOLANA_MAINNET_CHAIN)) {
2146
- return walletStandardChains.SOLANA_MAINNET_CHAIN;
2147
- }
2148
- else
2149
- return chains[0];
2150
- },
2151
- };
1916
+ return { async select(chains) {
1917
+ if (chains.length === 1) return chains[0];
1918
+ else if (chains.includes(_solana_wallet_standard_chains.SOLANA_MAINNET_CHAIN)) return _solana_wallet_standard_chains.SOLANA_MAINNET_CHAIN;
1919
+ else return chains[0];
1920
+ } };
2152
1921
  }
2153
-
1922
+ //#endregion
2154
1923
  exports.LocalSolanaMobileWalletAdapterWallet = LocalSolanaMobileWalletAdapterWallet;
2155
1924
  exports.RemoteSolanaMobileWalletAdapterWallet = RemoteSolanaMobileWalletAdapterWallet;
2156
1925
  exports.SolanaMobileWalletAdapterRemoteWalletName = SolanaMobileWalletAdapterRemoteWalletName;
@@ -2160,3 +1929,5 @@ exports.createDefaultChainSelector = createDefaultChainSelector;
2160
1929
  exports.createDefaultWalletNotFoundHandler = createDefaultWalletNotFoundHandler;
2161
1930
  exports.defaultErrorModalWalletNotFoundHandler = defaultErrorModalWalletNotFoundHandler;
2162
1931
  exports.registerMwa = registerMwa;
1932
+
1933
+ //# sourceMappingURL=index.browser.js.map