@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.
package/lib/esm/index.js CHANGED
@@ -1,162 +1,62 @@
1
- import { SolanaSignAndSendTransaction, SolanaSignIn, SolanaSignMessage, SolanaSignTransaction } from "@solana/wallet-standard-features";
2
- import QRCode from "qrcode";
1
+ import { base58FromUint8Array, base58ToUint8Array, base64FromUint8Array, base64ToUint8Array } from "@solana-mobile/mobile-wallet-adapter-protocol/encoding";
2
+ import { SOLANA_MAINNET_CHAIN } from "@solana/wallet-standard-chains";
3
+ import { registerWallet } from "@wallet-standard/wallet";
3
4
  import { SolanaMobileWalletAdapterError, SolanaMobileWalletAdapterErrorCode, startRemoteScenario, startScenario } from "@solana-mobile/mobile-wallet-adapter-protocol";
5
+ import { SolanaSignAndSendTransaction, SolanaSignIn, SolanaSignMessage, SolanaSignTransaction } from "@solana/wallet-standard-features";
4
6
  import { StandardConnect, StandardDisconnect, StandardEvents } from "@wallet-standard/features";
5
- import base58 from "bs58";
6
- import { registerWallet } from "@wallet-standard/wallet";
7
- import { SOLANA_MAINNET_CHAIN } from "@solana/wallet-standard-chains";
8
- //#region src/embedded-modal/loadingSpinner.ts
9
- const modalHtml$1 = `
10
- <div class="mobile-wallet-adapter-embedded-loading-indicator" role="dialog" aria-modal="true" aria-labelledby="modal-title">
11
- <div data-modal-close style="position: absolute; width: 100%; height: 100%;"></div>
12
- <div class="mobile-wallet-adapter-embedded-loading-container">
13
- <div class="mobile-wallet-adapter-embedded-loading-animation"></div>
14
- </div>
15
- </div>
16
- `;
17
- const css$6 = `
18
- .mobile-wallet-adapter-embedded-loading-indicator {
19
- display: flex; /* Use flexbox to center content */
20
- justify-content: center; /* Center horizontally */
21
- align-items: start; /* Center vertically */
22
- position: fixed; /* Stay in place */
23
- z-index: 1; /* Sit on top */
24
- left: 0;
25
- top: 0;
26
- width: 100%; /* Full width */
27
- height: 100%; /* Full height */
28
- background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
29
- overflow-y: auto; /* enable scrolling */
30
- }
31
-
32
- .mobile-wallet-adapter-embedded-loading-container {
33
- display: flex;
34
- margin: auto;
35
- }
36
-
37
- .mobile-wallet-adapter-embedded-loading-animation {
38
- position: relative;
39
- left: -9999px;
40
- width: 10px;
41
- height: 10px;
42
- border-radius: 5px;
43
- background-color: var(--spinner-color);
44
- color: var(--spinner-color);
45
- box-shadow: 9984px 0 0 0 var(--spinner-color),
46
- 9999px 0 0 0 var(--spinner-color),
47
- 10014px 0 0 0 var(--spinner-color);
48
- animation: dot-typing 1.5s infinite linear;
7
+ import QRCode from "qrcode";
8
+ //#region src/createDefaultAuthorizationCache.ts
9
+ const CACHE_KEY = "SolanaMobileWalletAdapterDefaultAuthorizationCache";
10
+ function createDefaultAuthorizationCache() {
11
+ let storage;
12
+ try {
13
+ storage = window.localStorage;
14
+ } catch {}
15
+ return {
16
+ async clear() {
17
+ if (!storage) return;
18
+ try {
19
+ storage.removeItem(CACHE_KEY);
20
+ } catch {}
21
+ },
22
+ async get() {
23
+ if (!storage) return;
24
+ try {
25
+ const parsed = JSON.parse(storage.getItem(CACHE_KEY));
26
+ if (parsed && parsed.accounts) {
27
+ const parsedAccounts = parsed.accounts.map((account) => {
28
+ return {
29
+ ...account,
30
+ publicKey: "publicKey" in account ? new Uint8Array(Object.values(account.publicKey)) : base58ToUint8Array(account.address)
31
+ };
32
+ });
33
+ return {
34
+ ...parsed,
35
+ accounts: parsedAccounts
36
+ };
37
+ } else return parsed || void 0;
38
+ } catch {}
39
+ },
40
+ async set(authorization) {
41
+ if (!storage) return;
42
+ try {
43
+ storage.setItem(CACHE_KEY, JSON.stringify(authorization));
44
+ } catch {}
45
+ }
46
+ };
49
47
  }
50
-
51
- @keyframes dot-typing {
52
- 0% {
53
- box-shadow: 9984px 0 0 0 var(--spinner-color),
54
- 9999px 0 0 0 var(--spinner-color),
55
- 10014px 0 0 0 var(--spinner-color);
56
- }
57
- 16.667% {
58
- box-shadow: 9984px -10px 0 0 var(--spinner-color),
59
- 9999px 0 0 0 var(--spinner-color),
60
- 10014px 0 0 0 var(--spinner-color);
61
- }
62
- 33.333% {
63
- box-shadow: 9984px 0 0 0 var(--spinner-color),
64
- 9999px 0 0 0 var(--spinner-color),
65
- 10014px 0 0 0 var(--spinner-color);
66
- }
67
- 50% {
68
- box-shadow: 9984px 0 0 0 var(--spinner-color),
69
- 9999px -10px 0 0 var(--spinner-color),
70
- 10014px 0 0 0 var(--spinner-color);
71
- }
72
- 66.667% {
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
- }
77
- 83.333% {
78
- box-shadow: 9984px 0 0 0 var(--spinner-color),
79
- 9999px 0 0 0 var(--spinner-color),
80
- 10014px -10px 0 0 var(--spinner-color);
81
- }
82
- 100% {
83
- box-shadow: 9984px 0 0 0 var(--spinner-color),
84
- 9999px 0 0 0 var(--spinner-color),
85
- 10014px 0 0 0 var(--spinner-color);
86
- }
48
+ //#endregion
49
+ //#region src/createDefaultChainSelector.ts
50
+ function createDefaultChainSelector() {
51
+ return { async select(chains) {
52
+ if (chains.length === 1) return chains[0];
53
+ else if (chains.includes(SOLANA_MAINNET_CHAIN)) return SOLANA_MAINNET_CHAIN;
54
+ else return chains[0];
55
+ } };
87
56
  }
88
- `;
89
- var EmbeddedLoadingSpinner = class {
90
- #root = null;
91
- #eventListeners = {};
92
- #listenersAttached = false;
93
- dom = null;
94
- constructor() {
95
- this.init = this.init.bind(this);
96
- this.#root = document.getElementById("mobile-wallet-adapter-embedded-root-ui");
97
- }
98
- async init() {
99
- console.log("Injecting modal");
100
- this.#injectHTML();
101
- }
102
- open = () => {
103
- console.debug("Modal open");
104
- this.#attachEventListeners();
105
- if (this.#root) this.#root.style.display = "flex";
106
- };
107
- close = (event = void 0) => {
108
- console.debug("Modal close");
109
- this.#removeEventListeners();
110
- if (this.#root) this.#root.style.display = "none";
111
- this.#eventListeners["close"]?.forEach((listener) => listener(event));
112
- };
113
- addEventListener(event, listener) {
114
- this.#eventListeners[event]?.push(listener) || (this.#eventListeners[event] = [listener]);
115
- return () => this.removeEventListener(event, listener);
116
- }
117
- removeEventListener(event, listener) {
118
- this.#eventListeners[event] = this.#eventListeners[event]?.filter((existingListener) => listener !== existingListener);
119
- }
120
- #injectHTML() {
121
- if (this.dom) return;
122
- this.#root = document.createElement("div");
123
- this.#root.id = "mobile-wallet-adapter-embedded-root-ui";
124
- this.#root.innerHTML = modalHtml$1;
125
- this.#root.style.display = "none";
126
- const styles = document.createElement("style");
127
- styles.id = "mobile-wallet-adapter-embedded-modal-styles";
128
- styles.textContent = css$6;
129
- const host = document.createElement("div");
130
- this.dom = host.attachShadow({ mode: "closed" });
131
- host.style.setProperty("--spinner-color", "#FFFFFF");
132
- this.dom.appendChild(styles);
133
- this.dom.appendChild(this.#root);
134
- document.body.appendChild(host);
135
- }
136
- #attachEventListeners() {
137
- if (!this.#root || this.#listenersAttached) return;
138
- [...this.#root.querySelectorAll("[data-modal-close]")].forEach((closer) => closer?.addEventListener("click", (event) => {
139
- this.close(event);
140
- }));
141
- window.addEventListener("load", this.close);
142
- document.addEventListener("keydown", this.#handleKeyDown);
143
- this.#listenersAttached = true;
144
- }
145
- #removeEventListeners() {
146
- if (!this.#listenersAttached) return;
147
- window.removeEventListener("load", this.close);
148
- document.removeEventListener("keydown", this.#handleKeyDown);
149
- if (!this.#root) return;
150
- [...this.#root.querySelectorAll("[data-modal-close]")].forEach((closer) => closer?.removeEventListener("click", this.close));
151
- this.#listenersAttached = false;
152
- }
153
- #handleKeyDown = (event) => {
154
- if (event.key === "Escape") this.close(event);
155
- };
156
- };
157
57
  //#endregion
158
58
  //#region src/embedded-modal/modal.ts
159
- const modalHtml = `
59
+ const modalHtml$1 = `
160
60
  <div class="mobile-wallet-adapter-embedded-modal-container" role="dialog" aria-modal="true" aria-labelledby="modal-title">
161
61
  <div data-modal-close style="position: absolute; width: 100%; height: 100%;"></div>
162
62
  <div class="mobile-wallet-adapter-embedded-modal-card">
@@ -171,7 +71,7 @@ const modalHtml = `
171
71
  </div>
172
72
  </div>
173
73
  `;
174
- const css$5 = `
74
+ const css$6 = `
175
75
  .mobile-wallet-adapter-embedded-modal-container {
176
76
  display: flex; /* Use flexbox to center content */
177
77
  justify-content: center; /* Center horizontally */
@@ -271,13 +171,13 @@ var EmbeddedModal = class {
271
171
  }
272
172
  this.#root = document.createElement("div");
273
173
  this.#root.id = "mobile-wallet-adapter-embedded-root-ui";
274
- this.#root.innerHTML = modalHtml;
174
+ this.#root.innerHTML = modalHtml$1;
275
175
  this.#root.style.display = "none";
276
176
  const content = this.#root.querySelector(".mobile-wallet-adapter-embedded-modal-content");
277
177
  if (content) content.innerHTML = this.contentHtml;
278
178
  const styles = document.createElement("style");
279
179
  styles.id = "mobile-wallet-adapter-embedded-modal-styles";
280
- styles.textContent = css$5 + this.contentStyles;
180
+ styles.textContent = css$6 + this.contentStyles;
281
181
  const host = document.createElement("div");
282
182
  host.innerHTML = fonts;
283
183
  this.dom = host.attachShadow({ mode: "closed" });
@@ -305,303 +205,124 @@ var EmbeddedModal = class {
305
205
  };
306
206
  };
307
207
  //#endregion
308
- //#region src/embedded-modal/remoteConnectionModal.ts
309
- var RemoteConnectionModal = class extends EmbeddedModal {
310
- contentStyles = css$4;
311
- contentHtml = QRCodeHtml;
312
- async initWithQR(qrCode) {
208
+ //#region src/embedded-modal/errorModal.ts
209
+ const WALLET_NOT_FOUND_ERROR_MESSAGE = "To use mobile wallet adapter, you must have a compatible mobile wallet application installed on your device.";
210
+ 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.";
211
+ var ErrorModal = class extends EmbeddedModal {
212
+ contentStyles = css$5;
213
+ contentHtml = ErrorDialogHtml$3;
214
+ initWithError(error) {
313
215
  super.init();
314
- this.populateQRCode(qrCode);
216
+ this.populateError(error);
315
217
  }
316
- async populateQRCode(qrUrl) {
317
- const qrcodeContainer = this.dom?.getElementById("mobile-wallet-adapter-embedded-modal-qr-code-container");
318
- if (qrcodeContainer) {
319
- const qrCodeElement = await QRCode.toCanvas(qrUrl, {
320
- width: 200,
321
- margin: 0
322
- });
323
- if (qrcodeContainer.firstElementChild !== null) qrcodeContainer.replaceChild(qrCodeElement, qrcodeContainer.firstElementChild);
324
- else qrcodeContainer.appendChild(qrCodeElement);
325
- const qrPlaceholder = this.dom?.getElementById("mobile-wallet-adapter-embedded-modal-qr-placeholder");
326
- if (qrPlaceholder) qrPlaceholder.style.display = "none";
327
- } else console.error("QRCode Container not found");
218
+ populateError(error) {
219
+ const errorMessageElement = this.dom?.getElementById("mobile-wallet-adapter-error-message");
220
+ const actionBtn = this.dom?.getElementById("mobile-wallet-adapter-error-action");
221
+ if (errorMessageElement) {
222
+ if (error.name === "SolanaMobileWalletAdapterError") switch (error.code) {
223
+ case "ERROR_WALLET_NOT_FOUND":
224
+ errorMessageElement.innerHTML = WALLET_NOT_FOUND_ERROR_MESSAGE;
225
+ if (actionBtn) actionBtn.addEventListener("click", () => {
226
+ window.location.href = "https://solanamobile.com/wallets";
227
+ });
228
+ return;
229
+ case "ERROR_BROWSER_NOT_SUPPORTED":
230
+ errorMessageElement.innerHTML = BROWSER_NOT_SUPPORTED_ERROR_MESSAGE;
231
+ if (actionBtn) actionBtn.style.display = "none";
232
+ return;
233
+ }
234
+ errorMessageElement.innerHTML = `An unexpected error occurred: ${error.message}`;
235
+ } else console.log("Failed to locate error dialog element");
328
236
  }
329
237
  };
330
- const QRCodeHtml = `
331
- <div class="mobile-wallet-adapter-embedded-modal-qr-content">
332
- <div>
333
- <svg class="mobile-wallet-adapter-embedded-modal-icon" width="100%" height="100%">
334
- <circle r="52" cx="53" cy="53" fill="#99b3be" stroke="#000000" stroke-width="2"/>
335
- <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"/>
336
- </svg>
337
- <div class="mobile-wallet-adapter-embedded-modal-title">Remote Mobile Wallet Adapter</div>
338
- </div>
339
- <div>
340
- <div>
341
- <h4 class="mobile-wallet-adapter-embedded-modal-qr-label">
342
- Open your wallet and scan this code
343
- </h4>
344
- </div>
345
- <div id="mobile-wallet-adapter-embedded-modal-qr-code-container" class="mobile-wallet-adapter-embedded-modal-qr-code-container">
346
- <div id="mobile-wallet-adapter-embedded-modal-qr-placeholder" class="mobile-wallet-adapter-embedded-modal-qr-placeholder"></div>
347
- </div>
348
- </div>
349
- </div>
350
- <div class="mobile-wallet-adapter-embedded-modal-divider"><hr></div>
351
- <div class="mobile-wallet-adapter-embedded-modal-footer">
352
- <div class="mobile-wallet-adapter-embedded-modal-subtitle">
353
- Follow the instructions on your device. When you're finished, this screen will update.
354
- </div>
355
- <div class="mobile-wallet-adapter-embedded-modal-progress-badge">
356
- <div>
357
- <div class="spinner">
358
- <div class="leftWrapper">
359
- <div class="left">
360
- <div class="circle"></div>
361
- </div>
362
- </div>
363
- <div class="rightWrapper">
364
- <div class="right">
365
- <div class="circle"></div>
366
- </div>
367
- </div>
368
- </div>
369
- </div>
370
- <div>Waiting for scan</div>
371
- </div>
238
+ const ErrorDialogHtml$3 = `
239
+ <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>
240
+ <div class="mobile-wallet-adapter-embedded-modal-title">We can't find a wallet.</div>
241
+ <div id="mobile-wallet-adapter-error-message" class="mobile-wallet-adapter-embedded-modal-subtitle"></div>
242
+ <div>
243
+ <button data-error-action id="mobile-wallet-adapter-error-action" class="mobile-wallet-adapter-embedded-modal-error-action">
244
+ Find a wallet
245
+ </button>
372
246
  </div>
373
247
  `;
374
- const css$4 = `
375
- .mobile-wallet-adapter-embedded-modal-qr-content {
376
- display: flex;
377
- margin-top: 10px;
378
- padding: 10px;
379
- }
380
-
381
- .mobile-wallet-adapter-embedded-modal-qr-content > div:first-child {
382
- display: flex;
383
- flex-direction: column;
384
- flex: 2;
385
- margin-top: auto;
386
- margin-right: 30px;
387
- }
388
-
389
- .mobile-wallet-adapter-embedded-modal-qr-content > div:nth-child(2) {
390
- display: flex;
391
- flex-direction: column;
392
- flex: 1;
393
- margin-left: auto;
248
+ const css$5 = `
249
+ .mobile-wallet-adapter-embedded-modal-content {
250
+ text-align: center;
394
251
  }
395
252
 
396
- .mobile-wallet-adapter-embedded-modal-footer {
397
- display: flex;
398
- padding: 10px;
253
+ .mobile-wallet-adapter-embedded-modal-error-icon {
254
+ margin-top: 24px;
399
255
  }
400
256
 
401
- .mobile-wallet-adapter-embedded-modal-icon {}
402
-
403
257
  .mobile-wallet-adapter-embedded-modal-title {
258
+ margin: 18px 100px auto 100px;
404
259
  color: #000000;
405
- font-size: 2.5em;
260
+ font-size: 2.75em;
406
261
  font-weight: 600;
407
262
  }
408
263
 
409
- .mobile-wallet-adapter-embedded-modal-qr-label {
410
- text-align: right;
411
- color: #000000;
412
- }
413
-
414
- .mobile-wallet-adapter-embedded-modal-qr-code-container {
415
- margin-left: auto;
416
- }
417
-
418
- .mobile-wallet-adapter-embedded-modal-qr-placeholder {
419
- margin-left: auto;
420
- min-width: 200px;
421
- min-height: 200px;
422
- background: linear-gradient(-60deg, #F7F8F8 30%, #ECEEEE 50%, #F7F8F8 70%);
423
- background-size: 200%;
424
- animation: placeholderAnimate 2.7s linear infinite;
425
- border-radius: 12px;
426
- }
427
-
428
- .mobile-wallet-adapter-embedded-modal-divider {
429
- margin-top: 20px;
430
- padding-left: 10px;
431
- padding-right: 10px;
432
- }
433
-
434
- .mobile-wallet-adapter-embedded-modal-divider hr {
435
- border-top: 1px solid #D9DEDE;
436
- }
437
-
438
264
  .mobile-wallet-adapter-embedded-modal-subtitle {
439
- margin: auto;
440
- margin-right: 60px;
441
- padding: 20px;
442
- color: #6E8286;
265
+ margin: 30px 60px 40px 60px;
266
+ color: #000000;
267
+ font-size: 1.25em;
268
+ font-weight: 400;
443
269
  }
444
270
 
445
- .mobile-wallet-adapter-embedded-modal-progress-badge {
446
- display: flex;
447
- background: #F7F8F8;
271
+ .mobile-wallet-adapter-embedded-modal-error-action {
272
+ display: block;
273
+ width: 100%;
448
274
  height: 56px;
449
- min-width: 200px;
450
- margin: auto;
451
- padding-left: 20px;
452
- padding-right: 20px;
275
+ /*margin-top: 40px;*/
276
+ font-size: 1.25em;
277
+ /*line-height: 24px;*/
278
+ /*letter-spacing: -1%;*/
279
+ background: #000000;
280
+ color: #FFFFFF;
453
281
  border-radius: 18px;
454
- color: #A8B6B8;
455
- align-items: center;
456
- }
457
-
458
- .mobile-wallet-adapter-embedded-modal-progress-badge > div:first-child {
459
- margin-left: auto;
460
- margin-right: 20px;
461
- }
462
-
463
- .mobile-wallet-adapter-embedded-modal-progress-badge > div:nth-child(2) {
464
- margin-right: auto;
465
282
  }
466
283
 
467
284
  /* Smaller screens */
468
285
  @media all and (max-width: 600px) {
469
- .mobile-wallet-adapter-embedded-modal-card {
470
- text-align: center;
471
- }
472
- .mobile-wallet-adapter-embedded-modal-qr-content {
473
- flex-direction: column;
474
- }
475
- .mobile-wallet-adapter-embedded-modal-qr-content > div:first-child {
476
- margin: auto;
477
- }
478
- .mobile-wallet-adapter-embedded-modal-qr-content > div:nth-child(2) {
479
- margin: auto;
480
- flex: 2 auto;
481
- }
482
- .mobile-wallet-adapter-embedded-modal-footer {
483
- flex-direction: column;
484
- }
485
- .mobile-wallet-adapter-embedded-modal-icon {
486
- display: none;
487
- }
488
286
  .mobile-wallet-adapter-embedded-modal-title {
489
287
  font-size: 1.5em;
288
+ margin-right: 12px;
289
+ margin-left: 12px;
490
290
  }
491
291
  .mobile-wallet-adapter-embedded-modal-subtitle {
492
- margin-right: unset;
493
- }
494
- .mobile-wallet-adapter-embedded-modal-qr-label {
495
- text-align: center;
496
- }
497
- .mobile-wallet-adapter-embedded-modal-qr-code-container {
498
- margin: auto;
499
- }
500
- .mobile-wallet-adapter-embedded-modal-qr-placeholder {
501
- margin: auto;
502
- }
503
- }
504
-
505
- /* QR Placeholder */
506
- @keyframes placeholderAnimate {
507
- 0% { background-position: 200% 0; }
508
- 100% { background-position: -200% 0; }
509
- }
510
-
511
- /* Spinner */
512
- @keyframes spinLeft {
513
- 0% {
514
- transform: rotate(20deg);
515
- }
516
- 50% {
517
- transform: rotate(160deg);
518
- }
519
- 100% {
520
- transform: rotate(20deg);
521
- }
522
- }
523
- @keyframes spinRight {
524
- 0% {
525
- transform: rotate(160deg);
526
- }
527
- 50% {
528
- transform: rotate(20deg);
529
- }
530
- 100% {
531
- transform: rotate(160deg);
532
- }
533
- }
534
- @keyframes spin {
535
- 0% {
536
- transform: rotate(0deg);
537
- }
538
- 100% {
539
- transform: rotate(2520deg);
292
+ margin-right: 12px;
293
+ margin-left: 12px;
540
294
  }
541
295
  }
542
-
543
- .spinner {
544
- position: relative;
545
- width: 1.5em;
546
- height: 1.5em;
547
- margin: auto;
548
- animation: spin 10s linear infinite;
549
- }
550
- .spinner::before {
551
- content: "";
552
- position: absolute;
553
- top: 0;
554
- bottom: 0;
555
- left: 0;
556
- right: 0;
296
+ `;
297
+ //#endregion
298
+ //#region src/createDefaultWalletNotFoundHandler.ts
299
+ async function defaultErrorModalWalletNotFoundHandler() {
300
+ if (typeof window !== "undefined") {
301
+ const userAgent = window.navigator.userAgent.toLowerCase();
302
+ const errorDialog = new ErrorModal();
303
+ if (userAgent.includes("wv")) errorDialog.initWithError({
304
+ name: "SolanaMobileWalletAdapterError",
305
+ code: "ERROR_BROWSER_NOT_SUPPORTED",
306
+ message: ""
307
+ });
308
+ else errorDialog.initWithError({
309
+ name: "SolanaMobileWalletAdapterError",
310
+ code: "ERROR_WALLET_NOT_FOUND",
311
+ message: ""
312
+ });
313
+ errorDialog.open();
314
+ }
557
315
  }
558
- .right, .rightWrapper, .left, .leftWrapper {
559
- position: absolute;
560
- top: 0;
561
- overflow: hidden;
562
- width: .75em;
563
- height: 1.5em;
564
- }
565
- .left, .leftWrapper {
566
- left: 0;
567
- }
568
- .right {
569
- left: -12px;
570
- }
571
- .rightWrapper {
572
- right: 0;
573
- }
574
- .circle {
575
- border: .125em solid #A8B6B8;
576
- width: 1.25em; /* 1.5em - 2*0.125em border */
577
- height: 1.25em; /* 1.5em - 2*0.125em border */
578
- border-radius: 0.75em; /* 0.5*1.5em spinner size 8 */
579
- }
580
- .left {
581
- transform-origin: 100% 50%;
582
- animation: spinLeft 2.5s cubic-bezier(.2,0,.8,1) infinite;
583
- }
584
- .right {
585
- transform-origin: 100% 50%;
586
- animation: spinRight 2.5s cubic-bezier(.2,0,.8,1) infinite;
587
- }
588
- `;
589
- //#endregion
590
- //#region src/icon.ts
591
- const icon = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03IDIuNUgxN0MxNy44Mjg0IDIuNSAxOC41IDMuMTcxNTcgMTguNSA0VjIwQzE4LjUgMjAuODI4NCAxNy44Mjg0IDIxLjUgMTcgMjEuNUg3QzYuMTcxNTcgMjEuNSA1LjUgMjAuODI4NCA1LjUgMjBWNEM1LjUgMy4xNzE1NyA2LjE3MTU3IDIuNSA3IDIuNVpNMyA0QzMgMS43OTA4NiA0Ljc5MDg2IDAgNyAwSDE3QzE5LjIwOTEgMCAyMSAxLjc5MDg2IDIxIDRWMjBDMjEgMjIuMjA5MSAxOS4yMDkxIDI0IDE3IDI0SDdDNC43OTA4NiAyNCAzIDIyLjIwOTEgMyAyMFY0Wk0xMSA0LjYxNTM4QzEwLjQ0NzcgNC42MTUzOCAxMCA1LjA2MzEgMTAgNS42MTUzOFY2LjM4NDYyQzEwIDYuOTM2OSAxMC40NDc3IDcuMzg0NjIgMTEgNy4zODQ2MkgxM0MxMy41NTIzIDcuMzg0NjIgMTQgNi45MzY5IDE0IDYuMzg0NjJWNS42MTUzOEMxNCA1LjA2MzEgMTMuNTUyMyA0LjYxNTM4IDEzIDQuNjE1MzhIMTFaIiBmaWxsPSIjRENCOEZGIi8+Cjwvc3ZnPgo=";
592
- //#endregion
593
- //#region src/base64Utils.ts
594
- function fromUint8Array(byteArray) {
595
- return window.btoa(String.fromCharCode.call(null, ...byteArray));
596
- }
597
- function toUint8Array(base64EncodedByteArray) {
598
- return new Uint8Array(window.atob(base64EncodedByteArray).split("").map((c) => c.charCodeAt(0)));
316
+ function createDefaultWalletNotFoundHandler() {
317
+ return async () => {
318
+ defaultErrorModalWalletNotFoundHandler();
319
+ };
599
320
  }
600
321
  //#endregion
601
322
  //#region src/embedded-modal/localConnectionModal.ts
602
323
  var LocalConnectionModal = class extends EmbeddedModal {
603
- contentStyles = css$3;
604
- contentHtml = ErrorDialogHtml$3;
324
+ contentStyles = css$4;
325
+ contentHtml = ErrorDialogHtml$2;
605
326
  initWithCallback(callback) {
606
327
  super.init();
607
328
  this.#prepareLaunchAction(callback);
@@ -616,7 +337,7 @@ var LocalConnectionModal = class extends EmbeddedModal {
616
337
  launchButton?.addEventListener("click", listener);
617
338
  }
618
339
  };
619
- const ErrorDialogHtml$3 = `
340
+ const ErrorDialogHtml$2 = `
620
341
  <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">
621
342
  <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"/>
622
343
  <mask id="mask0_189_522" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="8" y="8" width="32" height="32">
@@ -638,7 +359,7 @@ const ErrorDialogHtml$3 = `
638
359
  </button>
639
360
  </div>
640
361
  `;
641
- const css$3 = `
362
+ const css$4 = `
642
363
  .mobile-wallet-adapter-embedded-modal-close {
643
364
  display: none;
644
365
  }
@@ -676,10 +397,10 @@ const css$3 = `
676
397
  //#endregion
677
398
  //#region src/embedded-modal/loopbackBlockedModal.ts
678
399
  var LoopbackPermissionBlockedModal = class extends EmbeddedModal {
679
- contentStyles = css$2;
400
+ contentStyles = css$3;
680
401
  get contentHtml() {
681
402
  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";
682
- return ErrorDialogHtml$2.replace("{{PERMISSION_INSTRUCTION_DETAIL}}", instructions);
403
+ return ErrorDialogHtml$1.replace("{{PERMISSION_INSTRUCTION_DETAIL}}", instructions);
683
404
  }
684
405
  async init() {
685
406
  super.init();
@@ -694,7 +415,7 @@ var LoopbackPermissionBlockedModal = class extends EmbeddedModal {
694
415
  launchButton?.addEventListener("click", listener);
695
416
  }
696
417
  };
697
- const ErrorDialogHtml$2 = `
418
+ const ErrorDialogHtml$1 = `
698
419
  <div class="mobile-wallet-adapter-embedded-modal-header">
699
420
  Local Wallet Connection
700
421
  </div>
@@ -747,7 +468,7 @@ const ErrorDialogHtml$2 = `
747
468
  </button>
748
469
  </div>
749
470
  `;
750
- const css$2 = `
471
+ const css$3 = `
751
472
  .mobile-wallet-adapter-embedded-modal-close {
752
473
  display: none;
753
474
  }
@@ -837,8 +558,8 @@ const css$2 = `
837
558
  //#endregion
838
559
  //#region src/embedded-modal/loopbackPermissionModal.ts
839
560
  var LoopbackPermissionModal = class extends EmbeddedModal {
840
- contentStyles = css$1;
841
- contentHtml = ErrorDialogHtml$1;
561
+ contentStyles = css$2;
562
+ contentHtml = ErrorDialogHtml;
842
563
  async init() {
843
564
  super.init();
844
565
  this.#prepareLaunchAction();
@@ -849,13 +570,13 @@ var LoopbackPermissionModal = class extends EmbeddedModal {
849
570
  launchButton?.removeEventListener("click", listener);
850
571
  try {
851
572
  await fetch("http://localhost");
852
- } catch (e) {}
573
+ } catch {}
853
574
  this.close();
854
575
  };
855
576
  launchButton?.addEventListener("click", listener);
856
577
  }
857
578
  };
858
- const ErrorDialogHtml$1 = `
579
+ const ErrorDialogHtml = `
859
580
  <div class="mobile-wallet-adapter-embedded-modal-title">Allow connections to your wallet</div>
860
581
  <div id="mobile-wallet-adapter-local-launch-message" class="mobile-wallet-adapter-embedded-modal-subtitle">
861
582
  Tap "Allow" on the next screen
@@ -881,7 +602,7 @@ const ErrorDialogHtml$1 = `
881
602
  </button>
882
603
  </div>
883
604
  `;
884
- const css$1 = `
605
+ const css$2 = `
885
606
  .mobile-wallet-adapter-embedded-modal-close {
886
607
  display: none;
887
608
  }
@@ -927,72 +648,507 @@ const css$1 = `
927
648
  margin-left: 12px;
928
649
  }
929
650
  }
930
- `;
931
- //#endregion
932
- //#region src/getIsSupported.ts
933
- function getIsLocalAssociationSupported() {
934
- return typeof window !== "undefined" && window.isSecureContext && typeof document !== "undefined" && /android/i.test(navigator.userAgent);
651
+ `;
652
+ //#endregion
653
+ //#region src/getIsSupported.ts
654
+ function getIsLocalAssociationSupported() {
655
+ return typeof window !== "undefined" && window.isSecureContext && typeof document !== "undefined" && /android/i.test(navigator.userAgent);
656
+ }
657
+ function getIsRemoteAssociationSupported() {
658
+ return typeof window !== "undefined" && window.isSecureContext && typeof document !== "undefined" && !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
659
+ }
660
+ function isWebView(userAgentString) {
661
+ return /(WebView|Version\/.+(Chrome)\/(\d+)\.(\d+)\.(\d+)\.(\d+)|; wv\).+(Chrome)\/(\d+)\.(\d+)\.(\d+)\.(\d+))/i.test(userAgentString);
662
+ }
663
+ function isSolanaMobileWebShell(userAgentString) {
664
+ return userAgentString.includes("Solana Mobile Web Shell");
665
+ }
666
+ function getIsPwaLaunchedAsApp() {
667
+ const isAndroidTwa = typeof document !== "undefined" && document.referrer.startsWith("android-app://");
668
+ if (typeof window == "undefined") return isAndroidTwa;
669
+ const isStandalone = window.matchMedia("(display-mode: standalone)").matches;
670
+ const isFullscreen = window.matchMedia("(display-mode: fullscreen)").matches;
671
+ const isMinimalUI = window.matchMedia("(display-mode: minimal-ui)").matches;
672
+ return isAndroidTwa || isStandalone || isFullscreen || isMinimalUI;
673
+ }
674
+ async function checkLocalNetworkAccessPermission() {
675
+ if (typeof navigator !== "undefined" && isSolanaMobileWebShell(navigator.userAgent)) return;
676
+ try {
677
+ const lnaPermission = await navigator.permissions.query({ name: "loopback-network" });
678
+ if (lnaPermission.state === "granted") return;
679
+ else if (lnaPermission.state === "denied") {
680
+ const modal = new LoopbackPermissionBlockedModal();
681
+ modal.init();
682
+ modal.open();
683
+ throw new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_LOOPBACK_ACCESS_BLOCKED, "Local Network Access permission denied");
684
+ } else if (lnaPermission.state === "prompt") {
685
+ const modal = new LoopbackPermissionModal();
686
+ if (await new Promise((resolve, reject) => {
687
+ modal.addEventListener("close", (event) => {
688
+ if (event) reject(new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_CANCELLED, "Wallet connection cancelled by user", { event }));
689
+ });
690
+ lnaPermission.onchange = () => {
691
+ lnaPermission.onchange = null;
692
+ resolve(lnaPermission.state);
693
+ };
694
+ modal.init();
695
+ modal.open();
696
+ }) === "granted") {
697
+ const modal = new LocalConnectionModal();
698
+ await new Promise((resolve, reject) => {
699
+ modal.addEventListener("close", (event) => {
700
+ if (event) reject(new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_CANCELLED, "Wallet connection cancelled by user", { event }));
701
+ });
702
+ modal.initWithCallback(async () => {
703
+ resolve(true);
704
+ });
705
+ modal.open();
706
+ });
707
+ return;
708
+ } else return await checkLocalNetworkAccessPermission();
709
+ }
710
+ throw new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_LOOPBACK_ACCESS_BLOCKED, "Local Network Access permission unknown");
711
+ } catch (e) {
712
+ if (e instanceof TypeError && (e.message.includes("loopback-network") || e.message.includes("local-network-access"))) return;
713
+ if (e instanceof SolanaMobileWalletAdapterError) throw e;
714
+ throw new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_LOOPBACK_ACCESS_BLOCKED, e instanceof Error ? e.message : "Local Network Access permission unknown");
715
+ }
716
+ }
717
+ //#endregion
718
+ //#region src/embedded-modal/loadingSpinner.ts
719
+ const modalHtml = `
720
+ <div class="mobile-wallet-adapter-embedded-loading-indicator" role="dialog" aria-modal="true" aria-labelledby="modal-title">
721
+ <div data-modal-close style="position: absolute; width: 100%; height: 100%;"></div>
722
+ <div class="mobile-wallet-adapter-embedded-loading-container">
723
+ <div class="mobile-wallet-adapter-embedded-loading-animation"></div>
724
+ </div>
725
+ </div>
726
+ `;
727
+ const css$1 = `
728
+ .mobile-wallet-adapter-embedded-loading-indicator {
729
+ display: flex; /* Use flexbox to center content */
730
+ justify-content: center; /* Center horizontally */
731
+ align-items: start; /* Center vertically */
732
+ position: fixed; /* Stay in place */
733
+ z-index: 1; /* Sit on top */
734
+ left: 0;
735
+ top: 0;
736
+ width: 100%; /* Full width */
737
+ height: 100%; /* Full height */
738
+ background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
739
+ overflow-y: auto; /* enable scrolling */
740
+ }
741
+
742
+ .mobile-wallet-adapter-embedded-loading-container {
743
+ display: flex;
744
+ margin: auto;
745
+ }
746
+
747
+ .mobile-wallet-adapter-embedded-loading-animation {
748
+ position: relative;
749
+ left: -9999px;
750
+ width: 10px;
751
+ height: 10px;
752
+ border-radius: 5px;
753
+ background-color: var(--spinner-color);
754
+ color: var(--spinner-color);
755
+ box-shadow: 9984px 0 0 0 var(--spinner-color),
756
+ 9999px 0 0 0 var(--spinner-color),
757
+ 10014px 0 0 0 var(--spinner-color);
758
+ animation: dot-typing 1.5s infinite linear;
759
+ }
760
+
761
+ @keyframes dot-typing {
762
+ 0% {
763
+ box-shadow: 9984px 0 0 0 var(--spinner-color),
764
+ 9999px 0 0 0 var(--spinner-color),
765
+ 10014px 0 0 0 var(--spinner-color);
766
+ }
767
+ 16.667% {
768
+ box-shadow: 9984px -10px 0 0 var(--spinner-color),
769
+ 9999px 0 0 0 var(--spinner-color),
770
+ 10014px 0 0 0 var(--spinner-color);
771
+ }
772
+ 33.333% {
773
+ box-shadow: 9984px 0 0 0 var(--spinner-color),
774
+ 9999px 0 0 0 var(--spinner-color),
775
+ 10014px 0 0 0 var(--spinner-color);
776
+ }
777
+ 50% {
778
+ box-shadow: 9984px 0 0 0 var(--spinner-color),
779
+ 9999px -10px 0 0 var(--spinner-color),
780
+ 10014px 0 0 0 var(--spinner-color);
781
+ }
782
+ 66.667% {
783
+ box-shadow: 9984px 0 0 0 var(--spinner-color),
784
+ 9999px 0 0 0 var(--spinner-color),
785
+ 10014px 0 0 0 var(--spinner-color);
786
+ }
787
+ 83.333% {
788
+ box-shadow: 9984px 0 0 0 var(--spinner-color),
789
+ 9999px 0 0 0 var(--spinner-color),
790
+ 10014px -10px 0 0 var(--spinner-color);
791
+ }
792
+ 100% {
793
+ box-shadow: 9984px 0 0 0 var(--spinner-color),
794
+ 9999px 0 0 0 var(--spinner-color),
795
+ 10014px 0 0 0 var(--spinner-color);
796
+ }
797
+ }
798
+ `;
799
+ var EmbeddedLoadingSpinner = class {
800
+ #root = null;
801
+ #eventListeners = {};
802
+ #listenersAttached = false;
803
+ dom = null;
804
+ constructor() {
805
+ this.init = this.init.bind(this);
806
+ this.#root = document.getElementById("mobile-wallet-adapter-embedded-root-ui");
807
+ }
808
+ async init() {
809
+ console.log("Injecting modal");
810
+ this.#injectHTML();
811
+ }
812
+ open = () => {
813
+ console.debug("Modal open");
814
+ this.#attachEventListeners();
815
+ if (this.#root) this.#root.style.display = "flex";
816
+ };
817
+ close = (event = void 0) => {
818
+ console.debug("Modal close");
819
+ this.#removeEventListeners();
820
+ if (this.#root) this.#root.style.display = "none";
821
+ this.#eventListeners["close"]?.forEach((listener) => listener(event));
822
+ };
823
+ addEventListener(event, listener) {
824
+ this.#eventListeners[event]?.push(listener) || (this.#eventListeners[event] = [listener]);
825
+ return () => this.removeEventListener(event, listener);
826
+ }
827
+ removeEventListener(event, listener) {
828
+ this.#eventListeners[event] = this.#eventListeners[event]?.filter((existingListener) => listener !== existingListener);
829
+ }
830
+ #injectHTML() {
831
+ if (this.dom) return;
832
+ this.#root = document.createElement("div");
833
+ this.#root.id = "mobile-wallet-adapter-embedded-root-ui";
834
+ this.#root.innerHTML = modalHtml;
835
+ this.#root.style.display = "none";
836
+ const styles = document.createElement("style");
837
+ styles.id = "mobile-wallet-adapter-embedded-modal-styles";
838
+ styles.textContent = css$1;
839
+ const host = document.createElement("div");
840
+ this.dom = host.attachShadow({ mode: "closed" });
841
+ host.style.setProperty("--spinner-color", "#FFFFFF");
842
+ this.dom.appendChild(styles);
843
+ this.dom.appendChild(this.#root);
844
+ document.body.appendChild(host);
845
+ }
846
+ #attachEventListeners() {
847
+ if (!this.#root || this.#listenersAttached) return;
848
+ [...this.#root.querySelectorAll("[data-modal-close]")].forEach((closer) => closer?.addEventListener("click", (event) => {
849
+ this.close(event);
850
+ }));
851
+ window.addEventListener("load", this.close);
852
+ document.addEventListener("keydown", this.#handleKeyDown);
853
+ this.#listenersAttached = true;
854
+ }
855
+ #removeEventListeners() {
856
+ if (!this.#listenersAttached) return;
857
+ window.removeEventListener("load", this.close);
858
+ document.removeEventListener("keydown", this.#handleKeyDown);
859
+ if (!this.#root) return;
860
+ [...this.#root.querySelectorAll("[data-modal-close]")].forEach((closer) => closer?.removeEventListener("click", this.close));
861
+ this.#listenersAttached = false;
862
+ }
863
+ #handleKeyDown = (event) => {
864
+ if (event.key === "Escape") this.close(event);
865
+ };
866
+ };
867
+ //#endregion
868
+ //#region src/embedded-modal/remoteConnectionModal.ts
869
+ var RemoteConnectionModal = class extends EmbeddedModal {
870
+ contentStyles = css;
871
+ contentHtml = QRCodeHtml;
872
+ async initWithQR(qrCode) {
873
+ super.init();
874
+ this.populateQRCode(qrCode);
875
+ }
876
+ async populateQRCode(qrUrl) {
877
+ const qrcodeContainer = this.dom?.getElementById("mobile-wallet-adapter-embedded-modal-qr-code-container");
878
+ if (qrcodeContainer) {
879
+ const qrCodeElement = await QRCode.toCanvas(qrUrl, {
880
+ width: 200,
881
+ margin: 0
882
+ });
883
+ if (qrcodeContainer.firstElementChild !== null) qrcodeContainer.replaceChild(qrCodeElement, qrcodeContainer.firstElementChild);
884
+ else qrcodeContainer.appendChild(qrCodeElement);
885
+ const qrPlaceholder = this.dom?.getElementById("mobile-wallet-adapter-embedded-modal-qr-placeholder");
886
+ if (qrPlaceholder) qrPlaceholder.style.display = "none";
887
+ } else console.error("QRCode Container not found");
888
+ }
889
+ };
890
+ const QRCodeHtml = `
891
+ <div class="mobile-wallet-adapter-embedded-modal-qr-content">
892
+ <div>
893
+ <svg class="mobile-wallet-adapter-embedded-modal-icon" width="100%" height="100%">
894
+ <circle r="52" cx="53" cy="53" fill="#99b3be" stroke="#000000" stroke-width="2"/>
895
+ <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"/>
896
+ </svg>
897
+ <div class="mobile-wallet-adapter-embedded-modal-title">Remote Mobile Wallet Adapter</div>
898
+ </div>
899
+ <div>
900
+ <div>
901
+ <h4 class="mobile-wallet-adapter-embedded-modal-qr-label">
902
+ Open your wallet and scan this code
903
+ </h4>
904
+ </div>
905
+ <div id="mobile-wallet-adapter-embedded-modal-qr-code-container" class="mobile-wallet-adapter-embedded-modal-qr-code-container">
906
+ <div id="mobile-wallet-adapter-embedded-modal-qr-placeholder" class="mobile-wallet-adapter-embedded-modal-qr-placeholder"></div>
907
+ </div>
908
+ </div>
909
+ </div>
910
+ <div class="mobile-wallet-adapter-embedded-modal-divider"><hr></div>
911
+ <div class="mobile-wallet-adapter-embedded-modal-footer">
912
+ <div class="mobile-wallet-adapter-embedded-modal-subtitle">
913
+ Follow the instructions on your device. When you're finished, this screen will update.
914
+ </div>
915
+ <div class="mobile-wallet-adapter-embedded-modal-progress-badge">
916
+ <div>
917
+ <div class="spinner">
918
+ <div class="leftWrapper">
919
+ <div class="left">
920
+ <div class="circle"></div>
921
+ </div>
922
+ </div>
923
+ <div class="rightWrapper">
924
+ <div class="right">
925
+ <div class="circle"></div>
926
+ </div>
927
+ </div>
928
+ </div>
929
+ </div>
930
+ <div>Waiting for scan</div>
931
+ </div>
932
+ </div>
933
+ `;
934
+ const css = `
935
+ .mobile-wallet-adapter-embedded-modal-qr-content {
936
+ display: flex;
937
+ margin-top: 10px;
938
+ padding: 10px;
939
+ }
940
+
941
+ .mobile-wallet-adapter-embedded-modal-qr-content > div:first-child {
942
+ display: flex;
943
+ flex-direction: column;
944
+ flex: 2;
945
+ margin-top: auto;
946
+ margin-right: 30px;
947
+ }
948
+
949
+ .mobile-wallet-adapter-embedded-modal-qr-content > div:nth-child(2) {
950
+ display: flex;
951
+ flex-direction: column;
952
+ flex: 1;
953
+ margin-left: auto;
954
+ }
955
+
956
+ .mobile-wallet-adapter-embedded-modal-footer {
957
+ display: flex;
958
+ padding: 10px;
959
+ }
960
+
961
+ .mobile-wallet-adapter-embedded-modal-icon {}
962
+
963
+ .mobile-wallet-adapter-embedded-modal-title {
964
+ color: #000000;
965
+ font-size: 2.5em;
966
+ font-weight: 600;
967
+ }
968
+
969
+ .mobile-wallet-adapter-embedded-modal-qr-label {
970
+ text-align: right;
971
+ color: #000000;
972
+ }
973
+
974
+ .mobile-wallet-adapter-embedded-modal-qr-code-container {
975
+ margin-left: auto;
976
+ }
977
+
978
+ .mobile-wallet-adapter-embedded-modal-qr-placeholder {
979
+ margin-left: auto;
980
+ min-width: 200px;
981
+ min-height: 200px;
982
+ background: linear-gradient(-60deg, #F7F8F8 30%, #ECEEEE 50%, #F7F8F8 70%);
983
+ background-size: 200%;
984
+ animation: placeholderAnimate 2.7s linear infinite;
985
+ border-radius: 12px;
986
+ }
987
+
988
+ .mobile-wallet-adapter-embedded-modal-divider {
989
+ margin-top: 20px;
990
+ padding-left: 10px;
991
+ padding-right: 10px;
992
+ }
993
+
994
+ .mobile-wallet-adapter-embedded-modal-divider hr {
995
+ border-top: 1px solid #D9DEDE;
996
+ }
997
+
998
+ .mobile-wallet-adapter-embedded-modal-subtitle {
999
+ margin: auto;
1000
+ margin-right: 60px;
1001
+ padding: 20px;
1002
+ color: #6E8286;
1003
+ }
1004
+
1005
+ .mobile-wallet-adapter-embedded-modal-progress-badge {
1006
+ display: flex;
1007
+ background: #F7F8F8;
1008
+ height: 56px;
1009
+ min-width: 200px;
1010
+ margin: auto;
1011
+ padding-left: 20px;
1012
+ padding-right: 20px;
1013
+ border-radius: 18px;
1014
+ color: #A8B6B8;
1015
+ align-items: center;
1016
+ }
1017
+
1018
+ .mobile-wallet-adapter-embedded-modal-progress-badge > div:first-child {
1019
+ margin-left: auto;
1020
+ margin-right: 20px;
1021
+ }
1022
+
1023
+ .mobile-wallet-adapter-embedded-modal-progress-badge > div:nth-child(2) {
1024
+ margin-right: auto;
1025
+ }
1026
+
1027
+ /* Smaller screens */
1028
+ @media all and (max-width: 600px) {
1029
+ .mobile-wallet-adapter-embedded-modal-card {
1030
+ text-align: center;
1031
+ }
1032
+ .mobile-wallet-adapter-embedded-modal-qr-content {
1033
+ flex-direction: column;
1034
+ }
1035
+ .mobile-wallet-adapter-embedded-modal-qr-content > div:first-child {
1036
+ margin: auto;
1037
+ }
1038
+ .mobile-wallet-adapter-embedded-modal-qr-content > div:nth-child(2) {
1039
+ margin: auto;
1040
+ flex: 2 auto;
1041
+ }
1042
+ .mobile-wallet-adapter-embedded-modal-footer {
1043
+ flex-direction: column;
1044
+ }
1045
+ .mobile-wallet-adapter-embedded-modal-icon {
1046
+ display: none;
1047
+ }
1048
+ .mobile-wallet-adapter-embedded-modal-title {
1049
+ font-size: 1.5em;
1050
+ }
1051
+ .mobile-wallet-adapter-embedded-modal-subtitle {
1052
+ margin-right: unset;
1053
+ }
1054
+ .mobile-wallet-adapter-embedded-modal-qr-label {
1055
+ text-align: center;
1056
+ }
1057
+ .mobile-wallet-adapter-embedded-modal-qr-code-container {
1058
+ margin: auto;
1059
+ }
1060
+ .mobile-wallet-adapter-embedded-modal-qr-placeholder {
1061
+ margin: auto;
1062
+ }
1063
+ }
1064
+
1065
+ /* QR Placeholder */
1066
+ @keyframes placeholderAnimate {
1067
+ 0% { background-position: 200% 0; }
1068
+ 100% { background-position: -200% 0; }
1069
+ }
1070
+
1071
+ /* Spinner */
1072
+ @keyframes spinLeft {
1073
+ 0% {
1074
+ transform: rotate(20deg);
1075
+ }
1076
+ 50% {
1077
+ transform: rotate(160deg);
1078
+ }
1079
+ 100% {
1080
+ transform: rotate(20deg);
1081
+ }
1082
+ }
1083
+ @keyframes spinRight {
1084
+ 0% {
1085
+ transform: rotate(160deg);
1086
+ }
1087
+ 50% {
1088
+ transform: rotate(20deg);
1089
+ }
1090
+ 100% {
1091
+ transform: rotate(160deg);
1092
+ }
1093
+ }
1094
+ @keyframes spin {
1095
+ 0% {
1096
+ transform: rotate(0deg);
1097
+ }
1098
+ 100% {
1099
+ transform: rotate(2520deg);
1100
+ }
1101
+ }
1102
+
1103
+ .spinner {
1104
+ position: relative;
1105
+ width: 1.5em;
1106
+ height: 1.5em;
1107
+ margin: auto;
1108
+ animation: spin 10s linear infinite;
1109
+ }
1110
+ .spinner::before {
1111
+ content: "";
1112
+ position: absolute;
1113
+ top: 0;
1114
+ bottom: 0;
1115
+ left: 0;
1116
+ right: 0;
1117
+ }
1118
+ .right, .rightWrapper, .left, .leftWrapper {
1119
+ position: absolute;
1120
+ top: 0;
1121
+ overflow: hidden;
1122
+ width: .75em;
1123
+ height: 1.5em;
935
1124
  }
936
- function getIsRemoteAssociationSupported() {
937
- return typeof window !== "undefined" && window.isSecureContext && typeof document !== "undefined" && !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
1125
+ .left, .leftWrapper {
1126
+ left: 0;
938
1127
  }
939
- function isWebView(userAgentString) {
940
- return /(WebView|Version\/.+(Chrome)\/(\d+)\.(\d+)\.(\d+)\.(\d+)|; wv\).+(Chrome)\/(\d+)\.(\d+)\.(\d+)\.(\d+))/i.test(userAgentString);
1128
+ .right {
1129
+ left: -12px;
941
1130
  }
942
- function isSolanaMobileWebShell(userAgentString) {
943
- return userAgentString.includes("Solana Mobile Web Shell");
1131
+ .rightWrapper {
1132
+ right: 0;
944
1133
  }
945
- function getIsPwaLaunchedAsApp() {
946
- const isAndroidTwa = typeof document !== "undefined" && document.referrer.startsWith("android-app://");
947
- if (typeof window == "undefined") return isAndroidTwa;
948
- const isStandalone = window.matchMedia("(display-mode: standalone)").matches;
949
- const isFullscreen = window.matchMedia("(display-mode: fullscreen)").matches;
950
- const isMinimalUI = window.matchMedia("(display-mode: minimal-ui)").matches;
951
- return isAndroidTwa || isStandalone || isFullscreen || isMinimalUI;
1134
+ .circle {
1135
+ border: .125em solid #A8B6B8;
1136
+ width: 1.25em; /* 1.5em - 2*0.125em border */
1137
+ height: 1.25em; /* 1.5em - 2*0.125em border */
1138
+ border-radius: 0.75em; /* 0.5*1.5em spinner size 8 */
952
1139
  }
953
- async function checkLocalNetworkAccessPermission() {
954
- if (typeof navigator !== "undefined" && isSolanaMobileWebShell(navigator.userAgent)) return;
955
- try {
956
- let lnaPermission = await navigator.permissions.query({ name: "loopback-network" });
957
- if (lnaPermission.state === "granted") return;
958
- else if (lnaPermission.state === "denied") {
959
- const modal = new LoopbackPermissionBlockedModal();
960
- modal.init();
961
- modal.open();
962
- throw new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_LOOPBACK_ACCESS_BLOCKED, "Local Network Access permission denied");
963
- } else if (lnaPermission.state === "prompt") {
964
- const modal = new LoopbackPermissionModal();
965
- if (await new Promise((resolve, reject) => {
966
- modal.addEventListener("close", (event) => {
967
- if (event) reject(new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_CANCELLED, "Wallet connection cancelled by user", { event }));
968
- });
969
- lnaPermission.onchange = () => {
970
- lnaPermission.onchange = null;
971
- resolve(lnaPermission.state);
972
- };
973
- modal.init();
974
- modal.open();
975
- }) === "granted") {
976
- const modal = new LocalConnectionModal();
977
- await new Promise((resolve, reject) => {
978
- modal.addEventListener("close", (event) => {
979
- if (event) reject(new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_CANCELLED, "Wallet connection cancelled by user", { event }));
980
- });
981
- modal.initWithCallback(async () => {
982
- resolve(true);
983
- });
984
- modal.open();
985
- });
986
- return;
987
- } else return await checkLocalNetworkAccessPermission();
988
- }
989
- throw new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_LOOPBACK_ACCESS_BLOCKED, "Local Network Access permission unknown");
990
- } catch (e) {
991
- if (e instanceof TypeError && (e.message.includes("loopback-network") || e.message.includes("local-network-access"))) return;
992
- if (e instanceof SolanaMobileWalletAdapterError) throw e;
993
- throw new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_LOOPBACK_ACCESS_BLOCKED, e instanceof Error ? e.message : "Local Network Access permission unknown");
994
- }
1140
+ .left {
1141
+ transform-origin: 100% 50%;
1142
+ animation: spinLeft 2.5s cubic-bezier(.2,0,.8,1) infinite;
1143
+ }
1144
+ .right {
1145
+ transform-origin: 100% 50%;
1146
+ animation: spinRight 2.5s cubic-bezier(.2,0,.8,1) infinite;
995
1147
  }
1148
+ `;
1149
+ //#endregion
1150
+ //#region src/icon.ts
1151
+ const icon = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03IDIuNUgxN0MxNy44Mjg0IDIuNSAxOC41IDMuMTcxNTcgMTguNSA0VjIwQzE4LjUgMjAuODI4NCAxNy44Mjg0IDIxLjUgMTcgMjEuNUg3QzYuMTcxNTcgMjEuNSA1LjUgMjAuODI4NCA1LjUgMjBWNEM1LjUgMy4xNzE1NyA2LjE3MTU3IDIuNSA3IDIuNVpNMyA0QzMgMS43OTA4NiA0Ljc5MDg2IDAgNyAwSDE3QzE5LjIwOTEgMCAyMSAxLjc5MDg2IDIxIDRWMjBDMjEgMjIuMjA5MSAxOS4yMDkxIDI0IDE3IDI0SDdDNC43OTA4NiAyNCAzIDIyLjIwOTEgMyAyMFY0Wk0xMSA0LjYxNTM4QzEwLjQ0NzcgNC42MTUzOCAxMCA1LjA2MzEgMTAgNS42MTUzOFY2LjM4NDYyQzEwIDYuOTM2OSAxMC40NDc3IDcuMzg0NjIgMTEgNy4zODQ2MkgxM0MxMy41NTIzIDcuMzg0NjIgMTQgNi45MzY5IDE0IDYuMzg0NjJWNS42MTUzOEMxNCA1LjA2MzEgMTMuNTUyMyA0LjYxNTM4IDEzIDQuNjE1MzhIMTFaIiBmaWxsPSIjRENCOEZGIi8+Cjwvc3ZnPgo=";
996
1152
  //#endregion
997
1153
  //#region src/wallet.ts
998
1154
  const SolanaMobileWalletAdapterWalletName = "Mobile Wallet Adapter";
@@ -1005,6 +1161,9 @@ const DEFAULT_FEATURES = [
1005
1161
  SolanaSignIn
1006
1162
  ];
1007
1163
  const WALLET_ASSOCIATION_TIMEOUT = 3e4;
1164
+ function getErrorMessage(error) {
1165
+ return error instanceof Error ? error.message : "Unknown error";
1166
+ }
1008
1167
  var LocalSolanaMobileWalletAdapterWallet = class {
1009
1168
  #listeners = {};
1010
1169
  #version = "1.0.0";
@@ -1121,7 +1280,7 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1121
1280
  } else return { accounts: this.accounts };
1122
1281
  } else await this.#performAuthorization();
1123
1282
  } catch (e) {
1124
- throw new Error(e instanceof Error && e.message || "Unknown error");
1283
+ throw new Error(getErrorMessage(e), { cause: e });
1125
1284
  } finally {
1126
1285
  this.#connecting = false;
1127
1286
  }
@@ -1156,7 +1315,7 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1156
1315
  return authorization;
1157
1316
  });
