@fernolab/wallet-adapter-svelte 0.1.0

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.
@@ -0,0 +1,672 @@
1
+ import { getWallets } from '@wallet-standard/app';
2
+ import { PUBLIC_SOLANA_RPC_ENDPOINT } from '../config.js';
3
+ import { browser } from '../environment.js';
4
+ import { MOBILE_DEEPLINK_WALLETS, MOBILE_WALLETS, SolanaSignMessage, StandardConnect, StandardDisconnect, StandardEvents, adaptStandardWallets, adaptWallet, createWalletController, createMobileWalletBrowseUrl, dedupeStandardWallets, detectInjectedWallets, detectMobileRuntime, isSolanaWallet, resolveSolanaChainFromEndpoint } from '@fernolab/wallet-adapter-core';
5
+ export { adaptWallet, dedupeStandardWallets, isSolanaWallet };
6
+ // ============================================================================
7
+ // Constants
8
+ // ============================================================================
9
+ const LAST_WALLET_KEY = 'lastConnectedWallet';
10
+ const SolanaMobileWalletAdapterWalletName = 'Mobile Wallet Adapter';
11
+ const MOBILE_WALLET_ADAPTER_DISPLAY_NAME = 'Use Installed Wallet';
12
+ const INJECTED_WALLET_ICON = 'data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2248%22%20height%3D%2248%22%20viewBox%3D%220%200%2048%2048%22%20fill%3D%22none%22%3E%3Crect%20width%3D%2248%22%20height%3D%2248%22%20rx%3D%2210%22%20fill%3D%22%23111827%22%2F%3E%3Cpath%20d%3D%22M14%2018h20M14%2024h20M14%2030h20%22%20stroke%3D%22white%22%20stroke-width%3D%222.5%22%20stroke-linecap%3D%22round%22%2F%3E%3C%2Fsvg%3E';
13
+ export const RUNTIME_DEBUG_MODES = [
14
+ 'auto',
15
+ 'desktop',
16
+ 'ios',
17
+ 'android',
18
+ 'phantom',
19
+ 'solflare',
20
+ 'jupiter',
21
+ 'backpack'
22
+ ];
23
+ const RUNTIME_DEBUG_QUERY_KEYS = ['wallet_mobile', 'wallet_runtime'];
24
+ const MOBILE_WALLET_NAMES = [
25
+ SolanaMobileWalletAdapterWalletName,
26
+ 'Phantom',
27
+ 'Solflare',
28
+ 'Jupiter Mobile',
29
+ 'Jupiter',
30
+ 'Jupiter Wallet',
31
+ 'Backpack'
32
+ ];
33
+ const PREFERRED_WALLET_ORDER = [...MOBILE_WALLET_NAMES];
34
+ const DESKTOP_RUNTIME = {
35
+ isMobile: false,
36
+ isWalletBrowser: false,
37
+ platform: 'desktop',
38
+ supportsMobileWalletAdapter: false,
39
+ walletBrowser: null
40
+ };
41
+ // ============================================================================
42
+ // Wallet Detection & Adaptation
43
+ // ============================================================================
44
+ function getRuntimeDebugWalletId(mode) {
45
+ switch (mode) {
46
+ case 'phantom':
47
+ case 'solflare':
48
+ case 'jupiter':
49
+ case 'backpack':
50
+ return mode;
51
+ default:
52
+ return null;
53
+ }
54
+ }
55
+ function normalizeRuntimeDebugMode(value) {
56
+ const normalized = value?.trim().toLowerCase();
57
+ if (normalized === 'mobile') {
58
+ return 'android';
59
+ }
60
+ return RUNTIME_DEBUG_MODES.includes(normalized)
61
+ ? normalized
62
+ : 'auto';
63
+ }
64
+ function readRuntimeDebugMode() {
65
+ if (!browser || typeof location === 'undefined') {
66
+ return 'auto';
67
+ }
68
+ const url = new URL(location.href);
69
+ const hashParams = url.hash.includes('=')
70
+ ? new URLSearchParams(url.hash.replace(/^#/, ''))
71
+ : new URLSearchParams();
72
+ for (const key of RUNTIME_DEBUG_QUERY_KEYS) {
73
+ const mode = normalizeRuntimeDebugMode(url.searchParams.get(key) ?? hashParams.get(key));
74
+ if (mode !== 'auto') {
75
+ return mode;
76
+ }
77
+ }
78
+ return 'auto';
79
+ }
80
+ function writeRuntimeDebugMode(mode) {
81
+ if (!browser || typeof history === 'undefined' || typeof location === 'undefined') {
82
+ return;
83
+ }
84
+ const url = new URL(location.href);
85
+ for (const key of RUNTIME_DEBUG_QUERY_KEYS) {
86
+ url.searchParams.delete(key);
87
+ }
88
+ if (mode !== 'auto') {
89
+ url.searchParams.set(RUNTIME_DEBUG_QUERY_KEYS[0], mode);
90
+ }
91
+ history.replaceState(history.state, '', url);
92
+ }
93
+ function bytesFromString(input, length) {
94
+ const bytes = new Uint8Array(length);
95
+ let hash = 0x811c9dc5;
96
+ for (let index = 0; index < length; index += 1) {
97
+ for (let charIndex = 0; charIndex < input.length; charIndex += 1) {
98
+ hash ^= input.charCodeAt(charIndex) + index;
99
+ hash = Math.imul(hash, 0x01000193);
100
+ }
101
+ hash ^= hash >>> 13;
102
+ hash = Math.imul(hash, 0x85ebca6b);
103
+ bytes[index] = hash & 0xff;
104
+ }
105
+ return bytes;
106
+ }
107
+ function createDebugInjectedWallet(id) {
108
+ const wallet = MOBILE_WALLETS.find((candidate) => candidate.id === id);
109
+ const signature = bytesFromString(`wallet-debug:${id}:signature`, 64);
110
+ const publicKey = '11111111111111111111111111111111';
111
+ const publicKeyBytes = new Uint8Array(32);
112
+ const provider = {
113
+ connect: async () => ({ publicKey: { toBytes: () => publicKeyBytes, toString: () => publicKey } }),
114
+ disconnect: async () => undefined,
115
+ isBackpack: id === 'backpack',
116
+ isJupiter: id === 'jupiter',
117
+ isPhantom: id === 'phantom',
118
+ isSolflare: id === 'solflare',
119
+ signMessage: async () => signature
120
+ };
121
+ return {
122
+ id,
123
+ name: wallet?.name ?? id,
124
+ provider
125
+ };
126
+ }
127
+ function normalizeInjectedSignature(result) {
128
+ if (result instanceof Uint8Array) {
129
+ return result;
130
+ }
131
+ if (!result.signature) {
132
+ throw new Error('Injected wallet did not return a signature');
133
+ }
134
+ return result.signature instanceof Uint8Array ? result.signature : new Uint8Array(result.signature);
135
+ }
136
+ function getInjectedPublicKeyBytes(publicKey) {
137
+ const bytes = publicKey?.toBytes?.() ?? publicKey?.toBuffer?.();
138
+ return bytes ? new Uint8Array(bytes) : new Uint8Array(32);
139
+ }
140
+ function createInjectedAccount(address, chain, provider, publicKey) {
141
+ return {
142
+ address,
143
+ publicKey: getInjectedPublicKeyBytes(publicKey),
144
+ chains: [chain],
145
+ features: provider.signMessage ? [SolanaSignMessage] : []
146
+ };
147
+ }
148
+ function createInjectedStandardWallet(detectedWallet, chain) {
149
+ const { name, provider } = detectedWallet;
150
+ let accounts = [];
151
+ const listeners = new Set();
152
+ function emitChange() {
153
+ const payload = { accounts };
154
+ listeners.forEach((listener) => listener(payload));
155
+ }
156
+ const wallet = {
157
+ version: '1.0.0',
158
+ name,
159
+ icon: INJECTED_WALLET_ICON,
160
+ chains: [chain],
161
+ get accounts() {
162
+ return accounts;
163
+ },
164
+ features: {
165
+ [StandardConnect]: {
166
+ version: '1.0.0',
167
+ connect: async () => {
168
+ if (!provider.connect) {
169
+ throw new Error(`${name} does not expose a connect method`);
170
+ }
171
+ const response = await provider.connect();
172
+ const address = response.publicKey?.toString();
173
+ if (!address) {
174
+ throw new Error(`${name} did not return a public key`);
175
+ }
176
+ accounts = [createInjectedAccount(address, chain, provider, response.publicKey)];
177
+ emitChange();
178
+ return { accounts };
179
+ }
180
+ },
181
+ [StandardDisconnect]: {
182
+ version: '1.0.0',
183
+ disconnect: async () => {
184
+ await provider.disconnect?.();
185
+ accounts = [];
186
+ emitChange();
187
+ }
188
+ },
189
+ [StandardEvents]: {
190
+ version: '1.0.0',
191
+ on: ((event, listener) => {
192
+ if (event === 'change') {
193
+ listeners.add(listener);
194
+ }
195
+ return () => listeners.delete(listener);
196
+ })
197
+ },
198
+ ...(provider.signMessage
199
+ ? {
200
+ [SolanaSignMessage]: {
201
+ version: '1.1.0',
202
+ signMessage: async (...inputs) => await Promise.all(inputs.map(async ({ account, message }) => {
203
+ const currentAccount = accounts[0];
204
+ if (!currentAccount || account.address !== currentAccount.address) {
205
+ throw new Error(`${name} account mismatch`);
206
+ }
207
+ if (!provider.signMessage) {
208
+ throw new Error(`${name} does not support message signing`);
209
+ }
210
+ return {
211
+ signature: normalizeInjectedSignature(await provider.signMessage(message, 'utf8')),
212
+ signedMessage: message,
213
+ signatureType: 'ed25519'
214
+ };
215
+ }))
216
+ }
217
+ }
218
+ : {})
219
+ }
220
+ };
221
+ return {
222
+ name,
223
+ icon: wallet.icon ?? INJECTED_WALLET_ICON,
224
+ wallet
225
+ };
226
+ }
227
+ function createInjectedStandardWallets(chain, detectedWallets) {
228
+ if (!browser) {
229
+ return [];
230
+ }
231
+ return detectedWallets.map((wallet) => createInjectedStandardWallet(wallet, chain));
232
+ }
233
+ async function getStandardWallets(chain, detectedInjectedWallets) {
234
+ const registered = getWallets().get();
235
+ const adapted = adaptStandardWallets(registered);
236
+ const injectedWallets = createInjectedStandardWallets(chain, detectedInjectedWallets);
237
+ const unique = dedupeStandardWallets([...adapted, ...injectedWallets], PREFERRED_WALLET_ORDER);
238
+ return unique;
239
+ }
240
+ /**
241
+ * Listen for newly registered wallets
242
+ */
243
+ function onWalletRegistered(callback) {
244
+ const wallets = getWallets();
245
+ return wallets.on('register', (...newWallets) => {
246
+ for (const wallet of newWallets) {
247
+ const adapted = adaptWallet(wallet);
248
+ if (adapted) {
249
+ callback(adapted);
250
+ }
251
+ }
252
+ });
253
+ }
254
+ // ============================================================================
255
+ // Utility Functions
256
+ // ============================================================================
257
+ /**
258
+ * Determine Solana chain identifier from RPC endpoint
259
+ */
260
+ export function resolveChainFromEndpoint(endpoint) {
261
+ return resolveSolanaChainFromEndpoint(endpoint);
262
+ }
263
+ function getRuntimeForDebugMode(mode) {
264
+ switch (mode) {
265
+ case 'desktop':
266
+ return DESKTOP_RUNTIME;
267
+ case 'ios':
268
+ return {
269
+ isMobile: true,
270
+ isWalletBrowser: false,
271
+ platform: 'ios',
272
+ supportsMobileWalletAdapter: false,
273
+ walletBrowser: null
274
+ };
275
+ case 'android':
276
+ return {
277
+ isMobile: true,
278
+ isWalletBrowser: false,
279
+ platform: 'android',
280
+ supportsMobileWalletAdapter: true,
281
+ walletBrowser: null
282
+ };
283
+ case 'phantom':
284
+ case 'solflare':
285
+ case 'jupiter':
286
+ case 'backpack':
287
+ return {
288
+ isMobile: true,
289
+ isWalletBrowser: true,
290
+ platform: 'ios',
291
+ supportsMobileWalletAdapter: false,
292
+ walletBrowser: mode
293
+ };
294
+ default:
295
+ return null;
296
+ }
297
+ }
298
+ function getCurrentRuntime(mode) {
299
+ if (!browser || typeof navigator === 'undefined') {
300
+ return DESKTOP_RUNTIME;
301
+ }
302
+ const debugRuntime = getRuntimeForDebugMode(mode);
303
+ if (debugRuntime) {
304
+ return debugRuntime;
305
+ }
306
+ return detectMobileRuntime({ maxTouchPoints: navigator.maxTouchPoints });
307
+ }
308
+ function createCurrentMobileWalletLinks() {
309
+ if (!browser || typeof location === 'undefined') {
310
+ return [];
311
+ }
312
+ const targetUrl = location.href;
313
+ const referrerUrl = location.origin;
314
+ const jupiterWallet = MOBILE_WALLETS.find((wallet) => wallet.id === 'jupiter');
315
+ const links = MOBILE_DEEPLINK_WALLETS.map((wallet) => ({
316
+ name: wallet.name,
317
+ url: createMobileWalletBrowseUrl(wallet, targetUrl, referrerUrl)
318
+ }));
319
+ if (jupiterWallet) {
320
+ links.push({ name: jupiterWallet.name, url: jupiterWallet.websiteUrl });
321
+ }
322
+ return links;
323
+ }
324
+ function getDetectedWalletBrowserName(runtime, injectedWallets) {
325
+ const userAgentWallet = MOBILE_WALLETS.find((wallet) => wallet.id === runtime.walletBrowser);
326
+ if (userAgentWallet) {
327
+ return userAgentWallet.name;
328
+ }
329
+ const injectedWallet = injectedWallets[0];
330
+ if (runtime.isMobile && injectedWallet) {
331
+ return injectedWallet.name;
332
+ }
333
+ return null;
334
+ }
335
+ function getRuntimeLabel(runtime, injectedWallets) {
336
+ const walletBrowserName = getDetectedWalletBrowserName(runtime, injectedWallets);
337
+ if (walletBrowserName) {
338
+ return `${walletBrowserName} browser`;
339
+ }
340
+ if (runtime.supportsMobileWalletAdapter) {
341
+ return 'Android Chrome';
342
+ }
343
+ if (runtime.platform === 'ios') {
344
+ return 'iOS browser';
345
+ }
346
+ if (runtime.isMobile) {
347
+ return 'Mobile browser';
348
+ }
349
+ return 'Desktop browser';
350
+ }
351
+ /**
352
+ * Get typed feature from wallet
353
+ */
354
+ function getWalletFeature(wallet, featureName) {
355
+ const features = wallet.features;
356
+ return features[featureName] ?? null;
357
+ }
358
+ // ============================================================================
359
+ // Wallet Store
360
+ // ============================================================================
361
+ export function createWalletStore() {
362
+ // State
363
+ let rpcEndpoint = $state(PUBLIC_SOLANA_RPC_ENDPOINT);
364
+ let availableWallets = $state([]);
365
+ let standardWallet = $state(null);
366
+ let standardAccount = $state(null);
367
+ let publicKey = $state(null);
368
+ let connected = $state(false);
369
+ let connecting = $state(false);
370
+ let signing = $state(false);
371
+ let isInitialized = $state(false);
372
+ let error = $state(null);
373
+ let useMWA = $state(false);
374
+ let mobileRuntime = $state(DESKTOP_RUNTIME);
375
+ let runtimeDebugMode = $state(readRuntimeDebugMode());
376
+ let injectedWallets = $state([]);
377
+ let mobileWalletLinks = $state([]);
378
+ let walletChangeCallbacks = new Set();
379
+ let walletRegistrationOff = null;
380
+ const controller = createWalletController();
381
+ // Derived state
382
+ const shortAddress = $derived(publicKey ? `${publicKey.slice(0, 4)}...${publicKey.slice(-4)}` : '');
383
+ const connectionStatus = $derived(connecting ? 'connecting' : connected ? 'connected' : 'disconnected');
384
+ const detectedWalletBrowserName = $derived(getDetectedWalletBrowserName(mobileRuntime, injectedWallets));
385
+ const runtimeLabel = $derived(getRuntimeLabel(mobileRuntime, injectedWallets));
386
+ const mobileWalletAdapterWallet = $derived(availableWallets.find((wallet) => wallet.name === SolanaMobileWalletAdapterWalletName) ?? null);
387
+ // ============================================================================
388
+ // Event System
389
+ // ============================================================================
390
+ function notifyWalletChange(wallet) {
391
+ walletChangeCallbacks.forEach((callback) => {
392
+ try {
393
+ callback(wallet);
394
+ }
395
+ catch {
396
+ }
397
+ });
398
+ }
399
+ function onWalletChange(callback) {
400
+ walletChangeCallbacks.add(callback);
401
+ return () => {
402
+ walletChangeCallbacks.delete(callback);
403
+ };
404
+ }
405
+ controller.subscribe((state) => {
406
+ const previousWallet = standardWallet;
407
+ availableWallets = [...state.availableWallets];
408
+ standardWallet = state.standardWallet;
409
+ standardAccount = state.standardAccount;
410
+ publicKey = state.publicKey;
411
+ connected = state.connected;
412
+ connecting = state.connecting;
413
+ signing = state.signing;
414
+ error = state.error;
415
+ if (previousWallet !== state.standardWallet) {
416
+ if (browser) {
417
+ if (state.standardWallet) {
418
+ localStorage.setItem(LAST_WALLET_KEY, state.standardWallet.name);
419
+ }
420
+ else {
421
+ localStorage.removeItem(LAST_WALLET_KEY);
422
+ }
423
+ }
424
+ notifyWalletChange(state.standardWallet);
425
+ }
426
+ });
427
+ // ============================================================================
428
+ // Internal Helper Functions
429
+ // ============================================================================
430
+ function setError(err) {
431
+ error = err;
432
+ }
433
+ function getDetectedInjectedWallets() {
434
+ const debugWalletId = getRuntimeDebugWalletId(runtimeDebugMode);
435
+ if (debugWalletId) {
436
+ return [createDebugInjectedWallet(debugWalletId)];
437
+ }
438
+ return browser ? detectInjectedWallets() : [];
439
+ }
440
+ function refreshRuntimeState() {
441
+ mobileRuntime = getCurrentRuntime(runtimeDebugMode);
442
+ injectedWallets = getDetectedInjectedWallets();
443
+ mobileWalletLinks = createCurrentMobileWalletLinks();
444
+ useMWA = Boolean(mobileWalletAdapterWallet);
445
+ }
446
+ async function refreshAvailableWallets() {
447
+ if (!browser) {
448
+ return;
449
+ }
450
+ refreshRuntimeState();
451
+ const chain = resolveChainFromEndpoint(rpcEndpoint);
452
+ const detectedInjectedWallets = injectedWallets;
453
+ const wallets = await getStandardWallets(chain, detectedInjectedWallets);
454
+ controller.setAvailableWallets(wallets);
455
+ refreshRuntimeState();
456
+ }
457
+ function getWalletByNames(names) {
458
+ return availableWallets.find((wallet) => names.includes(wallet.name)) ?? null;
459
+ }
460
+ function getWalletBrowserNames() {
461
+ const detectedWallet = injectedWallets[0];
462
+ const walletId = detectedWallet?.id ?? mobileRuntime.walletBrowser;
463
+ switch (walletId) {
464
+ case 'phantom':
465
+ return ['Phantom'];
466
+ case 'solflare':
467
+ return ['Solflare'];
468
+ case 'jupiter':
469
+ return ['Jupiter Mobile', 'Jupiter', 'Jupiter Wallet'];
470
+ case 'backpack':
471
+ return ['Backpack'];
472
+ default:
473
+ return [];
474
+ }
475
+ }
476
+ // ============================================================================
477
+ // Public API
478
+ // ============================================================================
479
+ /**
480
+ * Initialize the wallet store
481
+ * @param endpoint - Solana RPC endpoint URL
482
+ */
483
+ async function initialize(endpoint = PUBLIC_SOLANA_RPC_ENDPOINT) {
484
+ try {
485
+ rpcEndpoint = endpoint;
486
+ if (!browser) {
487
+ return;
488
+ }
489
+ await refreshAvailableWallets();
490
+ const wallets = availableWallets;
491
+ // Attempt to restore last connected wallet
492
+ const lastWallet = localStorage.getItem(LAST_WALLET_KEY);
493
+ if (lastWallet) {
494
+ const existing = wallets.find((wallet) => wallet.name === lastWallet);
495
+ if (existing) {
496
+ try {
497
+ await connectStandard(existing);
498
+ }
499
+ catch (err) {
500
+ localStorage.removeItem(LAST_WALLET_KEY);
501
+ setError(err instanceof Error ? err : new Error(String(err)));
502
+ }
503
+ }
504
+ }
505
+ // Listen for newly registered wallets
506
+ if (!walletRegistrationOff) {
507
+ walletRegistrationOff = onWalletRegistered((wallet) => {
508
+ controller.setAvailableWallets(dedupeStandardWallets([...availableWallets, wallet], PREFERRED_WALLET_ORDER));
509
+ refreshRuntimeState();
510
+ });
511
+ }
512
+ isInitialized = true;
513
+ setError(null);
514
+ }
515
+ catch (err) {
516
+ isInitialized = false;
517
+ setError(err instanceof Error ? err : new Error('Failed to initialize wallet store'));
518
+ throw err;
519
+ }
520
+ }
521
+ async function setRuntimeDebugMode(mode) {
522
+ runtimeDebugMode = normalizeRuntimeDebugMode(mode);
523
+ writeRuntimeDebugMode(runtimeDebugMode);
524
+ await refreshAvailableWallets();
525
+ }
526
+ /**
527
+ * Connect to a wallet using the Wallet Standard
528
+ * @param wallet - The wallet to connect to
529
+ */
530
+ async function connectStandard(wallet) {
531
+ try {
532
+ await controller.connectStandard(wallet);
533
+ }
534
+ catch (err) {
535
+ const error = err instanceof Error ? err : new Error('Failed to connect wallet');
536
+ setError(error);
537
+ throw error;
538
+ }
539
+ }
540
+ async function connectMobileWalletAdapter() {
541
+ const mobileWallet = getWalletByNames([SolanaMobileWalletAdapterWalletName]);
542
+ if (!mobileWallet) {
543
+ throw new Error('Mobile Wallet Adapter is not available in this browser');
544
+ }
545
+ await connectStandard(mobileWallet);
546
+ }
547
+ async function connectWalletBrowser() {
548
+ const names = getWalletBrowserNames();
549
+ const walletBrowserName = detectedWalletBrowserName ?? 'Wallet browser';
550
+ const wallet = getWalletByNames(names);
551
+ if (!wallet) {
552
+ throw new Error(`${walletBrowserName} is not available in this browser`);
553
+ }
554
+ await connectStandard(wallet);
555
+ }
556
+ /**
557
+ * Disconnect the currently connected wallet
558
+ */
559
+ async function disconnect() {
560
+ try {
561
+ await controller.disconnect();
562
+ setError(null);
563
+ }
564
+ catch (err) {
565
+ const error = err instanceof Error ? err : new Error('Failed to disconnect');
566
+ setError(error);
567
+ throw error;
568
+ }
569
+ }
570
+ /**
571
+ * Sign a message with the connected wallet
572
+ * @param message - UTF-8 string or raw bytes to sign
573
+ * @returns Wallet Standard signature result
574
+ */
575
+ async function signMessage(message) {
576
+ try {
577
+ return await controller.signMessage(message);
578
+ }
579
+ catch (err) {
580
+ const error = err instanceof Error ? err : new Error('Failed to sign message');
581
+ setError(error);
582
+ throw error;
583
+ }
584
+ }
585
+ // ============================================================================
586
+ // Return Public Interface
587
+ // ============================================================================
588
+ return {
589
+ // State getters
590
+ get rpcEndpoint() {
591
+ return rpcEndpoint;
592
+ },
593
+ get availableWallets() {
594
+ return availableWallets;
595
+ },
596
+ get standardWallet() {
597
+ return standardWallet;
598
+ },
599
+ get standardAccount() {
600
+ return standardAccount;
601
+ },
602
+ get publicKey() {
603
+ return publicKey;
604
+ },
605
+ get connected() {
606
+ return connected;
607
+ },
608
+ get connecting() {
609
+ return connecting;
610
+ },
611
+ get signing() {
612
+ return signing;
613
+ },
614
+ get connectionStatus() {
615
+ return connectionStatus;
616
+ },
617
+ get useMWA() {
618
+ return useMWA;
619
+ },
620
+ get shortAddress() {
621
+ return shortAddress;
622
+ },
623
+ get isInitialized() {
624
+ return isInitialized;
625
+ },
626
+ get error() {
627
+ return error;
628
+ },
629
+ get mobileRuntime() {
630
+ return mobileRuntime;
631
+ },
632
+ get runtimeLabel() {
633
+ return runtimeLabel;
634
+ },
635
+ get runtimeDebugMode() {
636
+ return runtimeDebugMode;
637
+ },
638
+ get runtimeDebugModes() {
639
+ return RUNTIME_DEBUG_MODES;
640
+ },
641
+ get detectedInjectedWallets() {
642
+ return injectedWallets;
643
+ },
644
+ get detectedWalletBrowserName() {
645
+ return detectedWalletBrowserName;
646
+ },
647
+ get mobileWalletLinks() {
648
+ return mobileWalletLinks;
649
+ },
650
+ get mobileWalletAdapterWallet() {
651
+ return mobileWalletAdapterWallet;
652
+ },
653
+ get mobileWalletAdapterName() {
654
+ return SolanaMobileWalletAdapterWalletName;
655
+ },
656
+ get mobileWalletAdapterDisplayName() {
657
+ return MOBILE_WALLET_ADAPTER_DISPLAY_NAME;
658
+ },
659
+ // Methods
660
+ initialize,
661
+ refreshAvailableWallets,
662
+ setRuntimeDebugMode,
663
+ connectStandard,
664
+ connectMobileWalletAdapter,
665
+ connectWalletBrowser,
666
+ disconnect,
667
+ signMessage,
668
+ onWalletChange,
669
+ clearError: () => setError(null)
670
+ };
671
+ }
672
+ export const wallet = createWalletStore();