@solana-mobile/wallet-standard-mobile 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,170 +21,61 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
21
  enumerable: true
22
22
  }) : target, mod));
23
23
  //#endregion
24
- let _solana_wallet_standard_features = require("@solana/wallet-standard-features");
25
- let qrcode = require("qrcode");
26
- qrcode = __toESM(qrcode);
27
- let _solana_mobile_mobile_wallet_adapter_protocol = require("@solana-mobile/mobile-wallet-adapter-protocol");
28
- let _wallet_standard_features = require("@wallet-standard/features");
29
- let js_base64 = require("js-base64");
30
- let bs58 = require("bs58");
31
- bs58 = __toESM(bs58);
32
- let _wallet_standard_wallet = require("@wallet-standard/wallet");
33
24
  let _react_native_async_storage_async_storage = require("@react-native-async-storage/async-storage");
34
25
  _react_native_async_storage_async_storage = __toESM(_react_native_async_storage_async_storage);
26
+ let _solana_mobile_mobile_wallet_adapter_protocol_encoding = require("@solana-mobile/mobile-wallet-adapter-protocol/encoding");
35
27
  let _solana_wallet_standard_chains = require("@solana/wallet-standard-chains");
36
- //#region src/embedded-modal/loadingSpinner.ts
37
- const modalHtml$1 = `
38
- <div class="mobile-wallet-adapter-embedded-loading-indicator" role="dialog" aria-modal="true" aria-labelledby="modal-title">
39
- <div data-modal-close style="position: absolute; width: 100%; height: 100%;"></div>
40
- <div class="mobile-wallet-adapter-embedded-loading-container">
41
- <div class="mobile-wallet-adapter-embedded-loading-animation"></div>
42
- </div>
43
- </div>
44
- `;
45
- const css$6 = `
46
- .mobile-wallet-adapter-embedded-loading-indicator {
47
- display: flex; /* Use flexbox to center content */
48
- justify-content: center; /* Center horizontally */
49
- align-items: start; /* Center vertically */
50
- position: fixed; /* Stay in place */
51
- z-index: 1; /* Sit on top */
52
- left: 0;
53
- top: 0;
54
- width: 100%; /* Full width */
55
- height: 100%; /* Full height */
56
- background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
57
- overflow-y: auto; /* enable scrolling */
58
- }
59
-
60
- .mobile-wallet-adapter-embedded-loading-container {
61
- display: flex;
62
- margin: auto;
63
- }
64
-
65
- .mobile-wallet-adapter-embedded-loading-animation {
66
- position: relative;
67
- left: -9999px;
68
- width: 10px;
69
- height: 10px;
70
- border-radius: 5px;
71
- background-color: var(--spinner-color);
72
- color: var(--spinner-color);
73
- box-shadow: 9984px 0 0 0 var(--spinner-color),
74
- 9999px 0 0 0 var(--spinner-color),
75
- 10014px 0 0 0 var(--spinner-color);
76
- animation: dot-typing 1.5s infinite linear;
28
+ let _wallet_standard_wallet = require("@wallet-standard/wallet");
29
+ let _solana_mobile_mobile_wallet_adapter_protocol = require("@solana-mobile/mobile-wallet-adapter-protocol");
30
+ let _solana_wallet_standard_features = require("@solana/wallet-standard-features");
31
+ let _wallet_standard_features = require("@wallet-standard/features");
32
+ let qrcode = require("qrcode");
33
+ qrcode = __toESM(qrcode);
34
+ //#region src/__forks__/react-native/createDefaultAuthorizationCache.ts
35
+ const CACHE_KEY = "SolanaMobileWalletAdapterWalletStandardDefaultAuthorizationCache";
36
+ function createDefaultAuthorizationCache() {
37
+ return {
38
+ async clear() {
39
+ try {
40
+ await _react_native_async_storage_async_storage.default.removeItem(CACHE_KEY);
41
+ } catch {}
42
+ },
43
+ async get() {
44
+ try {
45
+ const parsed = JSON.parse(await _react_native_async_storage_async_storage.default.getItem(CACHE_KEY));
46
+ if (parsed && parsed.accounts) {
47
+ const parsedAccounts = parsed.accounts.map((account) => {
48
+ return {
49
+ ...account,
50
+ publicKey: "publicKey" in account ? new Uint8Array(Object.values(account.publicKey)) : (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base58ToUint8Array)(account.address)
51
+ };
52
+ });
53
+ return {
54
+ ...parsed,
55
+ accounts: parsedAccounts
56
+ };
57
+ } else return parsed || void 0;
58
+ } catch {}
59
+ },
60
+ async set(authorizationResult) {
61
+ try {
62
+ await _react_native_async_storage_async_storage.default.setItem(CACHE_KEY, JSON.stringify(authorizationResult));
63
+ } catch {}
64
+ }
65
+ };
77
66
  }
78
-
79
- @keyframes dot-typing {
80
- 0% {
81
- box-shadow: 9984px 0 0 0 var(--spinner-color),
82
- 9999px 0 0 0 var(--spinner-color),
83
- 10014px 0 0 0 var(--spinner-color);
84
- }
85
- 16.667% {
86
- box-shadow: 9984px -10px 0 0 var(--spinner-color),
87
- 9999px 0 0 0 var(--spinner-color),
88
- 10014px 0 0 0 var(--spinner-color);
89
- }
90
- 33.333% {
91
- box-shadow: 9984px 0 0 0 var(--spinner-color),
92
- 9999px 0 0 0 var(--spinner-color),
93
- 10014px 0 0 0 var(--spinner-color);
94
- }
95
- 50% {
96
- box-shadow: 9984px 0 0 0 var(--spinner-color),
97
- 9999px -10px 0 0 var(--spinner-color),
98
- 10014px 0 0 0 var(--spinner-color);
99
- }
100
- 66.667% {
101
- box-shadow: 9984px 0 0 0 var(--spinner-color),
102
- 9999px 0 0 0 var(--spinner-color),
103
- 10014px 0 0 0 var(--spinner-color);
104
- }
105
- 83.333% {
106
- box-shadow: 9984px 0 0 0 var(--spinner-color),
107
- 9999px 0 0 0 var(--spinner-color),
108
- 10014px -10px 0 0 var(--spinner-color);
109
- }
110
- 100% {
111
- box-shadow: 9984px 0 0 0 var(--spinner-color),
112
- 9999px 0 0 0 var(--spinner-color),
113
- 10014px 0 0 0 var(--spinner-color);
114
- }
67
+ //#endregion
68
+ //#region src/createDefaultChainSelector.ts
69
+ function createDefaultChainSelector() {
70
+ return { async select(chains) {
71
+ if (chains.length === 1) return chains[0];
72
+ else if (chains.includes(_solana_wallet_standard_chains.SOLANA_MAINNET_CHAIN)) return _solana_wallet_standard_chains.SOLANA_MAINNET_CHAIN;
73
+ else return chains[0];
74
+ } };
115
75
  }
116
- `;
117
- var EmbeddedLoadingSpinner = class {
118
- #root = null;
119
- #eventListeners = {};
120
- #listenersAttached = false;
121
- dom = null;
122
- constructor() {
123
- this.init = this.init.bind(this);
124
- this.#root = document.getElementById("mobile-wallet-adapter-embedded-root-ui");
125
- }
126
- async init() {
127
- console.log("Injecting modal");
128
- this.#injectHTML();
129
- }
130
- open = () => {
131
- console.debug("Modal open");
132
- this.#attachEventListeners();
133
- if (this.#root) this.#root.style.display = "flex";
134
- };
135
- close = (event = void 0) => {
136
- console.debug("Modal close");
137
- this.#removeEventListeners();
138
- if (this.#root) this.#root.style.display = "none";
139
- this.#eventListeners["close"]?.forEach((listener) => listener(event));
140
- };
141
- addEventListener(event, listener) {
142
- this.#eventListeners[event]?.push(listener) || (this.#eventListeners[event] = [listener]);
143
- return () => this.removeEventListener(event, listener);
144
- }
145
- removeEventListener(event, listener) {
146
- this.#eventListeners[event] = this.#eventListeners[event]?.filter((existingListener) => listener !== existingListener);
147
- }
148
- #injectHTML() {
149
- if (this.dom) return;
150
- this.#root = document.createElement("div");
151
- this.#root.id = "mobile-wallet-adapter-embedded-root-ui";
152
- this.#root.innerHTML = modalHtml$1;
153
- this.#root.style.display = "none";
154
- const styles = document.createElement("style");
155
- styles.id = "mobile-wallet-adapter-embedded-modal-styles";
156
- styles.textContent = css$6;
157
- const host = document.createElement("div");
158
- this.dom = host.attachShadow({ mode: "closed" });
159
- host.style.setProperty("--spinner-color", "#FFFFFF");
160
- this.dom.appendChild(styles);
161
- this.dom.appendChild(this.#root);
162
- document.body.appendChild(host);
163
- }
164
- #attachEventListeners() {
165
- if (!this.#root || this.#listenersAttached) return;
166
- [...this.#root.querySelectorAll("[data-modal-close]")].forEach((closer) => closer?.addEventListener("click", (event) => {
167
- this.close(event);
168
- }));
169
- window.addEventListener("load", this.close);
170
- document.addEventListener("keydown", this.#handleKeyDown);
171
- this.#listenersAttached = true;
172
- }
173
- #removeEventListeners() {
174
- if (!this.#listenersAttached) return;
175
- window.removeEventListener("load", this.close);
176
- document.removeEventListener("keydown", this.#handleKeyDown);
177
- if (!this.#root) return;
178
- [...this.#root.querySelectorAll("[data-modal-close]")].forEach((closer) => closer?.removeEventListener("click", this.close));
179
- this.#listenersAttached = false;
180
- }
181
- #handleKeyDown = (event) => {
182
- if (event.key === "Escape") this.close(event);
183
- };
184
- };
185
76
  //#endregion
186
77
  //#region src/embedded-modal/modal.ts
187
- const modalHtml = `
78
+ const modalHtml$1 = `
188
79
  <div class="mobile-wallet-adapter-embedded-modal-container" role="dialog" aria-modal="true" aria-labelledby="modal-title">
189
80
  <div data-modal-close style="position: absolute; width: 100%; height: 100%;"></div>
190
81
  <div class="mobile-wallet-adapter-embedded-modal-card">
@@ -199,7 +90,7 @@ const modalHtml = `
199
90
  </div>
200
91
  </div>
201
92
  `;
202
- const css$5 = `
93
+ const css$6 = `
203
94
  .mobile-wallet-adapter-embedded-modal-container {
204
95
  display: flex; /* Use flexbox to center content */
205
96
  justify-content: center; /* Center horizontally */
@@ -299,13 +190,13 @@ var EmbeddedModal = class {
299
190
  }
300
191
  this.#root = document.createElement("div");
301
192
  this.#root.id = "mobile-wallet-adapter-embedded-root-ui";
302
- this.#root.innerHTML = modalHtml;
193
+ this.#root.innerHTML = modalHtml$1;
303
194
  this.#root.style.display = "none";
304
195
  const content = this.#root.querySelector(".mobile-wallet-adapter-embedded-modal-content");
305
196
  if (content) content.innerHTML = this.contentHtml;
306
197
  const styles = document.createElement("style");
307
198
  styles.id = "mobile-wallet-adapter-embedded-modal-styles";
308
- styles.textContent = css$5 + this.contentStyles;
199
+ styles.textContent = css$6 + this.contentStyles;
309
200
  const host = document.createElement("div");
310
201
  host.innerHTML = fonts;
311
202
  this.dom = host.attachShadow({ mode: "closed" });
@@ -333,295 +224,124 @@ var EmbeddedModal = class {
333
224
  };
334
225
  };
335
226
  //#endregion
336
- //#region src/embedded-modal/remoteConnectionModal.ts
337
- var RemoteConnectionModal = class extends EmbeddedModal {
338
- contentStyles = css$4;
339
- contentHtml = QRCodeHtml;
340
- async initWithQR(qrCode) {
227
+ //#region src/embedded-modal/errorModal.ts
228
+ const WALLET_NOT_FOUND_ERROR_MESSAGE = "To use mobile wallet adapter, you must have a compatible mobile wallet application installed on your device.";
229
+ 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.";
230
+ var ErrorModal = class extends EmbeddedModal {
231
+ contentStyles = css$5;
232
+ contentHtml = ErrorDialogHtml$3;
233
+ initWithError(error) {
341
234
  super.init();
342
- this.populateQRCode(qrCode);
235
+ this.populateError(error);
343
236
  }
344
- async populateQRCode(qrUrl) {
345
- const qrcodeContainer = this.dom?.getElementById("mobile-wallet-adapter-embedded-modal-qr-code-container");
346
- if (qrcodeContainer) {
347
- const qrCodeElement = await qrcode.default.toCanvas(qrUrl, {
348
- width: 200,
349
- margin: 0
350
- });
351
- if (qrcodeContainer.firstElementChild !== null) qrcodeContainer.replaceChild(qrCodeElement, qrcodeContainer.firstElementChild);
352
- else qrcodeContainer.appendChild(qrCodeElement);
353
- const qrPlaceholder = this.dom?.getElementById("mobile-wallet-adapter-embedded-modal-qr-placeholder");
354
- if (qrPlaceholder) qrPlaceholder.style.display = "none";
355
- } else console.error("QRCode Container not found");
237
+ populateError(error) {
238
+ const errorMessageElement = this.dom?.getElementById("mobile-wallet-adapter-error-message");
239
+ const actionBtn = this.dom?.getElementById("mobile-wallet-adapter-error-action");
240
+ if (errorMessageElement) {
241
+ if (error.name === "SolanaMobileWalletAdapterError") switch (error.code) {
242
+ case "ERROR_WALLET_NOT_FOUND":
243
+ errorMessageElement.innerHTML = WALLET_NOT_FOUND_ERROR_MESSAGE;
244
+ if (actionBtn) actionBtn.addEventListener("click", () => {
245
+ window.location.href = "https://solanamobile.com/wallets";
246
+ });
247
+ return;
248
+ case "ERROR_BROWSER_NOT_SUPPORTED":
249
+ errorMessageElement.innerHTML = BROWSER_NOT_SUPPORTED_ERROR_MESSAGE;
250
+ if (actionBtn) actionBtn.style.display = "none";
251
+ return;
252
+ }
253
+ errorMessageElement.innerHTML = `An unexpected error occurred: ${error.message}`;
254
+ } else console.log("Failed to locate error dialog element");
356
255
  }
357
256
  };
358
- const QRCodeHtml = `
359
- <div class="mobile-wallet-adapter-embedded-modal-qr-content">
360
- <div>
361
- <svg class="mobile-wallet-adapter-embedded-modal-icon" width="100%" height="100%">
362
- <circle r="52" cx="53" cy="53" fill="#99b3be" stroke="#000000" stroke-width="2"/>
363
- <path d="m 53,82.7305 c -3.3116,0 -6.1361,-1.169 -8.4735,-3.507 -2.338,-2.338 -3.507,-5.1625 -3.507,-8.4735 0,-3.3116 1.169,-6.1364 3.507,-8.4744 2.3374,-2.338 5.1619,-3.507 8.4735,-3.507 3.3116,0 6.1361,1.169 8.4735,3.507 2.338,2.338 3.507,5.1628 3.507,8.4744 0,3.311 -1.169,6.1355 -3.507,8.4735 -2.3374,2.338 -5.1619,3.507 -8.4735,3.507 z m 0.007,-5.25 c 1.8532,0 3.437,-0.6598 4.7512,-1.9793 1.3149,-1.3195 1.9723,-2.9058 1.9723,-4.7591 0,-1.8526 -0.6598,-3.4364 -1.9793,-4.7512 -1.3195,-1.3149 -2.9055,-1.9723 -4.7582,-1.9723 -1.8533,0 -3.437,0.6598 -4.7513,1.9793 -1.3148,1.3195 -1.9722,2.9058 -1.9722,4.7591 0,1.8527 0.6597,3.4364 1.9792,4.7512 1.3195,1.3149 2.9056,1.9723 4.7583,1.9723 z m -28,-33.5729 -3.85,-3.6347 c 4.1195,-4.025 8.8792,-7.1984 14.2791,-9.52 5.4005,-2.3223 11.2551,-3.4834 17.5639,-3.4834 6.3087,0 12.1634,1.1611 17.5639,3.4834 5.3999,2.3216 10.1596,5.495 14.2791,9.52 l -3.85,3.6347 C 77.2999,40.358 73.0684,37.5726 68.2985,35.5514 63.5292,33.5301 58.4296,32.5195 53,32.5195 c -5.4297,0 -10.5292,1.0106 -15.2985,3.0319 -4.7699,2.0212 -9.0014,4.8066 -12.6945,8.3562 z m 44.625,10.8771 c -2.2709,-2.1046 -4.7962,-3.7167 -7.5758,-4.8361 -2.7795,-1.12 -5.7983,-1.68 -9.0562,-1.68 -3.2579,0 -6.2621,0.56 -9.0125,1.68 -2.7504,1.1194 -5.2903,2.7315 -7.6195,4.8361 L 32.5189,51.15 c 2.8355,-2.6028 5.9777,-4.6086 9.4263,-6.0174 3.4481,-1.4087 7.133,-2.1131 11.0548,-2.1131 3.9217,0 7.5979,0.7044 11.0285,2.1131 3.43,1.4088 6.5631,3.4146 9.3992,6.0174 z"/>
364
- </svg>
365
- <div class="mobile-wallet-adapter-embedded-modal-title">Remote Mobile Wallet Adapter</div>
366
- </div>
367
- <div>
368
- <div>
369
- <h4 class="mobile-wallet-adapter-embedded-modal-qr-label">
370
- Open your wallet and scan this code
371
- </h4>
372
- </div>
373
- <div id="mobile-wallet-adapter-embedded-modal-qr-code-container" class="mobile-wallet-adapter-embedded-modal-qr-code-container">
374
- <div id="mobile-wallet-adapter-embedded-modal-qr-placeholder" class="mobile-wallet-adapter-embedded-modal-qr-placeholder"></div>
375
- </div>
376
- </div>
377
- </div>
378
- <div class="mobile-wallet-adapter-embedded-modal-divider"><hr></div>
379
- <div class="mobile-wallet-adapter-embedded-modal-footer">
380
- <div class="mobile-wallet-adapter-embedded-modal-subtitle">
381
- Follow the instructions on your device. When you're finished, this screen will update.
382
- </div>
383
- <div class="mobile-wallet-adapter-embedded-modal-progress-badge">
384
- <div>
385
- <div class="spinner">
386
- <div class="leftWrapper">
387
- <div class="left">
388
- <div class="circle"></div>
389
- </div>
390
- </div>
391
- <div class="rightWrapper">
392
- <div class="right">
393
- <div class="circle"></div>
394
- </div>
395
- </div>
396
- </div>
397
- </div>
398
- <div>Waiting for scan</div>
399
- </div>
257
+ const ErrorDialogHtml$3 = `
258
+ <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>
259
+ <div class="mobile-wallet-adapter-embedded-modal-title">We can't find a wallet.</div>
260
+ <div id="mobile-wallet-adapter-error-message" class="mobile-wallet-adapter-embedded-modal-subtitle"></div>
261
+ <div>
262
+ <button data-error-action id="mobile-wallet-adapter-error-action" class="mobile-wallet-adapter-embedded-modal-error-action">
263
+ Find a wallet
264
+ </button>
400
265
  </div>
401
266
  `;
402
- const css$4 = `
403
- .mobile-wallet-adapter-embedded-modal-qr-content {
404
- display: flex;
405
- margin-top: 10px;
406
- padding: 10px;
407
- }
408
-
409
- .mobile-wallet-adapter-embedded-modal-qr-content > div:first-child {
410
- display: flex;
411
- flex-direction: column;
412
- flex: 2;
413
- margin-top: auto;
414
- margin-right: 30px;
415
- }
416
-
417
- .mobile-wallet-adapter-embedded-modal-qr-content > div:nth-child(2) {
418
- display: flex;
419
- flex-direction: column;
420
- flex: 1;
421
- margin-left: auto;
267
+ const css$5 = `
268
+ .mobile-wallet-adapter-embedded-modal-content {
269
+ text-align: center;
422
270
  }
423
271
 
424
- .mobile-wallet-adapter-embedded-modal-footer {
425
- display: flex;
426
- padding: 10px;
272
+ .mobile-wallet-adapter-embedded-modal-error-icon {
273
+ margin-top: 24px;
427
274
  }
428
275
 
429
- .mobile-wallet-adapter-embedded-modal-icon {}
430
-
431
276
  .mobile-wallet-adapter-embedded-modal-title {
277
+ margin: 18px 100px auto 100px;
432
278
  color: #000000;
433
- font-size: 2.5em;
279
+ font-size: 2.75em;
434
280
  font-weight: 600;
435
281
  }
436
282
 
437
- .mobile-wallet-adapter-embedded-modal-qr-label {
438
- text-align: right;
439
- color: #000000;
440
- }
441
-
442
- .mobile-wallet-adapter-embedded-modal-qr-code-container {
443
- margin-left: auto;
444
- }
445
-
446
- .mobile-wallet-adapter-embedded-modal-qr-placeholder {
447
- margin-left: auto;
448
- min-width: 200px;
449
- min-height: 200px;
450
- background: linear-gradient(-60deg, #F7F8F8 30%, #ECEEEE 50%, #F7F8F8 70%);
451
- background-size: 200%;
452
- animation: placeholderAnimate 2.7s linear infinite;
453
- border-radius: 12px;
454
- }
455
-
456
- .mobile-wallet-adapter-embedded-modal-divider {
457
- margin-top: 20px;
458
- padding-left: 10px;
459
- padding-right: 10px;
460
- }
461
-
462
- .mobile-wallet-adapter-embedded-modal-divider hr {
463
- border-top: 1px solid #D9DEDE;
464
- }
465
-
466
283
  .mobile-wallet-adapter-embedded-modal-subtitle {
467
- margin: auto;
468
- margin-right: 60px;
469
- padding: 20px;
470
- color: #6E8286;
284
+ margin: 30px 60px 40px 60px;
285
+ color: #000000;
286
+ font-size: 1.25em;
287
+ font-weight: 400;
471
288
  }
472
289
 
473
- .mobile-wallet-adapter-embedded-modal-progress-badge {
474
- display: flex;
475
- background: #F7F8F8;
290
+ .mobile-wallet-adapter-embedded-modal-error-action {
291
+ display: block;
292
+ width: 100%;
476
293
  height: 56px;
477
- min-width: 200px;
478
- margin: auto;
479
- padding-left: 20px;
480
- padding-right: 20px;
294
+ /*margin-top: 40px;*/
295
+ font-size: 1.25em;
296
+ /*line-height: 24px;*/
297
+ /*letter-spacing: -1%;*/
298
+ background: #000000;
299
+ color: #FFFFFF;
481
300
  border-radius: 18px;
482
- color: #A8B6B8;
483
- align-items: center;
484
- }
485
-
486
- .mobile-wallet-adapter-embedded-modal-progress-badge > div:first-child {
487
- margin-left: auto;
488
- margin-right: 20px;
489
- }
490
-
491
- .mobile-wallet-adapter-embedded-modal-progress-badge > div:nth-child(2) {
492
- margin-right: auto;
493
301
  }
494
302
 
495
303
  /* Smaller screens */
496
304
  @media all and (max-width: 600px) {
497
- .mobile-wallet-adapter-embedded-modal-card {
498
- text-align: center;
499
- }
500
- .mobile-wallet-adapter-embedded-modal-qr-content {
501
- flex-direction: column;
502
- }
503
- .mobile-wallet-adapter-embedded-modal-qr-content > div:first-child {
504
- margin: auto;
505
- }
506
- .mobile-wallet-adapter-embedded-modal-qr-content > div:nth-child(2) {
507
- margin: auto;
508
- flex: 2 auto;
509
- }
510
- .mobile-wallet-adapter-embedded-modal-footer {
511
- flex-direction: column;
512
- }
513
- .mobile-wallet-adapter-embedded-modal-icon {
514
- display: none;
515
- }
516
305
  .mobile-wallet-adapter-embedded-modal-title {
517
306
  font-size: 1.5em;
307
+ margin-right: 12px;
308
+ margin-left: 12px;
518
309
  }
519
310
  .mobile-wallet-adapter-embedded-modal-subtitle {
520
- margin-right: unset;
521
- }
522
- .mobile-wallet-adapter-embedded-modal-qr-label {
523
- text-align: center;
524
- }
525
- .mobile-wallet-adapter-embedded-modal-qr-code-container {
526
- margin: auto;
527
- }
528
- .mobile-wallet-adapter-embedded-modal-qr-placeholder {
529
- margin: auto;
530
- }
531
- }
532
-
533
- /* QR Placeholder */
534
- @keyframes placeholderAnimate {
535
- 0% { background-position: 200% 0; }
536
- 100% { background-position: -200% 0; }
537
- }
538
-
539
- /* Spinner */
540
- @keyframes spinLeft {
541
- 0% {
542
- transform: rotate(20deg);
543
- }
544
- 50% {
545
- transform: rotate(160deg);
546
- }
547
- 100% {
548
- transform: rotate(20deg);
549
- }
550
- }
551
- @keyframes spinRight {
552
- 0% {
553
- transform: rotate(160deg);
554
- }
555
- 50% {
556
- transform: rotate(20deg);
557
- }
558
- 100% {
559
- transform: rotate(160deg);
560
- }
561
- }
562
- @keyframes spin {
563
- 0% {
564
- transform: rotate(0deg);
565
- }
566
- 100% {
567
- transform: rotate(2520deg);
311
+ margin-right: 12px;
312
+ margin-left: 12px;
568
313
  }
569
314
  }
570
-
571
- .spinner {
572
- position: relative;
573
- width: 1.5em;
574
- height: 1.5em;
575
- margin: auto;
576
- animation: spin 10s linear infinite;
577
- }
578
- .spinner::before {
579
- content: "";
580
- position: absolute;
581
- top: 0;
582
- bottom: 0;
583
- left: 0;
584
- right: 0;
585
- }
586
- .right, .rightWrapper, .left, .leftWrapper {
587
- position: absolute;
588
- top: 0;
589
- overflow: hidden;
590
- width: .75em;
591
- height: 1.5em;
592
- }
593
- .left, .leftWrapper {
594
- left: 0;
595
- }
596
- .right {
597
- left: -12px;
598
- }
599
- .rightWrapper {
600
- right: 0;
601
- }
602
- .circle {
603
- border: .125em solid #A8B6B8;
604
- width: 1.25em; /* 1.5em - 2*0.125em border */
605
- height: 1.25em; /* 1.5em - 2*0.125em border */
606
- border-radius: 0.75em; /* 0.5*1.5em spinner size 8 */
607
- }
608
- .left {
609
- transform-origin: 100% 50%;
610
- animation: spinLeft 2.5s cubic-bezier(.2,0,.8,1) infinite;
611
- }
612
- .right {
613
- transform-origin: 100% 50%;
614
- animation: spinRight 2.5s cubic-bezier(.2,0,.8,1) infinite;
615
- }
616
315
  `;
617
316
  //#endregion
618
- //#region src/icon.ts
619
- const icon = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03IDIuNUgxN0MxNy44Mjg0IDIuNSAxOC41IDMuMTcxNTcgMTguNSA0VjIwQzE4LjUgMjAuODI4NCAxNy44Mjg0IDIxLjUgMTcgMjEuNUg3QzYuMTcxNTcgMjEuNSA1LjUgMjAuODI4NCA1LjUgMjBWNEM1LjUgMy4xNzE1NyA2LjE3MTU3IDIuNSA3IDIuNVpNMyA0QzMgMS43OTA4NiA0Ljc5MDg2IDAgNyAwSDE3QzE5LjIwOTEgMCAyMSAxLjc5MDg2IDIxIDRWMjBDMjEgMjIuMjA5MSAxOS4yMDkxIDI0IDE3IDI0SDdDNC43OTA4NiAyNCAzIDIyLjIwOTEgMyAyMFY0Wk0xMSA0LjYxNTM4QzEwLjQ0NzcgNC42MTUzOCAxMCA1LjA2MzEgMTAgNS42MTUzOFY2LjM4NDYyQzEwIDYuOTM2OSAxMC40NDc3IDcuMzg0NjIgMTEgNy4zODQ2MkgxM0MxMy41NTIzIDcuMzg0NjIgMTQgNi45MzY5IDE0IDYuMzg0NjJWNS42MTUzOEMxNCA1LjA2MzEgMTMuNTUyMyA0LjYxNTM4IDEzIDQuNjE1MzhIMTFaIiBmaWxsPSIjRENCOEZGIi8+Cjwvc3ZnPgo=";
317
+ //#region src/createDefaultWalletNotFoundHandler.ts
318
+ async function defaultErrorModalWalletNotFoundHandler() {
319
+ if (typeof window !== "undefined") {
320
+ const userAgent = window.navigator.userAgent.toLowerCase();
321
+ const errorDialog = new ErrorModal();
322
+ if (userAgent.includes("wv")) errorDialog.initWithError({
323
+ name: "SolanaMobileWalletAdapterError",
324
+ code: "ERROR_BROWSER_NOT_SUPPORTED",
325
+ message: ""
326
+ });
327
+ else errorDialog.initWithError({
328
+ name: "SolanaMobileWalletAdapterError",
329
+ code: "ERROR_WALLET_NOT_FOUND",
330
+ message: ""
331
+ });
332
+ errorDialog.open();
333
+ }
334
+ }
335
+ function createDefaultWalletNotFoundHandler() {
336
+ return async () => {
337
+ defaultErrorModalWalletNotFoundHandler();
338
+ };
339
+ }
620
340
  //#endregion
621
341
  //#region src/embedded-modal/localConnectionModal.ts
622
342
  var LocalConnectionModal = class extends EmbeddedModal {
623
- contentStyles = css$3;
624
- contentHtml = ErrorDialogHtml$3;
343
+ contentStyles = css$4;
344
+ contentHtml = ErrorDialogHtml$2;
625
345
  initWithCallback(callback) {
626
346
  super.init();
627
347
  this.#prepareLaunchAction(callback);
@@ -636,7 +356,7 @@ var LocalConnectionModal = class extends EmbeddedModal {
636
356
  launchButton?.addEventListener("click", listener);
637
357
  }
638
358
  };
639
- const ErrorDialogHtml$3 = `
359
+ const ErrorDialogHtml$2 = `
640
360
  <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">
641
361
  <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"/>
642
362
  <mask id="mask0_189_522" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="8" y="8" width="32" height="32">
@@ -658,7 +378,7 @@ const ErrorDialogHtml$3 = `
658
378
  </button>
659
379
  </div>
660
380
  `;
661
- const css$3 = `
381
+ const css$4 = `
662
382
  .mobile-wallet-adapter-embedded-modal-close {
663
383
  display: none;
664
384
  }
@@ -696,10 +416,10 @@ const css$3 = `
696
416
  //#endregion
697
417
  //#region src/embedded-modal/loopbackBlockedModal.ts
698
418
  var LoopbackPermissionBlockedModal = class extends EmbeddedModal {
699
- contentStyles = css$2;
419
+ contentStyles = css$3;
700
420
  get contentHtml() {
701
421
  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";
702
- return ErrorDialogHtml$2.replace("{{PERMISSION_INSTRUCTION_DETAIL}}", instructions);
422
+ return ErrorDialogHtml$1.replace("{{PERMISSION_INSTRUCTION_DETAIL}}", instructions);
703
423
  }
704
424
  async init() {
705
425
  super.init();
@@ -714,7 +434,7 @@ var LoopbackPermissionBlockedModal = class extends EmbeddedModal {
714
434
  launchButton?.addEventListener("click", listener);
715
435
  }
716
436
  };
717
- const ErrorDialogHtml$2 = `
437
+ const ErrorDialogHtml$1 = `
718
438
  <div class="mobile-wallet-adapter-embedded-modal-header">
719
439
  Local Wallet Connection
720
440
  </div>
@@ -767,7 +487,7 @@ const ErrorDialogHtml$2 = `
767
487
  </button>
768
488
  </div>
769
489
  `;
770
- const css$2 = `
490
+ const css$3 = `
771
491
  .mobile-wallet-adapter-embedded-modal-close {
772
492
  display: none;
773
493
  }
@@ -857,8 +577,8 @@ const css$2 = `
857
577
  //#endregion
858
578
  //#region src/embedded-modal/loopbackPermissionModal.ts
859
579
  var LoopbackPermissionModal = class extends EmbeddedModal {
860
- contentStyles = css$1;
861
- contentHtml = ErrorDialogHtml$1;
580
+ contentStyles = css$2;
581
+ contentHtml = ErrorDialogHtml;
862
582
  async init() {
863
583
  super.init();
864
584
  this.#prepareLaunchAction();
@@ -869,13 +589,13 @@ var LoopbackPermissionModal = class extends EmbeddedModal {
869
589
  launchButton?.removeEventListener("click", listener);
870
590
  try {
871
591
  await fetch("http://localhost");
872
- } catch (e) {}
592
+ } catch {}
873
593
  this.close();
874
594
  };
875
595
  launchButton?.addEventListener("click", listener);
876
596
  }
877
597
  };
878
- const ErrorDialogHtml$1 = `
598
+ const ErrorDialogHtml = `
879
599
  <div class="mobile-wallet-adapter-embedded-modal-title">Allow connections to your wallet</div>
880
600
  <div id="mobile-wallet-adapter-local-launch-message" class="mobile-wallet-adapter-embedded-modal-subtitle">
881
601
  Tap "Allow" on the next screen
@@ -901,7 +621,7 @@ const ErrorDialogHtml$1 = `
901
621
  </button>
902
622
  </div>
903
623
  `;
904
- const css$1 = `
624
+ const css$2 = `
905
625
  .mobile-wallet-adapter-embedded-modal-close {
906
626
  display: none;
907
627
  }
@@ -935,84 +655,519 @@ const css$1 = `
935
655
  color: #FFFFFF;
936
656
  border-radius: 18px;
937
657
  }
938
- /* Smaller screens */
939
- @media all and (max-width: 600px) {
940
- .mobile-wallet-adapter-embedded-modal-title {
941
- font-size: 1.5em;
942
- margin-right: 12px;
943
- margin-left: 12px;
944
- }
945
- .mobile-wallet-adapter-embedded-modal-subtitle {
946
- margin-right: 12px;
947
- margin-left: 12px;
948
- }
658
+ /* Smaller screens */
659
+ @media all and (max-width: 600px) {
660
+ .mobile-wallet-adapter-embedded-modal-title {
661
+ font-size: 1.5em;
662
+ margin-right: 12px;
663
+ margin-left: 12px;
664
+ }
665
+ .mobile-wallet-adapter-embedded-modal-subtitle {
666
+ margin-right: 12px;
667
+ margin-left: 12px;
668
+ }
669
+ }
670
+ `;
671
+ //#endregion
672
+ //#region src/getIsSupported.ts
673
+ function getIsLocalAssociationSupported() {
674
+ return typeof window !== "undefined" && window.isSecureContext && typeof document !== "undefined" && /android/i.test(navigator.userAgent);
675
+ }
676
+ function getIsRemoteAssociationSupported() {
677
+ return typeof window !== "undefined" && window.isSecureContext && typeof document !== "undefined" && !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
678
+ }
679
+ function isWebView(userAgentString) {
680
+ return /(WebView|Version\/.+(Chrome)\/(\d+)\.(\d+)\.(\d+)\.(\d+)|; wv\).+(Chrome)\/(\d+)\.(\d+)\.(\d+)\.(\d+))/i.test(userAgentString);
681
+ }
682
+ function isSolanaMobileWebShell(userAgentString) {
683
+ return userAgentString.includes("Solana Mobile Web Shell");
684
+ }
685
+ function getIsPwaLaunchedAsApp() {
686
+ const isAndroidTwa = typeof document !== "undefined" && document.referrer.startsWith("android-app://");
687
+ if (typeof window == "undefined") return isAndroidTwa;
688
+ const isStandalone = window.matchMedia("(display-mode: standalone)").matches;
689
+ const isFullscreen = window.matchMedia("(display-mode: fullscreen)").matches;
690
+ const isMinimalUI = window.matchMedia("(display-mode: minimal-ui)").matches;
691
+ return isAndroidTwa || isStandalone || isFullscreen || isMinimalUI;
692
+ }
693
+ async function checkLocalNetworkAccessPermission() {
694
+ if (typeof navigator !== "undefined" && isSolanaMobileWebShell(navigator.userAgent)) return;
695
+ try {
696
+ const lnaPermission = await navigator.permissions.query({ name: "loopback-network" });
697
+ if (lnaPermission.state === "granted") return;
698
+ else if (lnaPermission.state === "denied") {
699
+ const modal = new LoopbackPermissionBlockedModal();
700
+ modal.init();
701
+ modal.open();
702
+ 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");
703
+ } else if (lnaPermission.state === "prompt") {
704
+ const modal = new LoopbackPermissionModal();
705
+ if (await new Promise((resolve, reject) => {
706
+ modal.addEventListener("close", (event) => {
707
+ 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 }));
708
+ });
709
+ lnaPermission.onchange = () => {
710
+ lnaPermission.onchange = null;
711
+ resolve(lnaPermission.state);
712
+ };
713
+ modal.init();
714
+ modal.open();
715
+ }) === "granted") {
716
+ const modal = new LocalConnectionModal();
717
+ await new Promise((resolve, reject) => {
718
+ modal.addEventListener("close", (event) => {
719
+ 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 }));
720
+ });
721
+ modal.initWithCallback(async () => {
722
+ resolve(true);
723
+ });
724
+ modal.open();
725
+ });
726
+ return;
727
+ } else return await checkLocalNetworkAccessPermission();
728
+ }
729
+ 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");
730
+ } catch (e) {
731
+ if (e instanceof TypeError && (e.message.includes("loopback-network") || e.message.includes("local-network-access"))) return;
732
+ if (e instanceof _solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterError) throw e;
733
+ 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");
734
+ }
735
+ }
736
+ //#endregion
737
+ //#region src/embedded-modal/loadingSpinner.ts
738
+ const modalHtml = `
739
+ <div class="mobile-wallet-adapter-embedded-loading-indicator" role="dialog" aria-modal="true" aria-labelledby="modal-title">
740
+ <div data-modal-close style="position: absolute; width: 100%; height: 100%;"></div>
741
+ <div class="mobile-wallet-adapter-embedded-loading-container">
742
+ <div class="mobile-wallet-adapter-embedded-loading-animation"></div>
743
+ </div>
744
+ </div>
745
+ `;
746
+ const css$1 = `
747
+ .mobile-wallet-adapter-embedded-loading-indicator {
748
+ display: flex; /* Use flexbox to center content */
749
+ justify-content: center; /* Center horizontally */
750
+ align-items: start; /* Center vertically */
751
+ position: fixed; /* Stay in place */
752
+ z-index: 1; /* Sit on top */
753
+ left: 0;
754
+ top: 0;
755
+ width: 100%; /* Full width */
756
+ height: 100%; /* Full height */
757
+ background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
758
+ overflow-y: auto; /* enable scrolling */
759
+ }
760
+
761
+ .mobile-wallet-adapter-embedded-loading-container {
762
+ display: flex;
763
+ margin: auto;
764
+ }
765
+
766
+ .mobile-wallet-adapter-embedded-loading-animation {
767
+ position: relative;
768
+ left: -9999px;
769
+ width: 10px;
770
+ height: 10px;
771
+ border-radius: 5px;
772
+ background-color: var(--spinner-color);
773
+ color: var(--spinner-color);
774
+ box-shadow: 9984px 0 0 0 var(--spinner-color),
775
+ 9999px 0 0 0 var(--spinner-color),
776
+ 10014px 0 0 0 var(--spinner-color);
777
+ animation: dot-typing 1.5s infinite linear;
778
+ }
779
+
780
+ @keyframes dot-typing {
781
+ 0% {
782
+ box-shadow: 9984px 0 0 0 var(--spinner-color),
783
+ 9999px 0 0 0 var(--spinner-color),
784
+ 10014px 0 0 0 var(--spinner-color);
785
+ }
786
+ 16.667% {
787
+ box-shadow: 9984px -10px 0 0 var(--spinner-color),
788
+ 9999px 0 0 0 var(--spinner-color),
789
+ 10014px 0 0 0 var(--spinner-color);
790
+ }
791
+ 33.333% {
792
+ box-shadow: 9984px 0 0 0 var(--spinner-color),
793
+ 9999px 0 0 0 var(--spinner-color),
794
+ 10014px 0 0 0 var(--spinner-color);
795
+ }
796
+ 50% {
797
+ box-shadow: 9984px 0 0 0 var(--spinner-color),
798
+ 9999px -10px 0 0 var(--spinner-color),
799
+ 10014px 0 0 0 var(--spinner-color);
800
+ }
801
+ 66.667% {
802
+ box-shadow: 9984px 0 0 0 var(--spinner-color),
803
+ 9999px 0 0 0 var(--spinner-color),
804
+ 10014px 0 0 0 var(--spinner-color);
805
+ }
806
+ 83.333% {
807
+ box-shadow: 9984px 0 0 0 var(--spinner-color),
808
+ 9999px 0 0 0 var(--spinner-color),
809
+ 10014px -10px 0 0 var(--spinner-color);
810
+ }
811
+ 100% {
812
+ box-shadow: 9984px 0 0 0 var(--spinner-color),
813
+ 9999px 0 0 0 var(--spinner-color),
814
+ 10014px 0 0 0 var(--spinner-color);
815
+ }
816
+ }
817
+ `;
818
+ var EmbeddedLoadingSpinner = class {
819
+ #root = null;
820
+ #eventListeners = {};
821
+ #listenersAttached = false;
822
+ dom = null;
823
+ constructor() {
824
+ this.init = this.init.bind(this);
825
+ this.#root = document.getElementById("mobile-wallet-adapter-embedded-root-ui");
826
+ }
827
+ async init() {
828
+ console.log("Injecting modal");
829
+ this.#injectHTML();
830
+ }
831
+ open = () => {
832
+ console.debug("Modal open");
833
+ this.#attachEventListeners();
834
+ if (this.#root) this.#root.style.display = "flex";
835
+ };
836
+ close = (event = void 0) => {
837
+ console.debug("Modal close");
838
+ this.#removeEventListeners();
839
+ if (this.#root) this.#root.style.display = "none";
840
+ this.#eventListeners["close"]?.forEach((listener) => listener(event));
841
+ };
842
+ addEventListener(event, listener) {
843
+ this.#eventListeners[event]?.push(listener) || (this.#eventListeners[event] = [listener]);
844
+ return () => this.removeEventListener(event, listener);
845
+ }
846
+ removeEventListener(event, listener) {
847
+ this.#eventListeners[event] = this.#eventListeners[event]?.filter((existingListener) => listener !== existingListener);
848
+ }
849
+ #injectHTML() {
850
+ if (this.dom) return;
851
+ this.#root = document.createElement("div");
852
+ this.#root.id = "mobile-wallet-adapter-embedded-root-ui";
853
+ this.#root.innerHTML = modalHtml;
854
+ this.#root.style.display = "none";
855
+ const styles = document.createElement("style");
856
+ styles.id = "mobile-wallet-adapter-embedded-modal-styles";
857
+ styles.textContent = css$1;
858
+ const host = document.createElement("div");
859
+ this.dom = host.attachShadow({ mode: "closed" });
860
+ host.style.setProperty("--spinner-color", "#FFFFFF");
861
+ this.dom.appendChild(styles);
862
+ this.dom.appendChild(this.#root);
863
+ document.body.appendChild(host);
864
+ }
865
+ #attachEventListeners() {
866
+ if (!this.#root || this.#listenersAttached) return;
867
+ [...this.#root.querySelectorAll("[data-modal-close]")].forEach((closer) => closer?.addEventListener("click", (event) => {
868
+ this.close(event);
869
+ }));
870
+ window.addEventListener("load", this.close);
871
+ document.addEventListener("keydown", this.#handleKeyDown);
872
+ this.#listenersAttached = true;
873
+ }
874
+ #removeEventListeners() {
875
+ if (!this.#listenersAttached) return;
876
+ window.removeEventListener("load", this.close);
877
+ document.removeEventListener("keydown", this.#handleKeyDown);
878
+ if (!this.#root) return;
879
+ [...this.#root.querySelectorAll("[data-modal-close]")].forEach((closer) => closer?.removeEventListener("click", this.close));
880
+ this.#listenersAttached = false;
881
+ }
882
+ #handleKeyDown = (event) => {
883
+ if (event.key === "Escape") this.close(event);
884
+ };
885
+ };
886
+ //#endregion
887
+ //#region src/embedded-modal/remoteConnectionModal.ts
888
+ var RemoteConnectionModal = class extends EmbeddedModal {
889
+ contentStyles = css;
890
+ contentHtml = QRCodeHtml;
891
+ async initWithQR(qrCode) {
892
+ super.init();
893
+ this.populateQRCode(qrCode);
894
+ }
895
+ async populateQRCode(qrUrl) {
896
+ const qrcodeContainer = this.dom?.getElementById("mobile-wallet-adapter-embedded-modal-qr-code-container");
897
+ if (qrcodeContainer) {
898
+ const qrCodeElement = await qrcode.default.toCanvas(qrUrl, {
899
+ width: 200,
900
+ margin: 0
901
+ });
902
+ if (qrcodeContainer.firstElementChild !== null) qrcodeContainer.replaceChild(qrCodeElement, qrcodeContainer.firstElementChild);
903
+ else qrcodeContainer.appendChild(qrCodeElement);
904
+ const qrPlaceholder = this.dom?.getElementById("mobile-wallet-adapter-embedded-modal-qr-placeholder");
905
+ if (qrPlaceholder) qrPlaceholder.style.display = "none";
906
+ } else console.error("QRCode Container not found");
907
+ }
908
+ };
909
+ const QRCodeHtml = `
910
+ <div class="mobile-wallet-adapter-embedded-modal-qr-content">
911
+ <div>
912
+ <svg class="mobile-wallet-adapter-embedded-modal-icon" width="100%" height="100%">
913
+ <circle r="52" cx="53" cy="53" fill="#99b3be" stroke="#000000" stroke-width="2"/>
914
+ <path d="m 53,82.7305 c -3.3116,0 -6.1361,-1.169 -8.4735,-3.507 -2.338,-2.338 -3.507,-5.1625 -3.507,-8.4735 0,-3.3116 1.169,-6.1364 3.507,-8.4744 2.3374,-2.338 5.1619,-3.507 8.4735,-3.507 3.3116,0 6.1361,1.169 8.4735,3.507 2.338,2.338 3.507,5.1628 3.507,8.4744 0,3.311 -1.169,6.1355 -3.507,8.4735 -2.3374,2.338 -5.1619,3.507 -8.4735,3.507 z m 0.007,-5.25 c 1.8532,0 3.437,-0.6598 4.7512,-1.9793 1.3149,-1.3195 1.9723,-2.9058 1.9723,-4.7591 0,-1.8526 -0.6598,-3.4364 -1.9793,-4.7512 -1.3195,-1.3149 -2.9055,-1.9723 -4.7582,-1.9723 -1.8533,0 -3.437,0.6598 -4.7513,1.9793 -1.3148,1.3195 -1.9722,2.9058 -1.9722,4.7591 0,1.8527 0.6597,3.4364 1.9792,4.7512 1.3195,1.3149 2.9056,1.9723 4.7583,1.9723 z m -28,-33.5729 -3.85,-3.6347 c 4.1195,-4.025 8.8792,-7.1984 14.2791,-9.52 5.4005,-2.3223 11.2551,-3.4834 17.5639,-3.4834 6.3087,0 12.1634,1.1611 17.5639,3.4834 5.3999,2.3216 10.1596,5.495 14.2791,9.52 l -3.85,3.6347 C 77.2999,40.358 73.0684,37.5726 68.2985,35.5514 63.5292,33.5301 58.4296,32.5195 53,32.5195 c -5.4297,0 -10.5292,1.0106 -15.2985,3.0319 -4.7699,2.0212 -9.0014,4.8066 -12.6945,8.3562 z m 44.625,10.8771 c -2.2709,-2.1046 -4.7962,-3.7167 -7.5758,-4.8361 -2.7795,-1.12 -5.7983,-1.68 -9.0562,-1.68 -3.2579,0 -6.2621,0.56 -9.0125,1.68 -2.7504,1.1194 -5.2903,2.7315 -7.6195,4.8361 L 32.5189,51.15 c 2.8355,-2.6028 5.9777,-4.6086 9.4263,-6.0174 3.4481,-1.4087 7.133,-2.1131 11.0548,-2.1131 3.9217,0 7.5979,0.7044 11.0285,2.1131 3.43,1.4088 6.5631,3.4146 9.3992,6.0174 z"/>
915
+ </svg>
916
+ <div class="mobile-wallet-adapter-embedded-modal-title">Remote Mobile Wallet Adapter</div>
917
+ </div>
918
+ <div>
919
+ <div>
920
+ <h4 class="mobile-wallet-adapter-embedded-modal-qr-label">
921
+ Open your wallet and scan this code
922
+ </h4>
923
+ </div>
924
+ <div id="mobile-wallet-adapter-embedded-modal-qr-code-container" class="mobile-wallet-adapter-embedded-modal-qr-code-container">
925
+ <div id="mobile-wallet-adapter-embedded-modal-qr-placeholder" class="mobile-wallet-adapter-embedded-modal-qr-placeholder"></div>
926
+ </div>
927
+ </div>
928
+ </div>
929
+ <div class="mobile-wallet-adapter-embedded-modal-divider"><hr></div>
930
+ <div class="mobile-wallet-adapter-embedded-modal-footer">
931
+ <div class="mobile-wallet-adapter-embedded-modal-subtitle">
932
+ Follow the instructions on your device. When you're finished, this screen will update.
933
+ </div>
934
+ <div class="mobile-wallet-adapter-embedded-modal-progress-badge">
935
+ <div>
936
+ <div class="spinner">
937
+ <div class="leftWrapper">
938
+ <div class="left">
939
+ <div class="circle"></div>
940
+ </div>
941
+ </div>
942
+ <div class="rightWrapper">
943
+ <div class="right">
944
+ <div class="circle"></div>
945
+ </div>
946
+ </div>
947
+ </div>
948
+ </div>
949
+ <div>Waiting for scan</div>
950
+ </div>
951
+ </div>
952
+ `;
953
+ const css = `
954
+ .mobile-wallet-adapter-embedded-modal-qr-content {
955
+ display: flex;
956
+ margin-top: 10px;
957
+ padding: 10px;
958
+ }
959
+
960
+ .mobile-wallet-adapter-embedded-modal-qr-content > div:first-child {
961
+ display: flex;
962
+ flex-direction: column;
963
+ flex: 2;
964
+ margin-top: auto;
965
+ margin-right: 30px;
966
+ }
967
+
968
+ .mobile-wallet-adapter-embedded-modal-qr-content > div:nth-child(2) {
969
+ display: flex;
970
+ flex-direction: column;
971
+ flex: 1;
972
+ margin-left: auto;
973
+ }
974
+
975
+ .mobile-wallet-adapter-embedded-modal-footer {
976
+ display: flex;
977
+ padding: 10px;
978
+ }
979
+
980
+ .mobile-wallet-adapter-embedded-modal-icon {}
981
+
982
+ .mobile-wallet-adapter-embedded-modal-title {
983
+ color: #000000;
984
+ font-size: 2.5em;
985
+ font-weight: 600;
986
+ }
987
+
988
+ .mobile-wallet-adapter-embedded-modal-qr-label {
989
+ text-align: right;
990
+ color: #000000;
991
+ }
992
+
993
+ .mobile-wallet-adapter-embedded-modal-qr-code-container {
994
+ margin-left: auto;
995
+ }
996
+
997
+ .mobile-wallet-adapter-embedded-modal-qr-placeholder {
998
+ margin-left: auto;
999
+ min-width: 200px;
1000
+ min-height: 200px;
1001
+ background: linear-gradient(-60deg, #F7F8F8 30%, #ECEEEE 50%, #F7F8F8 70%);
1002
+ background-size: 200%;
1003
+ animation: placeholderAnimate 2.7s linear infinite;
1004
+ border-radius: 12px;
1005
+ }
1006
+
1007
+ .mobile-wallet-adapter-embedded-modal-divider {
1008
+ margin-top: 20px;
1009
+ padding-left: 10px;
1010
+ padding-right: 10px;
1011
+ }
1012
+
1013
+ .mobile-wallet-adapter-embedded-modal-divider hr {
1014
+ border-top: 1px solid #D9DEDE;
1015
+ }
1016
+
1017
+ .mobile-wallet-adapter-embedded-modal-subtitle {
1018
+ margin: auto;
1019
+ margin-right: 60px;
1020
+ padding: 20px;
1021
+ color: #6E8286;
1022
+ }
1023
+
1024
+ .mobile-wallet-adapter-embedded-modal-progress-badge {
1025
+ display: flex;
1026
+ background: #F7F8F8;
1027
+ height: 56px;
1028
+ min-width: 200px;
1029
+ margin: auto;
1030
+ padding-left: 20px;
1031
+ padding-right: 20px;
1032
+ border-radius: 18px;
1033
+ color: #A8B6B8;
1034
+ align-items: center;
1035
+ }
1036
+
1037
+ .mobile-wallet-adapter-embedded-modal-progress-badge > div:first-child {
1038
+ margin-left: auto;
1039
+ margin-right: 20px;
1040
+ }
1041
+
1042
+ .mobile-wallet-adapter-embedded-modal-progress-badge > div:nth-child(2) {
1043
+ margin-right: auto;
1044
+ }
1045
+
1046
+ /* Smaller screens */
1047
+ @media all and (max-width: 600px) {
1048
+ .mobile-wallet-adapter-embedded-modal-card {
1049
+ text-align: center;
1050
+ }
1051
+ .mobile-wallet-adapter-embedded-modal-qr-content {
1052
+ flex-direction: column;
1053
+ }
1054
+ .mobile-wallet-adapter-embedded-modal-qr-content > div:first-child {
1055
+ margin: auto;
1056
+ }
1057
+ .mobile-wallet-adapter-embedded-modal-qr-content > div:nth-child(2) {
1058
+ margin: auto;
1059
+ flex: 2 auto;
1060
+ }
1061
+ .mobile-wallet-adapter-embedded-modal-footer {
1062
+ flex-direction: column;
1063
+ }
1064
+ .mobile-wallet-adapter-embedded-modal-icon {
1065
+ display: none;
1066
+ }
1067
+ .mobile-wallet-adapter-embedded-modal-title {
1068
+ font-size: 1.5em;
1069
+ }
1070
+ .mobile-wallet-adapter-embedded-modal-subtitle {
1071
+ margin-right: unset;
1072
+ }
1073
+ .mobile-wallet-adapter-embedded-modal-qr-label {
1074
+ text-align: center;
1075
+ }
1076
+ .mobile-wallet-adapter-embedded-modal-qr-code-container {
1077
+ margin: auto;
1078
+ }
1079
+ .mobile-wallet-adapter-embedded-modal-qr-placeholder {
1080
+ margin: auto;
1081
+ }
1082
+ }
1083
+
1084
+ /* QR Placeholder */
1085
+ @keyframes placeholderAnimate {
1086
+ 0% { background-position: 200% 0; }
1087
+ 100% { background-position: -200% 0; }
1088
+ }
1089
+
1090
+ /* Spinner */
1091
+ @keyframes spinLeft {
1092
+ 0% {
1093
+ transform: rotate(20deg);
1094
+ }
1095
+ 50% {
1096
+ transform: rotate(160deg);
1097
+ }
1098
+ 100% {
1099
+ transform: rotate(20deg);
1100
+ }
1101
+ }
1102
+ @keyframes spinRight {
1103
+ 0% {
1104
+ transform: rotate(160deg);
1105
+ }
1106
+ 50% {
1107
+ transform: rotate(20deg);
1108
+ }
1109
+ 100% {
1110
+ transform: rotate(160deg);
1111
+ }
1112
+ }
1113
+ @keyframes spin {
1114
+ 0% {
1115
+ transform: rotate(0deg);
1116
+ }
1117
+ 100% {
1118
+ transform: rotate(2520deg);
1119
+ }
1120
+ }
1121
+
1122
+ .spinner {
1123
+ position: relative;
1124
+ width: 1.5em;
1125
+ height: 1.5em;
1126
+ margin: auto;
1127
+ animation: spin 10s linear infinite;
1128
+ }
1129
+ .spinner::before {
1130
+ content: "";
1131
+ position: absolute;
1132
+ top: 0;
1133
+ bottom: 0;
1134
+ left: 0;
1135
+ right: 0;
1136
+ }
1137
+ .right, .rightWrapper, .left, .leftWrapper {
1138
+ position: absolute;
1139
+ top: 0;
1140
+ overflow: hidden;
1141
+ width: .75em;
1142
+ height: 1.5em;
949
1143
  }
950
- `;
951
- //#endregion
952
- //#region src/getIsSupported.ts
953
- function getIsLocalAssociationSupported() {
954
- return typeof window !== "undefined" && window.isSecureContext && typeof document !== "undefined" && /android/i.test(navigator.userAgent);
1144
+ .left, .leftWrapper {
1145
+ left: 0;
955
1146
  }
956
- function getIsRemoteAssociationSupported() {
957
- return typeof window !== "undefined" && window.isSecureContext && typeof document !== "undefined" && !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
1147
+ .right {
1148
+ left: -12px;
958
1149
  }
959
- function isWebView(userAgentString) {
960
- return /(WebView|Version\/.+(Chrome)\/(\d+)\.(\d+)\.(\d+)\.(\d+)|; wv\).+(Chrome)\/(\d+)\.(\d+)\.(\d+)\.(\d+))/i.test(userAgentString);
1150
+ .rightWrapper {
1151
+ right: 0;
961
1152
  }
962
- function isSolanaMobileWebShell(userAgentString) {
963
- return userAgentString.includes("Solana Mobile Web Shell");
1153
+ .circle {
1154
+ border: .125em solid #A8B6B8;
1155
+ width: 1.25em; /* 1.5em - 2*0.125em border */
1156
+ height: 1.25em; /* 1.5em - 2*0.125em border */
1157
+ border-radius: 0.75em; /* 0.5*1.5em spinner size 8 */
964
1158
  }
965
- function getIsPwaLaunchedAsApp() {
966
- const isAndroidTwa = typeof document !== "undefined" && document.referrer.startsWith("android-app://");
967
- if (typeof window == "undefined") return isAndroidTwa;
968
- const isStandalone = window.matchMedia("(display-mode: standalone)").matches;
969
- const isFullscreen = window.matchMedia("(display-mode: fullscreen)").matches;
970
- const isMinimalUI = window.matchMedia("(display-mode: minimal-ui)").matches;
971
- return isAndroidTwa || isStandalone || isFullscreen || isMinimalUI;
1159
+ .left {
1160
+ transform-origin: 100% 50%;
1161
+ animation: spinLeft 2.5s cubic-bezier(.2,0,.8,1) infinite;
972
1162
  }
973
- async function checkLocalNetworkAccessPermission() {
974
- if (typeof navigator !== "undefined" && isSolanaMobileWebShell(navigator.userAgent)) return;
975
- try {
976
- let lnaPermission = await navigator.permissions.query({ name: "loopback-network" });
977
- if (lnaPermission.state === "granted") return;
978
- else if (lnaPermission.state === "denied") {
979
- const modal = new LoopbackPermissionBlockedModal();
980
- modal.init();
981
- modal.open();
982
- 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");
983
- } else if (lnaPermission.state === "prompt") {
984
- const modal = new LoopbackPermissionModal();
985
- if (await new Promise((resolve, reject) => {
986
- modal.addEventListener("close", (event) => {
987
- 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 }));
988
- });
989
- lnaPermission.onchange = () => {
990
- lnaPermission.onchange = null;
991
- resolve(lnaPermission.state);
992
- };
993
- modal.init();
994
- modal.open();
995
- }) === "granted") {
996
- const modal = new LocalConnectionModal();
997
- await new Promise((resolve, reject) => {
998
- modal.addEventListener("close", (event) => {
999
- 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 }));
1000
- });
1001
- modal.initWithCallback(async () => {
1002
- resolve(true);
1003
- });
1004
- modal.open();
1005
- });
1006
- return;
1007
- } else return await checkLocalNetworkAccessPermission();
1008
- }
1009
- 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");
1010
- } catch (e) {
1011
- if (e instanceof TypeError && (e.message.includes("loopback-network") || e.message.includes("local-network-access"))) return;
1012
- if (e instanceof _solana_mobile_mobile_wallet_adapter_protocol.SolanaMobileWalletAdapterError) throw e;
1013
- 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");
1014
- }
1163
+ .right {
1164
+ transform-origin: 100% 50%;
1165
+ animation: spinRight 2.5s cubic-bezier(.2,0,.8,1) infinite;
1015
1166
  }
1167
+ `;
1168
+ //#endregion
1169
+ //#region src/icon.ts
1170
+ const icon = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03IDIuNUgxN0MxNy44Mjg0IDIuNSAxOC41IDMuMTcxNTcgMTguNSA0VjIwQzE4LjUgMjAuODI4NCAxNy44Mjg0IDIxLjUgMTcgMjEuNUg3QzYuMTcxNTcgMjEuNSA1LjUgMjAuODI4NCA1LjUgMjBWNEM1LjUgMy4xNzE1NyA2LjE3MTU3IDIuNSA3IDIuNVpNMyA0QzMgMS43OTA4NiA0Ljc5MDg2IDAgNyAwSDE3QzE5LjIwOTEgMCAyMSAxLjc5MDg2IDIxIDRWMjBDMjEgMjIuMjA5MSAxOS4yMDkxIDI0IDE3IDI0SDdDNC43OTA4NiAyNCAzIDIyLjIwOTEgMyAyMFY0Wk0xMSA0LjYxNTM4QzEwLjQ0NzcgNC42MTUzOCAxMCA1LjA2MzEgMTAgNS42MTUzOFY2LjM4NDYyQzEwIDYuOTM2OSAxMC40NDc3IDcuMzg0NjIgMTEgNy4zODQ2MkgxM0MxMy41NTIzIDcuMzg0NjIgMTQgNi45MzY5IDE0IDYuMzg0NjJWNS42MTUzOEMxNCA1LjA2MzEgMTMuNTUyMyA0LjYxNTM4IDEzIDQuNjE1MzhIMTFaIiBmaWxsPSIjRENCOEZGIi8+Cjwvc3ZnPgo=";
1016
1171
  //#endregion
1017
1172
  //#region src/wallet.ts
1018
1173
  const SolanaMobileWalletAdapterWalletName = "Mobile Wallet Adapter";
@@ -1025,6 +1180,9 @@ const DEFAULT_FEATURES = [
1025
1180
  _solana_wallet_standard_features.SolanaSignIn
1026
1181
  ];
1027
1182
  const WALLET_ASSOCIATION_TIMEOUT = 3e4;
1183
+ function getErrorMessage(error) {
1184
+ return error instanceof Error ? error.message : "Unknown error";
1185
+ }
1028
1186
  var LocalSolanaMobileWalletAdapterWallet = class {
1029
1187
  #listeners = {};
1030
1188
  #version = "1.0.0";
@@ -1141,7 +1299,7 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1141
1299
  } else return { accounts: this.accounts };
1142
1300
  } else await this.#performAuthorization();
1143
1301
  } catch (e) {
1144
- throw new Error(e instanceof Error && e.message || "Unknown error");
1302
+ throw new Error(getErrorMessage(e), { cause: e });
1145
1303
  } finally {
1146
1304
  this.#connecting = false;
1147
1305
  }
@@ -1176,7 +1334,7 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1176
1334
  return authorization;
1177
1335
  });
1178
1336
  } catch (e) {
1179
- throw new Error(e instanceof Error && e.message || "Unknown error");
1337
+ throw new Error(getErrorMessage(e), { cause: e });
1180
1338
  }
1181
1339
  };
1182
1340
  #handleAuthorizationResult = async (authorization) => {
@@ -1219,7 +1377,7 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1219
1377
  Promise.all([this.#authorizationCache.set(authorization), this.#handleAuthorizationResult(authorization)]);
1220
1378
  } catch (e) {
1221
1379
  this.#disconnect();
1222
- throw new Error(e instanceof Error && e.message || "Unknown error");
1380
+ throw new Error(getErrorMessage(e), { cause: e });
1223
1381
  }
1224
1382
  };
1225
1383
  #disconnect = async () => {
@@ -1235,10 +1393,12 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1235
1393
  const currentConnectionGeneration = this.#connectionGeneration;
1236
1394
  const loadingSpinner = new EmbeddedLoadingSpinner();
1237
1395
  try {
1396
+ let associating = true;
1238
1397
  let timeout = void 0;
1239
1398
  const result = await Promise.race([checkLocalNetworkAccessPermission().then(async () => {
1240
1399
  loadingSpinner.init();
1241
1400
  const { wallet, close } = await (0, _solana_mobile_mobile_wallet_adapter_protocol.startScenario)(config);
1401
+ associating = false;
1242
1402
  loadingSpinner.addEventListener("close", (event) => {
1243
1403
  if (event) close();
1244
1404
  });
@@ -1249,7 +1409,7 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1249
1409
  return result;
1250
1410
  }), new Promise((_, reject) => {
1251
1411
  timeout = setTimeout(() => {
1252
- 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 }));
1412
+ 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 }));
1253
1413
  }, WALLET_ASSOCIATION_TIMEOUT);
1254
1414
  })]);
1255
1415
  clearTimeout(timeout);
@@ -1270,9 +1430,9 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1270
1430
  };
1271
1431
  #accountsToWalletStandardAccounts = (accounts) => {
1272
1432
  return accounts.map((account) => {
1273
- const publicKey = (0, js_base64.toUint8Array)(account.address);
1433
+ const publicKey = (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array)(account.address);
1274
1434
  return {
1275
- address: bs58.default.encode(publicKey),
1435
+ address: (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base58FromUint8Array)(publicKey),
1276
1436
  publicKey,
1277
1437
  label: account.label,
1278
1438
  icon: account.icon,
@@ -1285,31 +1445,31 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1285
1445
  const { authToken, chain } = this.#assertIsAuthorized();
1286
1446
  try {
1287
1447
  const base64Transactions = transactions.map((tx) => {
1288
- return (0, js_base64.fromUint8Array)(tx);
1448
+ return (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64FromUint8Array)(tx);
1289
1449
  });
1290
1450
  return await this.#transact(async (wallet) => {
1291
1451
  await this.#performReauthorization(wallet, authToken, chain);
1292
- return (await wallet.signTransactions({ payloads: base64Transactions })).signed_payloads.map(js_base64.toUint8Array);
1452
+ return (await wallet.signTransactions({ payloads: base64Transactions })).signed_payloads.map(_solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array);
1293
1453
  });
1294
1454
  } catch (e) {
1295
- throw new Error(e instanceof Error && e.message || "Unknown error");
1455
+ throw new Error(getErrorMessage(e), { cause: e });
1296
1456
  }
1297
1457
  };
1298
1458
  #performSignAndSendTransaction = async (transaction, options) => {
1299
1459
  const { authToken, chain } = this.#assertIsAuthorized();
1300
1460
  try {
1301
1461
  return await this.#transact(async (wallet) => {
1302
- const [capabilities, _1] = await Promise.all([wallet.getCapabilities(), this.#performReauthorization(wallet, authToken, chain)]);
1462
+ const [capabilities] = await Promise.all([wallet.getCapabilities(), this.#performReauthorization(wallet, authToken, chain)]);
1303
1463
  if (capabilities.supports_sign_and_send_transactions) {
1304
- const base64Transaction = (0, js_base64.fromUint8Array)(transaction);
1464
+ const base64Transaction = (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64FromUint8Array)(transaction);
1305
1465
  return (await wallet.signAndSendTransactions({
1306
1466
  ...options,
1307
1467
  payloads: [base64Transaction]
1308
- })).signatures.map(js_base64.toUint8Array)[0];
1468
+ })).signatures.map(_solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array)[0];
1309
1469
  } else throw new Error("connected wallet does not support signAndSendTransaction");
1310
1470
  });
1311
1471
  } catch (e) {
1312
- throw new Error(e instanceof Error && e.message || "Unknown error");
1472
+ throw new Error(getErrorMessage(e), { cause: e });
1313
1473
  }
1314
1474
  };
1315
1475
  #signAndSendTransaction = async (...inputs) => {
@@ -1327,15 +1487,15 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1327
1487
  };
1328
1488
  #signMessage = async (...inputs) => {
1329
1489
  const { authToken, chain } = this.#assertIsAuthorized();
1330
- const addresses = inputs.map(({ account }) => (0, js_base64.fromUint8Array)(new Uint8Array(account.publicKey)));
1331
- const messages = inputs.map(({ message }) => (0, js_base64.fromUint8Array)(message));
1490
+ const addresses = inputs.map(({ account }) => (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64FromUint8Array)(new Uint8Array(account.publicKey)));
1491
+ const messages = inputs.map(({ message }) => (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64FromUint8Array)(message));
1332
1492
  try {
1333
1493
  return await this.#transact(async (wallet) => {
1334
1494
  await this.#performReauthorization(wallet, authToken, chain);
1335
1495
  return (await wallet.signMessages({
1336
1496
  addresses,
1337
1497
  payloads: messages
1338
- })).signed_payloads.map(js_base64.toUint8Array).map((signedMessage) => {
1498
+ })).signed_payloads.map(_solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array).map((signedMessage) => {
1339
1499
  return {
1340
1500
  signedMessage,
1341
1501
  signature: signedMessage.slice(-SIGNATURE_LENGTH_IN_BYTES)
@@ -1343,7 +1503,7 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1343
1503
  });
1344
1504
  });
1345
1505
  } catch (e) {
1346
- throw new Error(e instanceof Error && e.message || "Unknown error");
1506
+ throw new Error(getErrorMessage(e), { cause: e });
1347
1507
  }
1348
1508
  };
1349
1509
  #signIn = async (...inputs) => {
@@ -1364,16 +1524,16 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1364
1524
  const signedInAccount = authorizationResult.accounts.find((acc) => acc.address == signedInAddress);
1365
1525
  return {
1366
1526
  account: {
1367
- ...signedInAccount ?? { address: bs58.default.encode((0, js_base64.toUint8Array)(signedInAddress)) },
1368
- publicKey: (0, js_base64.toUint8Array)(signedInAddress),
1527
+ ...signedInAccount ?? { address: (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base58FromUint8Array)((0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array)(signedInAddress)) },
1528
+ publicKey: (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array)(signedInAddress),
1369
1529
  chains: signedInAccount?.chains ?? this.#chains,
1370
1530
  features: signedInAccount?.features ?? authorizationResult.capabilities.features
1371
1531
  },
1372
- signedMessage: (0, js_base64.toUint8Array)(authorizationResult.sign_in_result.signed_message),
1373
- signature: (0, js_base64.toUint8Array)(authorizationResult.sign_in_result.signature)
1532
+ signedMessage: (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array)(authorizationResult.sign_in_result.signed_message),
1533
+ signature: (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array)(authorizationResult.sign_in_result.signature)
1374
1534
  };
1375
1535
  } catch (e) {
1376
- throw new Error(e instanceof Error && e.message || "Unknown error");
1536
+ throw new Error(getErrorMessage(e), { cause: e });
1377
1537
  } finally {
1378
1538
  this.#connecting = false;
1379
1539
  }
@@ -1486,13 +1646,13 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1486
1646
  #off(event, listener) {
1487
1647
  this.#listeners[event] = this.#listeners[event]?.filter((existingListener) => listener !== existingListener);
1488
1648
  }
1489
- #connect = async ({ silent } = {}) => {
1649
+ #connect = async (_input = {}) => {
1490
1650
  if (this.#connecting || this.connected) return { accounts: this.accounts };
1491
1651
  this.#connecting = true;
1492
1652
  try {
1493
1653
  await this.#performAuthorization();
1494
1654
  } catch (e) {
1495
- throw new Error(e instanceof Error && e.message || "Unknown error");
1655
+ throw new Error(getErrorMessage(e), { cause: e });
1496
1656
  } finally {
1497
1657
  this.#connecting = false;
1498
1658
  }
@@ -1528,7 +1688,7 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1528
1688
  return authorizationResult;
1529
1689
  });
1530
1690
  } catch (e) {
1531
- throw new Error(e instanceof Error && e.message || "Unknown error");
1691
+ throw new Error(getErrorMessage(e), { cause: e });
1532
1692
  }
1533
1693
  };
1534
1694
  #handleAuthorizationResult = async (authorization) => {
@@ -1571,7 +1731,7 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1571
1731
  Promise.all([this.#authorizationCache.set(authorization), this.#handleAuthorizationResult(authorization)]);
1572
1732
  } catch (e) {
1573
1733
  this.#disconnect();
1574
- throw new Error(e instanceof Error && e.message || "Unknown error");
1734
+ throw new Error(getErrorMessage(e), { cause: e });
1575
1735
  }
1576
1736
  };
1577
1737
  #disconnect = async () => {
@@ -1623,9 +1783,9 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1623
1783
  };
1624
1784
  #accountsToWalletStandardAccounts = (accounts) => {
1625
1785
  return accounts.map((account) => {
1626
- const publicKey = (0, js_base64.toUint8Array)(account.address);
1786
+ const publicKey = (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array)(account.address);
1627
1787
  return {
1628
- address: bs58.default.encode(publicKey),
1788
+ address: (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base58FromUint8Array)(publicKey),
1629
1789
  publicKey,
1630
1790
  label: account.label,
1631
1791
  icon: account.icon,
@@ -1639,25 +1799,25 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1639
1799
  try {
1640
1800
  return await this.#transact(async (wallet) => {
1641
1801
  await this.#performReauthorization(wallet, authToken, chain);
1642
- return (await wallet.signTransactions({ payloads: transactions.map(js_base64.fromUint8Array) })).signed_payloads.map(js_base64.toUint8Array);
1802
+ return (await wallet.signTransactions({ payloads: transactions.map(_solana_mobile_mobile_wallet_adapter_protocol_encoding.base64FromUint8Array) })).signed_payloads.map(_solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array);
1643
1803
  });
1644
1804
  } catch (e) {
1645
- throw new Error(e instanceof Error && e.message || "Unknown error");
1805
+ throw new Error(getErrorMessage(e), { cause: e });
1646
1806
  }
1647
1807
  };
1648
1808
  #performSignAndSendTransaction = async (transaction, options) => {
1649
1809
  const { authToken, chain } = this.#assertIsAuthorized();
1650
1810
  try {
1651
1811
  return await this.#transact(async (wallet) => {
1652
- const [capabilities, _1] = await Promise.all([wallet.getCapabilities(), this.#performReauthorization(wallet, authToken, chain)]);
1812
+ const [capabilities] = await Promise.all([wallet.getCapabilities(), this.#performReauthorization(wallet, authToken, chain)]);
1653
1813
  if (capabilities.supports_sign_and_send_transactions) return (await wallet.signAndSendTransactions({
1654
1814
  ...options,
1655
- payloads: [(0, js_base64.fromUint8Array)(transaction)]
1656
- })).signatures.map(js_base64.toUint8Array)[0];
1815
+ payloads: [(0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64FromUint8Array)(transaction)]
1816
+ })).signatures.map(_solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array)[0];
1657
1817
  else throw new Error("connected wallet does not support signAndSendTransaction");
1658
1818
  });
1659
1819
  } catch (e) {
1660
- throw new Error(e instanceof Error && e.message || "Unknown error");
1820
+ throw new Error(getErrorMessage(e), { cause: e });
1661
1821
  }
1662
1822
  };
1663
1823
  #signAndSendTransaction = async (...inputs) => {
@@ -1675,15 +1835,15 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1675
1835
  };
1676
1836
  #signMessage = async (...inputs) => {
1677
1837
  const { authToken, chain } = this.#assertIsAuthorized();
1678
- const addresses = inputs.map(({ account }) => (0, js_base64.fromUint8Array)(new Uint8Array(account.publicKey)));
1679
- const messages = inputs.map(({ message }) => (0, js_base64.fromUint8Array)(message));
1838
+ const addresses = inputs.map(({ account }) => (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64FromUint8Array)(new Uint8Array(account.publicKey)));
1839
+ const messages = inputs.map(({ message }) => (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64FromUint8Array)(message));
1680
1840
  try {
1681
1841
  return await this.#transact(async (wallet) => {
1682
1842
  await this.#performReauthorization(wallet, authToken, chain);
1683
1843
  return (await wallet.signMessages({
1684
1844
  addresses,
1685
1845
  payloads: messages
1686
- })).signed_payloads.map(js_base64.toUint8Array).map((signedMessage) => {
1846
+ })).signed_payloads.map(_solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array).map((signedMessage) => {
1687
1847
  return {
1688
1848
  signedMessage,
1689
1849
  signature: signedMessage.slice(-SIGNATURE_LENGTH_IN_BYTES)
@@ -1691,7 +1851,7 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1691
1851
  });
1692
1852
  });
1693
1853
  } catch (e) {
1694
- throw new Error(e instanceof Error && e.message || "Unknown error");
1854
+ throw new Error(getErrorMessage(e), { cause: e });
1695
1855
  }
1696
1856
  };
1697
1857
  #signIn = async (...inputs) => {
@@ -1712,16 +1872,16 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1712
1872
  const signedInAccount = authorizationResult.accounts.find((acc) => acc.address == signedInAddress);
1713
1873
  return {
1714
1874
  account: {
1715
- ...signedInAccount ?? { address: bs58.default.encode((0, js_base64.toUint8Array)(signedInAddress)) },
1716
- publicKey: (0, js_base64.toUint8Array)(signedInAddress),
1875
+ ...signedInAccount ?? { address: (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base58FromUint8Array)((0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array)(signedInAddress)) },
1876
+ publicKey: (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array)(signedInAddress),
1717
1877
  chains: signedInAccount?.chains ?? this.#chains,
1718
1878
  features: signedInAccount?.features ?? authorizationResult.capabilities.features
1719
1879
  },
1720
- signedMessage: (0, js_base64.toUint8Array)(authorizationResult.sign_in_result.signed_message),
1721
- signature: (0, js_base64.toUint8Array)(authorizationResult.sign_in_result.signature)
1880
+ signedMessage: (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array)(authorizationResult.sign_in_result.signed_message),
1881
+ signature: (0, _solana_mobile_mobile_wallet_adapter_protocol_encoding.base64ToUint8Array)(authorizationResult.sign_in_result.signature)
1722
1882
  };
1723
1883
  } catch (e) {
1724
- throw new Error(e instanceof Error && e.message || "Unknown error");
1884
+ throw new Error(getErrorMessage(e), { cause: e });
1725
1885
  } finally {
1726
1886
  this.#connecting = false;
1727
1887
  }
@@ -1746,163 +1906,6 @@ function registerMwa(config) {
1746
1906
  }));
1747
1907
  }
1748
1908
  //#endregion
1749
- //#region src/embedded-modal/errorModal.ts
1750
- const WALLET_NOT_FOUND_ERROR_MESSAGE = "To use mobile wallet adapter, you must have a compatible mobile wallet application installed on your device.";
1751
- 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.";
1752
- var ErrorModal = class extends EmbeddedModal {
1753
- contentStyles = css;
1754
- contentHtml = ErrorDialogHtml;
1755
- initWithError(error) {
1756
- super.init();
1757
- this.populateError(error);
1758
- }
1759
- populateError(error) {
1760
- const errorMessageElement = this.dom?.getElementById("mobile-wallet-adapter-error-message");
1761
- const actionBtn = this.dom?.getElementById("mobile-wallet-adapter-error-action");
1762
- if (errorMessageElement) {
1763
- if (error.name === "SolanaMobileWalletAdapterError") switch (error.code) {
1764
- case "ERROR_WALLET_NOT_FOUND":
1765
- errorMessageElement.innerHTML = WALLET_NOT_FOUND_ERROR_MESSAGE;
1766
- if (actionBtn) actionBtn.addEventListener("click", () => {
1767
- window.location.href = "https://solanamobile.com/wallets";
1768
- });
1769
- return;
1770
- case "ERROR_BROWSER_NOT_SUPPORTED":
1771
- errorMessageElement.innerHTML = BROWSER_NOT_SUPPORTED_ERROR_MESSAGE;
1772
- if (actionBtn) actionBtn.style.display = "none";
1773
- return;
1774
- }
1775
- errorMessageElement.innerHTML = `An unexpected error occurred: ${error.message}`;
1776
- } else console.log("Failed to locate error dialog element");
1777
- }
1778
- };
1779
- const ErrorDialogHtml = `
1780
- <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>
1781
- <div class="mobile-wallet-adapter-embedded-modal-title">We can't find a wallet.</div>
1782
- <div id="mobile-wallet-adapter-error-message" class="mobile-wallet-adapter-embedded-modal-subtitle"></div>
1783
- <div>
1784
- <button data-error-action id="mobile-wallet-adapter-error-action" class="mobile-wallet-adapter-embedded-modal-error-action">
1785
- Find a wallet
1786
- </button>
1787
- </div>
1788
- `;
1789
- const css = `
1790
- .mobile-wallet-adapter-embedded-modal-content {
1791
- text-align: center;
1792
- }
1793
-
1794
- .mobile-wallet-adapter-embedded-modal-error-icon {
1795
- margin-top: 24px;
1796
- }
1797
-
1798
- .mobile-wallet-adapter-embedded-modal-title {
1799
- margin: 18px 100px auto 100px;
1800
- color: #000000;
1801
- font-size: 2.75em;
1802
- font-weight: 600;
1803
- }
1804
-
1805
- .mobile-wallet-adapter-embedded-modal-subtitle {
1806
- margin: 30px 60px 40px 60px;
1807
- color: #000000;
1808
- font-size: 1.25em;
1809
- font-weight: 400;
1810
- }
1811
-
1812
- .mobile-wallet-adapter-embedded-modal-error-action {
1813
- display: block;
1814
- width: 100%;
1815
- height: 56px;
1816
- /*margin-top: 40px;*/
1817
- font-size: 1.25em;
1818
- /*line-height: 24px;*/
1819
- /*letter-spacing: -1%;*/
1820
- background: #000000;
1821
- color: #FFFFFF;
1822
- border-radius: 18px;
1823
- }
1824
-
1825
- /* Smaller screens */
1826
- @media all and (max-width: 600px) {
1827
- .mobile-wallet-adapter-embedded-modal-title {
1828
- font-size: 1.5em;
1829
- margin-right: 12px;
1830
- margin-left: 12px;
1831
- }
1832
- .mobile-wallet-adapter-embedded-modal-subtitle {
1833
- margin-right: 12px;
1834
- margin-left: 12px;
1835
- }
1836
- }
1837
- `;
1838
- //#endregion
1839
- //#region src/createDefaultWalletNotFoundHandler.ts
1840
- async function defaultErrorModalWalletNotFoundHandler() {
1841
- if (typeof window !== "undefined") {
1842
- const userAgent = window.navigator.userAgent.toLowerCase();
1843
- const errorDialog = new ErrorModal();
1844
- if (userAgent.includes("wv")) errorDialog.initWithError({
1845
- name: "SolanaMobileWalletAdapterError",
1846
- code: "ERROR_BROWSER_NOT_SUPPORTED",
1847
- message: ""
1848
- });
1849
- else errorDialog.initWithError({
1850
- name: "SolanaMobileWalletAdapterError",
1851
- code: "ERROR_WALLET_NOT_FOUND",
1852
- message: ""
1853
- });
1854
- errorDialog.open();
1855
- }
1856
- }
1857
- function createDefaultWalletNotFoundHandler() {
1858
- return async () => {
1859
- defaultErrorModalWalletNotFoundHandler();
1860
- };
1861
- }
1862
- //#endregion
1863
- //#region src/__forks__/react-native/createDefaultAuthorizationCache.ts
1864
- const CACHE_KEY = "SolanaMobileWalletAdapterWalletStandardDefaultAuthorizationCache";
1865
- function createDefaultAuthorizationCache() {
1866
- return {
1867
- async clear() {
1868
- try {
1869
- await _react_native_async_storage_async_storage.default.removeItem(CACHE_KEY);
1870
- } catch {}
1871
- },
1872
- async get() {
1873
- try {
1874
- const parsed = JSON.parse(await _react_native_async_storage_async_storage.default.getItem(CACHE_KEY));
1875
- if (parsed && parsed.accounts) {
1876
- const parsedAccounts = parsed.accounts.map((account) => {
1877
- return {
1878
- ...account,
1879
- publicKey: "publicKey" in account ? new Uint8Array(Object.values(account.publicKey)) : bs58.default.decode(account.address)
1880
- };
1881
- });
1882
- return {
1883
- ...parsed,
1884
- accounts: parsedAccounts
1885
- };
1886
- } else return parsed || void 0;
1887
- } catch {}
1888
- },
1889
- async set(authorizationResult) {
1890
- try {
1891
- await _react_native_async_storage_async_storage.default.setItem(CACHE_KEY, JSON.stringify(authorizationResult));
1892
- } catch {}
1893
- }
1894
- };
1895
- }
1896
- //#endregion
1897
- //#region src/createDefaultChainSelector.ts
1898
- function createDefaultChainSelector() {
1899
- return { async select(chains) {
1900
- if (chains.length === 1) return chains[0];
1901
- else if (chains.includes(_solana_wallet_standard_chains.SOLANA_MAINNET_CHAIN)) return _solana_wallet_standard_chains.SOLANA_MAINNET_CHAIN;
1902
- else return chains[0];
1903
- } };
1904
- }
1905
- //#endregion
1906
1909
  exports.LocalSolanaMobileWalletAdapterWallet = LocalSolanaMobileWalletAdapterWallet;
1907
1910
  exports.RemoteSolanaMobileWalletAdapterWallet = RemoteSolanaMobileWalletAdapterWallet;
1908
1911
  exports.SolanaMobileWalletAdapterRemoteWalletName = SolanaMobileWalletAdapterRemoteWalletName;