1158
1317
  } catch (e) {
1159
- throw new Error(e instanceof Error && e.message || "Unknown error");
1318
+ throw new Error(getErrorMessage(e), { cause: e });
1160
1319
  }
1161
1320
  };
1162
1321
  #handleAuthorizationResult = async (authorization) => {
@@ -1199,7 +1358,7 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1199
1358
  Promise.all([this.#authorizationCache.set(authorization), this.#handleAuthorizationResult(authorization)]);
1200
1359
  } catch (e) {
1201
1360
  this.#disconnect();
1202
- throw new Error(e instanceof Error && e.message || "Unknown error");
1361
+ throw new Error(getErrorMessage(e), { cause: e });
1203
1362
  }
1204
1363
  };
1205
1364
  #disconnect = async () => {
@@ -1215,10 +1374,12 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1215
1374
  const currentConnectionGeneration = this.#connectionGeneration;
1216
1375
  const loadingSpinner = new EmbeddedLoadingSpinner();
1217
1376
  try {
1377
+ let associating = true;
1218
1378
  let timeout = void 0;
1219
1379
  const result = await Promise.race([checkLocalNetworkAccessPermission().then(async () => {
1220
1380
  loadingSpinner.init();
1221
1381
  const { wallet, close } = await startScenario(config);
1382
+ associating = false;
1222
1383
  loadingSpinner.addEventListener("close", (event) => {
1223
1384
  if (event) close();
1224
1385
  });
@@ -1229,7 +1390,7 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1229
1390
  return result;
1230
1391
  }), new Promise((_, reject) => {
1231
1392
  timeout = setTimeout(() => {
1232
- reject(new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_CANCELLED, "Wallet connection timed out", { event: void 0 }));
1393
+ if (associating) reject(new SolanaMobileWalletAdapterError(SolanaMobileWalletAdapterErrorCode.ERROR_ASSOCIATION_CANCELLED, "Wallet connection timed out", { event: void 0 }));
1233
1394
  }, WALLET_ASSOCIATION_TIMEOUT);
1234
1395
  })]);
1235
1396
  clearTimeout(timeout);
@@ -1250,9 +1411,9 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1250
1411
  };
1251
1412
  #accountsToWalletStandardAccounts = (accounts) => {
1252
1413
  return accounts.map((account) => {
1253
- const publicKey = toUint8Array(account.address);
1414
+ const publicKey = base64ToUint8Array(account.address);
1254
1415
  return {
1255
- address: base58.encode(publicKey),
1416
+ address: base58FromUint8Array(publicKey),
1256
1417
  publicKey,
1257
1418
  label: account.label,
1258
1419
  icon: account.icon,
@@ -1265,31 +1426,31 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1265
1426
  const { authToken, chain } = this.#assertIsAuthorized();
1266
1427
  try {
1267
1428
  const base64Transactions = transactions.map((tx) => {
1268
- return fromUint8Array(tx);
1429
+ return base64FromUint8Array(tx);
1269
1430
  });
1270
1431
  return await this.#transact(async (wallet) => {
1271
1432
  await this.#performReauthorization(wallet, authToken, chain);
1272
- return (await wallet.signTransactions({ payloads: base64Transactions })).signed_payloads.map(toUint8Array);
1433
+ return (await wallet.signTransactions({ payloads: base64Transactions })).signed_payloads.map(base64ToUint8Array);
1273
1434
  });
1274
1435
  } catch (e) {
1275
- throw new Error(e instanceof Error && e.message || "Unknown error");
1436
+ throw new Error(getErrorMessage(e), { cause: e });
1276
1437
  }
1277
1438
  };
1278
1439
  #performSignAndSendTransaction = async (transaction, options) => {
1279
1440
  const { authToken, chain } = this.#assertIsAuthorized();
1280
1441
  try {
1281
1442
  return await this.#transact(async (wallet) => {
1282
- const [capabilities, _1] = await Promise.all([wallet.getCapabilities(), this.#performReauthorization(wallet, authToken, chain)]);
1443
+ const [capabilities] = await Promise.all([wallet.getCapabilities(), this.#performReauthorization(wallet, authToken, chain)]);
1283
1444
  if (capabilities.supports_sign_and_send_transactions) {
1284
- const base64Transaction = fromUint8Array(transaction);
1445
+ const base64Transaction = base64FromUint8Array(transaction);
1285
1446
  return (await wallet.signAndSendTransactions({
1286
1447
  ...options,
1287
1448
  payloads: [base64Transaction]
1288
- })).signatures.map(toUint8Array)[0];
1449
+ })).signatures.map(base64ToUint8Array)[0];
1289
1450
  } else throw new Error("connected wallet does not support signAndSendTransaction");
1290
1451
  });
1291
1452
  } catch (e) {
1292
- throw new Error(e instanceof Error && e.message || "Unknown error");
1453
+ throw new Error(getErrorMessage(e), { cause: e });
1293
1454
  }
1294
1455
  };
1295
1456
  #signAndSendTransaction = async (...inputs) => {
@@ -1307,15 +1468,15 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1307
1468
  };
1308
1469
  #signMessage = async (...inputs) => {
1309
1470
  const { authToken, chain } = this.#assertIsAuthorized();
1310
- const addresses = inputs.map(({ account }) => fromUint8Array(new Uint8Array(account.publicKey)));
1311
- const messages = inputs.map(({ message }) => fromUint8Array(message));
1471
+ const addresses = inputs.map(({ account }) => base64FromUint8Array(new Uint8Array(account.publicKey)));
1472
+ const messages = inputs.map(({ message }) => base64FromUint8Array(message));
1312
1473
  try {
1313
1474
  return await this.#transact(async (wallet) => {
1314
1475
  await this.#performReauthorization(wallet, authToken, chain);
1315
1476
  return (await wallet.signMessages({
1316
1477
  addresses,
1317
1478
  payloads: messages
1318
- })).signed_payloads.map(toUint8Array).map((signedMessage) => {
1479
+ })).signed_payloads.map(base64ToUint8Array).map((signedMessage) => {
1319
1480
  return {
1320
1481
  signedMessage,
1321
1482
  signature: signedMessage.slice(-SIGNATURE_LENGTH_IN_BYTES)
@@ -1323,7 +1484,7 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1323
1484
  });
1324
1485
  });
1325
1486
  } catch (e) {
1326
- throw new Error(e instanceof Error && e.message || "Unknown error");
1487
+ throw new Error(getErrorMessage(e), { cause: e });
1327
1488
  }
1328
1489
  };
1329
1490
  #signIn = async (...inputs) => {
@@ -1344,16 +1505,16 @@ var LocalSolanaMobileWalletAdapterWallet = class {
1344
1505
  const signedInAccount = authorizationResult.accounts.find((acc) => acc.address == signedInAddress);
1345
1506
  return {
1346
1507
  account: {
1347
- ...signedInAccount ?? { address: base58.encode(toUint8Array(signedInAddress)) },
1348
- publicKey: toUint8Array(signedInAddress),
1508
+ ...signedInAccount ?? { address: base58FromUint8Array(base64ToUint8Array(signedInAddress)) },
1509
+ publicKey: base64ToUint8Array(signedInAddress),
1349
1510
  chains: signedInAccount?.chains ?? this.#chains,
1350
1511
  features: signedInAccount?.features ?? authorizationResult.capabilities.features
1351
1512
  },
1352
- signedMessage: toUint8Array(authorizationResult.sign_in_result.signed_message),
1353
- signature: toUint8Array(authorizationResult.sign_in_result.signature)
1513
+ signedMessage: base64ToUint8Array(authorizationResult.sign_in_result.signed_message),
1514
+ signature: base64ToUint8Array(authorizationResult.sign_in_result.signature)
1354
1515
  };
1355
1516
  } catch (e) {
1356
- throw new Error(e instanceof Error && e.message || "Unknown error");
1517
+ throw new Error(getErrorMessage(e), { cause: e });
1357
1518
  } finally {
1358
1519
  this.#connecting = false;
1359
1520
  }
@@ -1466,13 +1627,13 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1466
1627
  #off(event, listener) {
1467
1628
  this.#listeners[event] = this.#listeners[event]?.filter((existingListener) => listener !== existingListener);
1468
1629
  }
1469
- #connect = async ({ silent } = {}) => {
1630
+ #connect = async (_input = {}) => {
1470
1631
  if (this.#connecting || this.connected) return { accounts: this.accounts };
1471
1632
  this.#connecting = true;
1472
1633
  try {
1473
1634
  await this.#performAuthorization();
1474
1635
  } catch (e) {
1475
- throw new Error(e instanceof Error && e.message || "Unknown error");
1636
+ throw new Error(getErrorMessage(e), { cause: e });
1476
1637
  } finally {
1477
1638
  this.#connecting = false;
1478
1639
  }
@@ -1508,7 +1669,7 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1508
1669
  return authorizationResult;
1509
1670
  });
1510
1671
  } catch (e) {
1511
- throw new Error(e instanceof Error && e.message || "Unknown error");
1672
+ throw new Error(getErrorMessage(e), { cause: e });
1512
1673
  }
1513
1674
  };
1514
1675
  #handleAuthorizationResult = async (authorization) => {
@@ -1551,7 +1712,7 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1551
1712
  Promise.all([this.#authorizationCache.set(authorization), this.#handleAuthorizationResult(authorization)]);
1552
1713
  } catch (e) {
1553
1714
  this.#disconnect();
1554
- throw new Error(e instanceof Error && e.message || "Unknown error");
1715
+ throw new Error(getErrorMessage(e), { cause: e });
1555
1716
  }
1556
1717
  };
1557
1718
  #disconnect = async () => {
@@ -1603,9 +1764,9 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1603
1764
  };
1604
1765
  #accountsToWalletStandardAccounts = (accounts) => {
1605
1766
  return accounts.map((account) => {
1606
- const publicKey = toUint8Array(account.address);
1767
+ const publicKey = base64ToUint8Array(account.address);
1607
1768
  return {
1608
- address: base58.encode(publicKey),
1769
+ address: base58FromUint8Array(publicKey),
1609
1770
  publicKey,
1610
1771
  label: account.label,
1611
1772
  icon: account.icon,
@@ -1619,25 +1780,25 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1619
1780
  try {
1620
1781
  return await this.#transact(async (wallet) => {
1621
1782
  await this.#performReauthorization(wallet, authToken, chain);
1622
- return (await wallet.signTransactions({ payloads: transactions.map(fromUint8Array) })).signed_payloads.map(toUint8Array);
1783
+ return (await wallet.signTransactions({ payloads: transactions.map(base64FromUint8Array) })).signed_payloads.map(base64ToUint8Array);
1623
1784
  });
1624
1785
  } catch (e) {
1625
- throw new Error(e instanceof Error && e.message || "Unknown error");
1786
+ throw new Error(getErrorMessage(e), { cause: e });
1626
1787
  }
1627
1788
  };
1628
1789
  #performSignAndSendTransaction = async (transaction, options) => {
1629
1790
  const { authToken, chain } = this.#assertIsAuthorized();
1630
1791
  try {
1631
1792
  return await this.#transact(async (wallet) => {
1632
- const [capabilities, _1] = await Promise.all([wallet.getCapabilities(), this.#performReauthorization(wallet, authToken, chain)]);
1793
+ const [capabilities] = await Promise.all([wallet.getCapabilities(), this.#performReauthorization(wallet, authToken, chain)]);
1633
1794
  if (capabilities.supports_sign_and_send_transactions) return (await wallet.signAndSendTransactions({
1634
1795
  ...options,
1635
- payloads: [fromUint8Array(transaction)]
1636
- })).signatures.map(toUint8Array)[0];
1796
+ payloads: [base64FromUint8Array(transaction)]
1797
+ })).signatures.map(base64ToUint8Array)[0];
1637
1798
  else throw new Error("connected wallet does not support signAndSendTransaction");
1638
1799
  });
1639
1800
  } catch (e) {
1640
- throw new Error(e instanceof Error && e.message || "Unknown error");
1801
+ throw new Error(getErrorMessage(e), { cause: e });
1641
1802
  }
1642
1803
  };
1643
1804
  #signAndSendTransaction = async (...inputs) => {
@@ -1655,15 +1816,15 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1655
1816
  };
1656
1817
  #signMessage = async (...inputs) => {
1657
1818
  const { authToken, chain } = this.#assertIsAuthorized();
1658
- const addresses = inputs.map(({ account }) => fromUint8Array(new Uint8Array(account.publicKey)));
1659
- const messages = inputs.map(({ message }) => fromUint8Array(message));
1819
+ const addresses = inputs.map(({ account }) => base64FromUint8Array(new Uint8Array(account.publicKey)));
1820
+ const messages = inputs.map(({ message }) => base64FromUint8Array(message));
1660
1821
  try {
1661
1822
  return await this.#transact(async (wallet) => {
1662
1823
  await this.#performReauthorization(wallet, authToken, chain);
1663
1824
  return (await wallet.signMessages({
1664
1825
  addresses,
1665
1826
  payloads: messages
1666
- })).signed_payloads.map(toUint8Array).map((signedMessage) => {
1827
+ })).signed_payloads.map(base64ToUint8Array).map((signedMessage) => {
1667
1828
  return {
1668
1829
  signedMessage,
1669
1830
  signature: signedMessage.slice(-SIGNATURE_LENGTH_IN_BYTES)
@@ -1671,7 +1832,7 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1671
1832
  });
1672
1833
  });
1673
1834
  } catch (e) {
1674
- throw new Error(e instanceof Error && e.message || "Unknown error");
1835
+ throw new Error(getErrorMessage(e), { cause: e });
1675
1836
  }
1676
1837
  };
1677
1838
  #signIn = async (...inputs) => {
@@ -1692,16 +1853,16 @@ var RemoteSolanaMobileWalletAdapterWallet = class {
1692
1853
  const signedInAccount = authorizationResult.accounts.find((acc) => acc.address == signedInAddress);
1693
1854
  return {
1694
1855
  account: {
1695
- ...signedInAccount ?? { address: base58.encode(toUint8Array(signedInAddress)) },
1696
- publicKey: toUint8Array(signedInAddress),
1856
+ ...signedInAccount ?? { address: base58FromUint8Array(base64ToUint8Array(signedInAddress)) },
1857
+ publicKey: base64ToUint8Array(signedInAddress),
1697
1858
  chains: signedInAccount?.chains ?? this.#chains,
1698
1859
  features: signedInAccount?.features ?? authorizationResult.capabilities.features
1699
1860
  },
1700
- signedMessage: toUint8Array(authorizationResult.sign_in_result.signed_message),
1701
- signature: toUint8Array(authorizationResult.sign_in_result.signature)
1861
+ signedMessage: base64ToUint8Array(authorizationResult.sign_in_result.signed_message),
1862
+ signature: base64ToUint8Array(authorizationResult.sign_in_result.signature)
1702
1863
  };
1703
1864
  } catch (e) {
1704
- throw new Error(e instanceof Error && e.message || "Unknown error");
1865
+ throw new Error(getErrorMessage(e), { cause: e });
1705
1866
  } finally {
1706
1867
  this.#connecting = false;
1707
1868
  }
@@ -1726,170 +1887,6 @@ function registerMwa(config) {
1726
1887
  }));
1727
1888
  }
1728
1889
  //#endregion
1729
- //#region src/embedded-modal/errorModal.ts
1730
- const WALLET_NOT_FOUND_ERROR_MESSAGE = "To use mobile wallet adapter, you must have a compatible mobile wallet application installed on your device.";
1731
- 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.";
1732
- var ErrorModal = class extends EmbeddedModal {
1733
- contentStyles = css;
1734
- contentHtml = ErrorDialogHtml;
1735
- initWithError(error) {
1736
- super.init();
1737
- this.populateError(error);
1738
- }
1739
- populateError(error) {
1740
- const errorMessageElement = this.dom?.getElementById("mobile-wallet-adapter-error-message");
1741
- const actionBtn = this.dom?.getElementById("mobile-wallet-adapter-error-action");
1742
- if (errorMessageElement) {
1743
- if (error.name === "SolanaMobileWalletAdapterError") switch (error.code) {
1744
- case "ERROR_WALLET_NOT_FOUND":
1745
- errorMessageElement.innerHTML = WALLET_NOT_FOUND_ERROR_MESSAGE;
1746
- if (actionBtn) actionBtn.addEventListener("click", () => {
1747
- window.location.href = "https://solanamobile.com/wallets";
1748
- });
1749
- return;
1750
- case "ERROR_BROWSER_NOT_SUPPORTED":
1751
- errorMessageElement.innerHTML = BROWSER_NOT_SUPPORTED_ERROR_MESSAGE;
1752
- if (actionBtn) actionBtn.style.display = "none";
1753
- return;
1754
- }
1755
- errorMessageElement.innerHTML = `An unexpected error occurred: ${error.message}`;
1756
- } else console.log("Failed to locate error dialog element");
1757
- }
1758
- };
1759
- const ErrorDialogHtml = `
1760
- <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>
1761
- <div class="mobile-wallet-adapter-embedded-modal-title">We can't find a wallet.</div>
1762
- <div id="mobile-wallet-adapter-error-message" class="mobile-wallet-adapter-embedded-modal-subtitle"></div>
1763
- <div>
1764
- <button data-error-action id="mobile-wallet-adapter-error-action" class="mobile-wallet-adapter-embedded-modal-error-action">
1765
- Find a wallet
1766
- </button>
1767
- </div>
1768
- `;
1769
- const css = `
1770
- .mobile-wallet-adapter-embedded-modal-content {
1771
- text-align: center;
1772
- }
1773
-
1774
- .mobile-wallet-adapter-embedded-modal-error-icon {
1775
- margin-top: 24px;
1776
- }
1777
-
1778
- .mobile-wallet-adapter-embedded-modal-title {
1779
- margin: 18px 100px auto 100px;
1780
- color: #000000;
1781
- font-size: 2.75em;
1782
- font-weight: 600;
1783
- }
1784
-
1785
- .mobile-wallet-adapter-embedded-modal-subtitle {
1786
- margin: 30px 60px 40px 60px;
1787
- color: #000000;
1788
- font-size: 1.25em;
1789
- font-weight: 400;
1790
- }
1791
-
1792
- .mobile-wallet-adapter-embedded-modal-error-action {
1793
- display: block;
1794
- width: 100%;
1795
- height: 56px;
1796
- /*margin-top: 40px;*/
1797
- font-size: 1.25em;
1798
- /*line-height: 24px;*/
1799
- /*letter-spacing: -1%;*/
1800
- background: #000000;
1801
- color: #FFFFFF;
1802
- border-radius: 18px;
1803
- }
1804
-
1805
- /* Smaller screens */
1806
- @media all and (max-width: 600px) {
1807
- .mobile-wallet-adapter-embedded-modal-title {
1808
- font-size: 1.5em;
1809
- margin-right: 12px;
1810
- margin-left: 12px;
1811
- }
1812
- .mobile-wallet-adapter-embedded-modal-subtitle {
1813
- margin-right: 12px;
1814
- margin-left: 12px;
1815
- }
1816
- }
1817
- `;
1818
- //#endregion
1819
- //#region src/createDefaultWalletNotFoundHandler.ts
1820
- async function defaultErrorModalWalletNotFoundHandler() {
1821
- if (typeof window !== "undefined") {
1822
- const userAgent = window.navigator.userAgent.toLowerCase();
1823
- const errorDialog = new ErrorModal();
1824
- if (userAgent.includes("wv")) errorDialog.initWithError({
1825
- name: "SolanaMobileWalletAdapterError",
1826
- code: "ERROR_BROWSER_NOT_SUPPORTED",
1827
- message: ""
1828
- });
1829
- else errorDialog.initWithError({
1830
- name: "SolanaMobileWalletAdapterError",
1831
- code: "ERROR_WALLET_NOT_FOUND",
1832
- message: ""
1833
- });
1834
- errorDialog.open();
1835
- }
1836
- }
1837
- function createDefaultWalletNotFoundHandler() {
1838
- return async () => {
1839
- defaultErrorModalWalletNotFoundHandler();
1840
- };
1841
- }
1842
- //#endregion
1843
- //#region src/createDefaultAuthorizationCache.ts
1844
- const CACHE_KEY = "SolanaMobileWalletAdapterDefaultAuthorizationCache";
1845
- function createDefaultAuthorizationCache() {
1846
- let storage;
1847
- try {
1848
- storage = window.localStorage;
1849
- } catch {}
1850
- return {
1851
- async clear() {
1852
- if (!storage) return;
1853
- try {
1854
- storage.removeItem(CACHE_KEY);
1855
- } catch {}
1856
- },
1857
- async get() {
1858
- if (!storage) return;
1859
- try {
1860
- const parsed = JSON.parse(storage.getItem(CACHE_KEY));
1861
- if (parsed && parsed.accounts) {
1862
- const parsedAccounts = parsed.accounts.map((account) => {
1863
- return {
1864
- ...account,
1865
- publicKey: "publicKey" in account ? new Uint8Array(Object.values(account.publicKey)) : base58.decode(account.address)
1866
- };
1867
- });
1868
- return {
1869
- ...parsed,
1870
- accounts: parsedAccounts
1871
- };
1872
- } else return parsed || void 0;
1873
- } catch {}
1874
- },
1875
- async set(authorization) {
1876
- if (!storage) return;
1877
- try {
1878
- storage.setItem(CACHE_KEY, JSON.stringify(authorization));
1879
- } catch {}
1880
- }
1881
- };
1882
- }
1883
- //#endregion
1884
- //#region src/createDefaultChainSelector.ts
1885
- function createDefaultChainSelector() {
1886
- return { async select(chains) {
1887
- if (chains.length === 1) return chains[0];
1888
- else if (chains.includes(SOLANA_MAINNET_CHAIN)) return SOLANA_MAINNET_CHAIN;
1889
- else return chains[0];
1890
- } };
1891
- }
1892
- //#endregion
1893
1890
  export { LocalSolanaMobileWalletAdapterWallet, RemoteSolanaMobileWalletAdapterWallet, SolanaMobileWalletAdapterRemoteWalletName, SolanaMobileWalletAdapterWalletName, createDefaultAuthorizationCache, createDefaultChainSelector, createDefaultWalletNotFoundHandler, defaultErrorModalWalletNotFoundHandler, registerMwa };
1894
1891
 
1895
1892
  //# sourceMappingURL=index.js.map